* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-09-11 22:30 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-09-11 22:30 UTC (permalink / raw
To: gentoo-commits
commit: f0dc7817c3af87cf128b5b1bc20a94d9f910b987
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Sep 11 22:30:20 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Sep 11 22:30:20 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f0dc7817
Add genpatches
Bluetooth: Check key sizes only when Secure Simple Pairing is
enabled. See bug #686758
tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig.
See bug #710790. Thanks to Phil Stracchino
sign-file: full functionality with modern LibreSSL
Kernel Self Protection patch
CPU Optimization patch
Print firmware info (Reqs CONFIG_GENTOO_PRINT_FIRMWARE_INFO
Patch to enable link security restrictions by default.
Patch to support for namespace user.pax.* on tmpfs.
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 37 ++
1500_XATTR_USER_PREFIX.patch | 67 ++
...ble-link-security-restrictions-by-default.patch | 17 +
1700_sparc-address-warray-bound-warnings.patch | 17 +
...zes-only-if-Secure-Simple-Pairing-enabled.patch | 37 ++
2700_revert-drm-i915-dma-resv-obj-fix.patch | 107 ++++
...3-Fix-build-issue-by-selecting-CONFIG_REG.patch | 30 +
2920_sign-file-patch-for-libressl.patch | 16 +
3000_Support-printing-firmware-info.patch | 14 +
5010_enable-cpu-optimizations-universal.patch | 675 +++++++++++++++++++++
10 files changed, 1017 insertions(+)
diff --git a/0000_README b/0000_README
index 90189932..b3a5a14c 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,43 @@ EXPERIMENTAL
Individual Patch Descriptions:
--------------------------------------------------------------------------
+Patch: 1500_XATTR_USER_PREFIX.patch
+From: https://bugs.gentoo.org/show_bug.cgi?id=470644
+Desc: Support for namespace user.pax.* on tmpfs.
+
+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.
+
+Patch: 1700_sparc-address-warray-bound-warnings.patch
+From: https://github.com/KSPP/linux/issues/109
+Desc: Address -Warray-bounds warnings
+
+Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
+From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
+Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
+
+Patch: 2700_revert-drm-i915-dma-resv-obj-fix.patch
+From: https://bugs.gentoo.org/866023
+Desc: Revert Revert for drm i915 thanks to Luigi 'Comio' Mantellini
+
+Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
+From: https://bugs.gentoo.org/710790
+Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
+
+Patch: 2920_sign-file-patch-for-libressl.patch
+From: https://bugs.gentoo.org/717166
+Desc: sign-file: full functionality with modern LibreSSL
+
+Patch: 3000_Support-printing-firmware-info.patch
+From: https://bugs.gentoo.org/732852
+Desc: Print firmware info (Reqs CONFIG_GENTOO_PRINT_FIRMWARE_INFO). Thanks to Georgy Yakovlev
+
Patch: 4567_distro-Gentoo-Kconfig.patch
From: Tom Wijsman <TomWij@gentoo.org>
Desc: Add Gentoo Linux support config settings and defaults.
+
+Patch: 5010_enable-cpu-optimizations-universal.patch
+From: https://github.com/graysky2/kernel_compiler_patch
+Desc: Kernel >= 5.15 patch enables gcc = v11.1+ optimizations for additional CPUs.
+
diff --git a/1500_XATTR_USER_PREFIX.patch b/1500_XATTR_USER_PREFIX.patch
new file mode 100644
index 00000000..245dcc29
--- /dev/null
+++ b/1500_XATTR_USER_PREFIX.patch
@@ -0,0 +1,67 @@
+From: Anthony G. Basile <blueness@gentoo.org>
+
+This patch adds support for a restricted user-controlled namespace on
+tmpfs filesystem used to house PaX flags. The namespace must be of the
+form user.pax.* and its value cannot exceed a size of 8 bytes.
+
+This is needed even on all Gentoo systems so that XATTR_PAX flags
+are preserved for users who might build packages using portage on
+a tmpfs system with a non-hardened kernel and then switch to a
+hardened kernel with XATTR_PAX enabled.
+
+The namespace is added to any user with Extended Attribute support
+enabled for tmpfs. Users who do not enable xattrs will not have
+the XATTR_PAX flags preserved.
+
+diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
+index 1590c49..5eab462 100644
+--- a/include/uapi/linux/xattr.h
++++ b/include/uapi/linux/xattr.h
+@@ -73,5 +73,9 @@
+ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
+ #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
+
++/* User namespace */
++#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
++#define XATTR_PAX_FLAGS_SUFFIX "flags"
++#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
+
+ #endif /* _UAPI_LINUX_XATTR_H */
+--- a/mm/shmem.c 2020-05-04 15:30:27.042035334 -0400
++++ b/mm/shmem.c 2020-05-04 15:34:57.013881725 -0400
+@@ -3238,6 +3238,14 @@ static int shmem_xattr_handler_set(const
+ struct shmem_inode_info *info = SHMEM_I(inode);
+
+ name = xattr_full_name(handler, name);
++
++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
++ if (strcmp(name, XATTR_NAME_PAX_FLAGS))
++ return -EOPNOTSUPP;
++ if (size > 8)
++ return -EINVAL;
++ }
++
+ return simple_xattr_set(&info->xattrs, name, value, size, flags, NULL);
+ }
+
+@@ -3253,6 +3261,12 @@ static const struct xattr_handler shmem_
+ .set = shmem_xattr_handler_set,
+ };
+
++static const struct xattr_handler shmem_user_xattr_handler = {
++ .prefix = XATTR_USER_PREFIX,
++ .get = shmem_xattr_handler_get,
++ .set = shmem_xattr_handler_set,
++};
++
+ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ #ifdef CONFIG_TMPFS_POSIX_ACL
+ &posix_acl_access_xattr_handler,
+@@ -3260,6 +3274,7 @@ static const struct xattr_handler *shmem
+ #endif
+ &shmem_security_xattr_handler,
+ &shmem_trusted_xattr_handler,
++ &shmem_user_xattr_handler,
+ NULL
+ };
+
diff --git a/1510_fs-enable-link-security-restrictions-by-default.patch b/1510_fs-enable-link-security-restrictions-by-default.patch
new file mode 100644
index 00000000..e8c30157
--- /dev/null
+++ b/1510_fs-enable-link-security-restrictions-by-default.patch
@@ -0,0 +1,17 @@
+--- a/fs/namei.c 2022-01-23 13:02:27.876558299 -0500
++++ b/fs/namei.c 2022-03-06 12:47:39.375719693 -0500
+@@ -1020,10 +1020,10 @@ static inline void put_link(struct namei
+ path_put(&last->link);
+ }
+
+-static int sysctl_protected_symlinks __read_mostly;
+-static int sysctl_protected_hardlinks __read_mostly;
+-static int sysctl_protected_fifos __read_mostly;
+-static int sysctl_protected_regular __read_mostly;
++static int sysctl_protected_symlinks __read_mostly = 1;
++static int sysctl_protected_hardlinks __read_mostly = 1;
++int sysctl_protected_fifos __read_mostly = 1;
++int sysctl_protected_regular __read_mostly = 1;
+
+ #ifdef CONFIG_SYSCTL
+ static struct ctl_table namei_sysctls[] = {
diff --git a/1700_sparc-address-warray-bound-warnings.patch b/1700_sparc-address-warray-bound-warnings.patch
new file mode 100644
index 00000000..f9393555
--- /dev/null
+++ b/1700_sparc-address-warray-bound-warnings.patch
@@ -0,0 +1,17 @@
+--- a/arch/sparc/mm/init_64.c 2022-05-24 16:48:40.749677491 -0400
++++ b/arch/sparc/mm/init_64.c 2022-05-24 16:55:15.511356945 -0400
+@@ -3052,11 +3052,11 @@ static inline resource_size_t compute_ke
+ static void __init kernel_lds_init(void)
+ {
+ code_resource.start = compute_kern_paddr(_text);
+- code_resource.end = compute_kern_paddr(_etext - 1);
++ code_resource.end = compute_kern_paddr(_etext) - 1;
+ data_resource.start = compute_kern_paddr(_etext);
+- data_resource.end = compute_kern_paddr(_edata - 1);
++ data_resource.end = compute_kern_paddr(_edata) - 1;
+ bss_resource.start = compute_kern_paddr(__bss_start);
+- bss_resource.end = compute_kern_paddr(_end - 1);
++ bss_resource.end = compute_kern_paddr(_end) - 1;
+ }
+
+ static int __init report_memory(void)
diff --git a/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch b/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
new file mode 100644
index 00000000..394ad48f
--- /dev/null
+++ b/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
@@ -0,0 +1,37 @@
+The encryption is only mandatory to be enforced when both sides are using
+Secure Simple Pairing and this means the key size check makes only sense
+in that case.
+
+On legacy Bluetooth 2.0 and earlier devices like mice the encryption was
+optional and thus causing an issue if the key size check is not bound to
+using Secure Simple Pairing.
+
+Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections")
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: stable@vger.kernel.org
+---
+ net/bluetooth/hci_conn.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 3cf0764d5793..7516cdde3373 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1272,8 +1272,13 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
+ return 0;
+ }
+
+- if (hci_conn_ssp_enabled(conn) &&
+- !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
++ /* If Secure Simple Pairing is not enabled, then legacy connection
++ * setup is used and no encryption or key sizes can be enforced.
++ */
++ if (!hci_conn_ssp_enabled(conn))
++ return 1;
++
++ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ return 0;
+
+ /* The minimum encryption key size needs to be enforced by the
+--
+2.20.1
diff --git a/2700_revert-drm-i915-dma-resv-obj-fix.patch b/2700_revert-drm-i915-dma-resv-obj-fix.patch
new file mode 100644
index 00000000..a9fcaf4a
--- /dev/null
+++ b/2700_revert-drm-i915-dma-resv-obj-fix.patch
@@ -0,0 +1,107 @@
+From d481c481ca7813d688ffcb1c5418b48f83d945c1 Mon Sep 17 00:00:00 2001
+From: Luigi 'Comio' Mantellini <luigi.mantellini@gmail.com>
+Date: Sun, 28 Aug 2022 09:17:35 +0200
+Subject: [PATCH] Revert "drm/i915: Individualize fences before adding to
+ dma_resv obj"
+
+This reverts commit 842d9346b2fdda4d2fb8ccb5b87faef1ac01ab51.
+---
+ .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 3 +-
+ drivers/gpu/drm/i915/i915_vma.c | 48 ++++++++-----------
+ 2 files changed, 21 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index 30fe847c6664..c326bd2b444f 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -999,8 +999,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
+ }
+ }
+
+- /* Reserve enough slots to accommodate composite fences */
+- err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
++ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
+ if (err)
+ return err;
+
+diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
+index 16460b169ed2..e71826f0e4b1 100644
+--- a/drivers/gpu/drm/i915/i915_vma.c
++++ b/drivers/gpu/drm/i915/i915_vma.c
+@@ -23,7 +23,6 @@
+ */
+
+ #include <linux/sched/mm.h>
+-#include <linux/dma-fence-array.h>
+ #include <drm/drm_gem.h>
+
+ #include "display/intel_frontbuffer.h"
+@@ -1839,21 +1838,6 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
+ if (unlikely(err))
+ return err;
+
+- /*
+- * Reserve fences slot early to prevent an allocation after preparing
+- * the workload and associating fences with dma_resv.
+- */
+- if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
+- struct dma_fence *curr;
+- int idx;
+-
+- dma_fence_array_for_each(curr, idx, fence)
+- ;
+- err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
+- if (unlikely(err))
+- return err;
+- }
+-
+ if (flags & EXEC_OBJECT_WRITE) {
+ struct intel_frontbuffer *front;
+
+@@ -1863,23 +1847,31 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
+ i915_active_add_request(&front->write, rq);
+ intel_frontbuffer_put(front);
+ }
+- }
+
+- if (fence) {
+- struct dma_fence *curr;
+- enum dma_resv_usage usage;
+- int idx;
++ if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
++ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
++ if (unlikely(err))
++ return err;
++ }
+
+- obj->read_domains = 0;
+- if (flags & EXEC_OBJECT_WRITE) {
+- usage = DMA_RESV_USAGE_WRITE;
++ if (fence) {
++ dma_resv_add_fence(vma->obj->base.resv, fence,
++ DMA_RESV_USAGE_WRITE);
+ obj->write_domain = I915_GEM_DOMAIN_RENDER;
+- } else {
+- usage = DMA_RESV_USAGE_READ;
++ obj->read_domains = 0;
++ }
++ } else {
++ if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
++ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
++ if (unlikely(err))
++ return err;
+ }
+
+- dma_fence_array_for_each(curr, idx, fence)
+- dma_resv_add_fence(vma->obj->base.resv, curr, usage);
++ if (fence) {
++ dma_resv_add_fence(vma->obj->base.resv, fence,
++ DMA_RESV_USAGE_READ);
++ obj->write_domain = 0;
++ }
+ }
+
+ if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
+--
+2.37.2
+
diff --git a/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch b/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
new file mode 100644
index 00000000..43356857
--- /dev/null
+++ b/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
@@ -0,0 +1,30 @@
+From dc328d75a6f37f4ff11a81ae16b1ec88c3197640 Mon Sep 17 00:00:00 2001
+From: Mike Pagano <mpagano@gentoo.org>
+Date: Mon, 23 Mar 2020 08:20:06 -0400
+Subject: [PATCH 1/1] This driver requires REGMAP_I2C to build. Select it by
+ default in Kconfig. Reported at gentoo bugzilla:
+ https://bugs.gentoo.org/710790
+Cc: mpagano@gentoo.org
+
+Reported-by: Phil Stracchino <phils@caerllewys.net>
+
+Signed-off-by: Mike Pagano <mpagano@gentoo.org>
+---
+ drivers/hwmon/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 47ac20aee06f..530b4f29ba85 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1769,6 +1769,7 @@ config SENSORS_TMP421
+ config SENSORS_TMP513
+ tristate "Texas Instruments TMP513 and compatibles"
+ depends on I2C
++ select REGMAP_I2C
+ help
+ If you say yes here you get support for Texas Instruments TMP512,
+ and TMP513 temperature and power supply sensor chips.
+--
+2.24.1
+
diff --git a/2920_sign-file-patch-for-libressl.patch b/2920_sign-file-patch-for-libressl.patch
new file mode 100644
index 00000000..e6ec017d
--- /dev/null
+++ b/2920_sign-file-patch-for-libressl.patch
@@ -0,0 +1,16 @@
+--- a/scripts/sign-file.c 2020-05-20 18:47:21.282820662 -0400
++++ b/scripts/sign-file.c 2020-05-20 18:48:37.991081899 -0400
+@@ -41,9 +41,10 @@
+ * signing with anything other than SHA1 - so we're stuck with that if such is
+ * the case.
+ */
+-#if defined(LIBRESSL_VERSION_NUMBER) || \
+- OPENSSL_VERSION_NUMBER < 0x10000000L || \
+- defined(OPENSSL_NO_CMS)
++#if defined(OPENSSL_NO_CMS) || \
++ ( defined(LIBRESSL_VERSION_NUMBER) \
++ && (LIBRESSL_VERSION_NUMBER < 0x3010000fL) ) || \
++ OPENSSL_VERSION_NUMBER < 0x10000000L
+ #define USE_PKCS7
+ #endif
+ #ifndef USE_PKCS7
diff --git a/3000_Support-printing-firmware-info.patch b/3000_Support-printing-firmware-info.patch
new file mode 100644
index 00000000..a630cfbe
--- /dev/null
+++ b/3000_Support-printing-firmware-info.patch
@@ -0,0 +1,14 @@
+--- a/drivers/base/firmware_loader/main.c 2021-08-24 15:42:07.025482085 -0400
++++ b/drivers/base/firmware_loader/main.c 2021-08-24 15:44:40.782975313 -0400
+@@ -809,6 +809,11 @@ _request_firmware(const struct firmware
+
+ ret = _request_firmware_prepare(&fw, name, device, buf, size,
+ offset, opt_flags);
++
++#ifdef CONFIG_GENTOO_PRINT_FIRMWARE_INFO
++ printk(KERN_NOTICE "Loading firmware: %s\n", name);
++#endif
++
+ if (ret <= 0) /* error or already assigned */
+ goto out;
+
diff --git a/5010_enable-cpu-optimizations-universal.patch b/5010_enable-cpu-optimizations-universal.patch
new file mode 100644
index 00000000..b9c03cb6
--- /dev/null
+++ b/5010_enable-cpu-optimizations-universal.patch
@@ -0,0 +1,675 @@
+From b5892719c43f739343c628e3d357471a3bdaa368 Mon Sep 17 00:00:00 2001
+From: graysky <graysky@archlinux.us>
+Date: Tue, 15 Mar 2022 05:58:43 -0400
+Subject: [PATCH] more uarches for kernel 5.17+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+FEATURES
+This patch adds additional CPU options to the Linux kernel accessible under:
+ Processor type and features --->
+ Processor family --->
+
+With the release of gcc 11.1 and clang 12.0, several generic 64-bit levels are
+offered which are good for supported Intel or AMD CPUs:
+• x86-64-v2
+• x86-64-v3
+• x86-64-v4
+
+Users of glibc 2.33 and above can see which level is supported by current
+hardware by running:
+ /lib/ld-linux-x86-64.so.2 --help | grep supported
+
+Alternatively, compare the flags from /proc/cpuinfo to this list.[1]
+
+CPU-specific microarchitectures include:
+• AMD Improved K8-family
+• AMD K10-family
+• AMD Family 10h (Barcelona)
+• AMD Family 14h (Bobcat)
+• AMD Family 16h (Jaguar)
+• AMD Family 15h (Bulldozer)
+• AMD Family 15h (Piledriver)
+• AMD Family 15h (Steamroller)
+• AMD Family 15h (Excavator)
+• AMD Family 17h (Zen)
+• AMD Family 17h (Zen 2)
+• AMD Family 19h (Zen 3)†
+• Intel Silvermont low-power processors
+• Intel Goldmont low-power processors (Apollo Lake and Denverton)
+• Intel Goldmont Plus low-power processors (Gemini Lake)
+• Intel 1st Gen Core i3/i5/i7 (Nehalem)
+• Intel 1.5 Gen Core i3/i5/i7 (Westmere)
+• Intel 2nd Gen Core i3/i5/i7 (Sandybridge)
+• Intel 3rd Gen Core i3/i5/i7 (Ivybridge)
+• Intel 4th Gen Core i3/i5/i7 (Haswell)
+• Intel 5th Gen Core i3/i5/i7 (Broadwell)
+• Intel 6th Gen Core i3/i5/i7 (Skylake)
+• Intel 6th Gen Core i7/i9 (Skylake X)
+• Intel 8th Gen Core i3/i5/i7 (Cannon Lake)
+• Intel 10th Gen Core i7/i9 (Ice Lake)
+• Intel Xeon (Cascade Lake)
+• Intel Xeon (Cooper Lake)*
+• Intel 3rd Gen 10nm++ i3/i5/i7/i9-family (Tiger Lake)*
+• Intel 3rd Gen 10nm++ Xeon (Sapphire Rapids)‡
+• Intel 11th Gen i3/i5/i7/i9-family (Rocket Lake)‡
+• Intel 12th Gen i3/i5/i7/i9-family (Alder Lake)‡
+
+Notes: If not otherwise noted, gcc >=9.1 is required for support.
+ *Requires gcc >=10.1 or clang >=10.0
+ †Required gcc >=10.3 or clang >=12.0
+ ‡Required gcc >=11.1 or clang >=12.0
+
+It also offers to compile passing the 'native' option which, "selects the CPU
+to generate code for at compilation time by determining the processor type of
+the compiling machine. Using -march=native enables all instruction subsets
+supported by the local machine and will produce code optimized for the local
+machine under the constraints of the selected instruction set."[2]
+
+Users of Intel CPUs should select the 'Intel-Native' option and users of AMD
+CPUs should select the 'AMD-Native' option.
+
+MINOR NOTES RELATING TO INTEL ATOM PROCESSORS
+This patch also changes -march=atom to -march=bonnell in accordance with the
+gcc v4.9 changes. Upstream is using the deprecated -match=atom flags when I
+believe it should use the newer -march=bonnell flag for atom processors.[3]
+
+It is not recommended to compile on Atom-CPUs with the 'native' option.[4] The
+recommendation is to use the 'atom' option instead.
+
+BENEFITS
+Small but real speed increases are measurable using a make endpoint comparing
+a generic kernel to one built with one of the respective microarchs.
+
+See the following experimental evidence supporting this statement:
+https://github.com/graysky2/kernel_gcc_patch
+
+REQUIREMENTS
+linux version 5.17+
+gcc version >=9.0 or clang version >=9.0
+
+ACKNOWLEDGMENTS
+This patch builds on the seminal work by Jeroen.[5]
+
+REFERENCES
+1. https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/77566eb03bc6a326811cb7e9
+2. https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-x86-Options
+3. https://bugzilla.kernel.org/show_bug.cgi?id=77461
+4. https://github.com/graysky2/kernel_gcc_patch/issues/15
+5. http://www.linuxforge.net/docs/linux/linux-gcc.php
+
+Signed-off-by: graysky <graysky@archlinux.us>
+---
+ arch/x86/Kconfig.cpu | 332 ++++++++++++++++++++++++++++++--
+ arch/x86/Makefile | 40 +++-
+ arch/x86/include/asm/vermagic.h | 66 +++++++
+ 3 files changed, 424 insertions(+), 14 deletions(-)
+
+diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+index 542377cd419d..22b919cdb6d1 100644
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -157,7 +157,7 @@ config MPENTIUM4
+
+
+ config MK6
+- bool "K6/K6-II/K6-III"
++ bool "AMD K6/K6-II/K6-III"
+ depends on X86_32
+ help
+ Select this for an AMD K6-family processor. Enables use of
+@@ -165,7 +165,7 @@ config MK6
+ flags to GCC.
+
+ config MK7
+- bool "Athlon/Duron/K7"
++ bool "AMD Athlon/Duron/K7"
+ depends on X86_32
+ help
+ Select this for an AMD Athlon K7-family processor. Enables use of
+@@ -173,12 +173,98 @@ config MK7
+ flags to GCC.
+
+ config MK8
+- bool "Opteron/Athlon64/Hammer/K8"
++ bool "AMD Opteron/Athlon64/Hammer/K8"
+ help
+ Select this for an AMD Opteron or Athlon64 Hammer-family processor.
+ Enables use of some extended instructions, and passes appropriate
+ optimization flags to GCC.
+
++config MK8SSE3
++ bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
++ help
++ Select this for improved AMD Opteron or Athlon64 Hammer-family processors.
++ Enables use of some extended instructions, and passes appropriate
++ optimization flags to GCC.
++
++config MK10
++ bool "AMD 61xx/7x50/PhenomX3/X4/II/K10"
++ help
++ Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50,
++ Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor.
++ Enables use of some extended instructions, and passes appropriate
++ optimization flags to GCC.
++
++config MBARCELONA
++ bool "AMD Barcelona"
++ help
++ Select this for AMD Family 10h Barcelona processors.
++
++ Enables -march=barcelona
++
++config MBOBCAT
++ bool "AMD Bobcat"
++ help
++ Select this for AMD Family 14h Bobcat processors.
++
++ Enables -march=btver1
++
++config MJAGUAR
++ bool "AMD Jaguar"
++ help
++ Select this for AMD Family 16h Jaguar processors.
++
++ Enables -march=btver2
++
++config MBULLDOZER
++ bool "AMD Bulldozer"
++ help
++ Select this for AMD Family 15h Bulldozer processors.
++
++ Enables -march=bdver1
++
++config MPILEDRIVER
++ bool "AMD Piledriver"
++ help
++ Select this for AMD Family 15h Piledriver processors.
++
++ Enables -march=bdver2
++
++config MSTEAMROLLER
++ bool "AMD Steamroller"
++ help
++ Select this for AMD Family 15h Steamroller processors.
++
++ Enables -march=bdver3
++
++config MEXCAVATOR
++ bool "AMD Excavator"
++ help
++ Select this for AMD Family 15h Excavator processors.
++
++ Enables -march=bdver4
++
++config MZEN
++ bool "AMD Zen"
++ help
++ Select this for AMD Family 17h Zen processors.
++
++ Enables -march=znver1
++
++config MZEN2
++ bool "AMD Zen 2"
++ help
++ Select this for AMD Family 17h Zen 2 processors.
++
++ Enables -march=znver2
++
++config MZEN3
++ bool "AMD Zen 3"
++ depends on (CC_IS_GCC && GCC_VERSION >= 100300) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ help
++ Select this for AMD Family 19h Zen 3 processors.
++
++ Enables -march=znver3
++
+ config MCRUSOE
+ bool "Crusoe"
+ depends on X86_32
+@@ -270,7 +356,7 @@ config MPSC
+ in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
+
+ config MCORE2
+- bool "Core 2/newer Xeon"
++ bool "Intel Core 2"
+ help
+
+ Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
+@@ -278,6 +364,8 @@ config MCORE2
+ family in /proc/cpuinfo. Newer ones have 6 and older ones 15
+ (not a typo)
+
++ Enables -march=core2
++
+ config MATOM
+ bool "Intel Atom"
+ help
+@@ -287,6 +375,182 @@ config MATOM
+ accordingly optimized code. Use a recent GCC with specific Atom
+ support in order to fully benefit from selecting this option.
+
++config MNEHALEM
++ bool "Intel Nehalem"
++ select X86_P6_NOP
++ help
++
++ Select this for 1st Gen Core processors in the Nehalem family.
++
++ Enables -march=nehalem
++
++config MWESTMERE
++ bool "Intel Westmere"
++ select X86_P6_NOP
++ help
++
++ Select this for the Intel Westmere formerly Nehalem-C family.
++
++ Enables -march=westmere
++
++config MSILVERMONT
++ bool "Intel Silvermont"
++ select X86_P6_NOP
++ help
++
++ Select this for the Intel Silvermont platform.
++
++ Enables -march=silvermont
++
++config MGOLDMONT
++ bool "Intel Goldmont"
++ select X86_P6_NOP
++ help
++
++ Select this for the Intel Goldmont platform including Apollo Lake and Denverton.
++
++ Enables -march=goldmont
++
++config MGOLDMONTPLUS
++ bool "Intel Goldmont Plus"
++ select X86_P6_NOP
++ help
++
++ Select this for the Intel Goldmont Plus platform including Gemini Lake.
++
++ Enables -march=goldmont-plus
++
++config MSANDYBRIDGE
++ bool "Intel Sandy Bridge"
++ select X86_P6_NOP
++ help
++
++ Select this for 2nd Gen Core processors in the Sandy Bridge family.
++
++ Enables -march=sandybridge
++
++config MIVYBRIDGE
++ bool "Intel Ivy Bridge"
++ select X86_P6_NOP
++ help
++
++ Select this for 3rd Gen Core processors in the Ivy Bridge family.
++
++ Enables -march=ivybridge
++
++config MHASWELL
++ bool "Intel Haswell"
++ select X86_P6_NOP
++ help
++
++ Select this for 4th Gen Core processors in the Haswell family.
++
++ Enables -march=haswell
++
++config MBROADWELL
++ bool "Intel Broadwell"
++ select X86_P6_NOP
++ help
++
++ Select this for 5th Gen Core processors in the Broadwell family.
++
++ Enables -march=broadwell
++
++config MSKYLAKE
++ bool "Intel Skylake"
++ select X86_P6_NOP
++ help
++
++ Select this for 6th Gen Core processors in the Skylake family.
++
++ Enables -march=skylake
++
++config MSKYLAKEX
++ bool "Intel Skylake X"
++ select X86_P6_NOP
++ help
++
++ Select this for 6th Gen Core processors in the Skylake X family.
++
++ Enables -march=skylake-avx512
++
++config MCANNONLAKE
++ bool "Intel Cannon Lake"
++ select X86_P6_NOP
++ help
++
++ Select this for 8th Gen Core processors
++
++ Enables -march=cannonlake
++
++config MICELAKE
++ bool "Intel Ice Lake"
++ select X86_P6_NOP
++ help
++
++ Select this for 10th Gen Core processors in the Ice Lake family.
++
++ Enables -march=icelake-client
++
++config MCASCADELAKE
++ bool "Intel Cascade Lake"
++ select X86_P6_NOP
++ help
++
++ Select this for Xeon processors in the Cascade Lake family.
++
++ Enables -march=cascadelake
++
++config MCOOPERLAKE
++ bool "Intel Cooper Lake"
++ depends on (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000)
++ select X86_P6_NOP
++ help
++
++ Select this for Xeon processors in the Cooper Lake family.
++
++ Enables -march=cooperlake
++
++config MTIGERLAKE
++ bool "Intel Tiger Lake"
++ depends on (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000)
++ select X86_P6_NOP
++ help
++
++ Select this for third-generation 10 nm process processors in the Tiger Lake family.
++
++ Enables -march=tigerlake
++
++config MSAPPHIRERAPIDS
++ bool "Intel Sapphire Rapids"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ select X86_P6_NOP
++ help
++
++ Select this for third-generation 10 nm process processors in the Sapphire Rapids family.
++
++ Enables -march=sapphirerapids
++
++config MROCKETLAKE
++ bool "Intel Rocket Lake"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ select X86_P6_NOP
++ help
++
++ Select this for eleventh-generation processors in the Rocket Lake family.
++
++ Enables -march=rocketlake
++
++config MALDERLAKE
++ bool "Intel Alder Lake"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ select X86_P6_NOP
++ help
++
++ Select this for twelfth-generation processors in the Alder Lake family.
++
++ Enables -march=alderlake
++
+ config GENERIC_CPU
+ bool "Generic-x86-64"
+ depends on X86_64
+@@ -294,6 +558,50 @@ config GENERIC_CPU
+ Generic x86-64 CPU.
+ Run equally well on all x86-64 CPUs.
+
++config GENERIC_CPU2
++ bool "Generic-x86-64-v2"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ depends on X86_64
++ help
++ Generic x86-64 CPU.
++ Run equally well on all x86-64 CPUs with min support of x86-64-v2.
++
++config GENERIC_CPU3
++ bool "Generic-x86-64-v3"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ depends on X86_64
++ help
++ Generic x86-64-v3 CPU with v3 instructions.
++ Run equally well on all x86-64 CPUs with min support of x86-64-v3.
++
++config GENERIC_CPU4
++ bool "Generic-x86-64-v4"
++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++ depends on X86_64
++ help
++ Generic x86-64 CPU with v4 instructions.
++ Run equally well on all x86-64 CPUs with min support of x86-64-v4.
++
++config MNATIVE_INTEL
++ bool "Intel-Native optimizations autodetected by the compiler"
++ help
++
++ Clang 3.8, GCC 4.2 and above support -march=native, which automatically detects
++ the optimum settings to use based on your processor. Do NOT use this
++ for AMD CPUs. Intel Only!
++
++ Enables -march=native
++
++config MNATIVE_AMD
++ bool "AMD-Native optimizations autodetected by the compiler"
++ help
++
++ Clang 3.8, GCC 4.2 and above support -march=native, which automatically detects
++ the optimum settings to use based on your processor. Do NOT use this
++ for Intel CPUs. AMD Only!
++
++ Enables -march=native
++
+ endchoice
+
+ config X86_GENERIC
+@@ -318,7 +626,7 @@ config X86_INTERNODE_CACHE_SHIFT
+ config X86_L1_CACHE_SHIFT
+ int
+ default "7" if MPENTIUM4 || MPSC
+- default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
++ default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 || GENERIC_CPU4
+ default "4" if MELAN || M486SX || M486 || MGEODEGX1
+ default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
+
+@@ -336,11 +644,11 @@ config X86_ALIGNMENT_16
+
+ config X86_INTEL_USERCOPY
+ def_bool y
+- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
++ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL
+
+ config X86_USE_PPRO_CHECKSUM
+ def_bool y
+- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
+ #
+ # P6_NOPs are a relatively minor optimization that require a family >=
+@@ -356,26 +664,26 @@ config X86_USE_PPRO_CHECKSUM
+ config X86_P6_NOP
+ def_bool y
+ depends on X86_64
+- depends on (MCORE2 || MPENTIUM4 || MPSC)
++ depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL)
+
+ config X86_TSC
+ def_bool y
+- depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
++ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD) || X86_64
+
+ config X86_CMPXCHG64
+ def_bool y
+- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8
++ depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
+ # this should be set for all -march=.. options where the compiler
+ # generates cmov.
+ config X86_CMOV
+ def_bool y
+- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
++ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+
+ config X86_MINIMUM_CPU_FAMILY
+ int
+ default "64" if X86_64
+- default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8)
++ default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+ default "5" if X86_32 && X86_CMPXCHG64
+ default "4"
+
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index e84cdd409b64..7d3bbf060079 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -131,8 +131,44 @@ else
+ # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
+ cflags-$(CONFIG_MK8) += -march=k8
+ cflags-$(CONFIG_MPSC) += -march=nocona
+- cflags-$(CONFIG_MCORE2) += -march=core2
+- cflags-$(CONFIG_MATOM) += -march=atom
++ cflags-$(CONFIG_MK8SSE3) += -march=k8-sse3
++ cflags-$(CONFIG_MK10) += -march=amdfam10
++ cflags-$(CONFIG_MBARCELONA) += -march=barcelona
++ cflags-$(CONFIG_MBOBCAT) += -march=btver1
++ cflags-$(CONFIG_MJAGUAR) += -march=btver2
++ cflags-$(CONFIG_MBULLDOZER) += -march=bdver1
++ cflags-$(CONFIG_MPILEDRIVER) += -march=bdver2 -mno-tbm
++ cflags-$(CONFIG_MSTEAMROLLER) += -march=bdver3 -mno-tbm
++ cflags-$(CONFIG_MEXCAVATOR) += -march=bdver4 -mno-tbm
++ cflags-$(CONFIG_MZEN) += -march=znver1
++ cflags-$(CONFIG_MZEN2) += -march=znver2
++ cflags-$(CONFIG_MZEN3) += -march=znver3
++ cflags-$(CONFIG_MNATIVE_INTEL) += -march=native
++ cflags-$(CONFIG_MNATIVE_AMD) += -march=native
++ cflags-$(CONFIG_MATOM) += -march=bonnell
++ cflags-$(CONFIG_MCORE2) += -march=core2
++ cflags-$(CONFIG_MNEHALEM) += -march=nehalem
++ cflags-$(CONFIG_MWESTMERE) += -march=westmere
++ cflags-$(CONFIG_MSILVERMONT) += -march=silvermont
++ cflags-$(CONFIG_MGOLDMONT) += -march=goldmont
++ cflags-$(CONFIG_MGOLDMONTPLUS) += -march=goldmont-plus
++ cflags-$(CONFIG_MSANDYBRIDGE) += -march=sandybridge
++ cflags-$(CONFIG_MIVYBRIDGE) += -march=ivybridge
++ cflags-$(CONFIG_MHASWELL) += -march=haswell
++ cflags-$(CONFIG_MBROADWELL) += -march=broadwell
++ cflags-$(CONFIG_MSKYLAKE) += -march=skylake
++ cflags-$(CONFIG_MSKYLAKEX) += -march=skylake-avx512
++ cflags-$(CONFIG_MCANNONLAKE) += -march=cannonlake
++ cflags-$(CONFIG_MICELAKE) += -march=icelake-client
++ cflags-$(CONFIG_MCASCADELAKE) += -march=cascadelake
++ cflags-$(CONFIG_MCOOPERLAKE) += -march=cooperlake
++ cflags-$(CONFIG_MTIGERLAKE) += -march=tigerlake
++ cflags-$(CONFIG_MSAPPHIRERAPIDS) += -march=sapphirerapids
++ cflags-$(CONFIG_MROCKETLAKE) += -march=rocketlake
++ cflags-$(CONFIG_MALDERLAKE) += -march=alderlake
++ cflags-$(CONFIG_GENERIC_CPU2) += -march=x86-64-v2
++ cflags-$(CONFIG_GENERIC_CPU3) += -march=x86-64-v3
++ cflags-$(CONFIG_GENERIC_CPU4) += -march=x86-64-v4
+ cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic
+ KBUILD_CFLAGS += $(cflags-y)
+
+diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h
+index 75884d2cdec3..4e6a08d4c7e5 100644
+--- a/arch/x86/include/asm/vermagic.h
++++ b/arch/x86/include/asm/vermagic.h
+@@ -17,6 +17,48 @@
+ #define MODULE_PROC_FAMILY "586MMX "
+ #elif defined CONFIG_MCORE2
+ #define MODULE_PROC_FAMILY "CORE2 "
++#elif defined CONFIG_MNATIVE_INTEL
++#define MODULE_PROC_FAMILY "NATIVE_INTEL "
++#elif defined CONFIG_MNATIVE_AMD
++#define MODULE_PROC_FAMILY "NATIVE_AMD "
++#elif defined CONFIG_MNEHALEM
++#define MODULE_PROC_FAMILY "NEHALEM "
++#elif defined CONFIG_MWESTMERE
++#define MODULE_PROC_FAMILY "WESTMERE "
++#elif defined CONFIG_MSILVERMONT
++#define MODULE_PROC_FAMILY "SILVERMONT "
++#elif defined CONFIG_MGOLDMONT
++#define MODULE_PROC_FAMILY "GOLDMONT "
++#elif defined CONFIG_MGOLDMONTPLUS
++#define MODULE_PROC_FAMILY "GOLDMONTPLUS "
++#elif defined CONFIG_MSANDYBRIDGE
++#define MODULE_PROC_FAMILY "SANDYBRIDGE "
++#elif defined CONFIG_MIVYBRIDGE
++#define MODULE_PROC_FAMILY "IVYBRIDGE "
++#elif defined CONFIG_MHASWELL
++#define MODULE_PROC_FAMILY "HASWELL "
++#elif defined CONFIG_MBROADWELL
++#define MODULE_PROC_FAMILY "BROADWELL "
++#elif defined CONFIG_MSKYLAKE
++#define MODULE_PROC_FAMILY "SKYLAKE "
++#elif defined CONFIG_MSKYLAKEX
++#define MODULE_PROC_FAMILY "SKYLAKEX "
++#elif defined CONFIG_MCANNONLAKE
++#define MODULE_PROC_FAMILY "CANNONLAKE "
++#elif defined CONFIG_MICELAKE
++#define MODULE_PROC_FAMILY "ICELAKE "
++#elif defined CONFIG_MCASCADELAKE
++#define MODULE_PROC_FAMILY "CASCADELAKE "
++#elif defined CONFIG_MCOOPERLAKE
++#define MODULE_PROC_FAMILY "COOPERLAKE "
++#elif defined CONFIG_MTIGERLAKE
++#define MODULE_PROC_FAMILY "TIGERLAKE "
++#elif defined CONFIG_MSAPPHIRERAPIDS
++#define MODULE_PROC_FAMILY "SAPPHIRERAPIDS "
++#elif defined CONFIG_ROCKETLAKE
++#define MODULE_PROC_FAMILY "ROCKETLAKE "
++#elif defined CONFIG_MALDERLAKE
++#define MODULE_PROC_FAMILY "ALDERLAKE "
+ #elif defined CONFIG_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
+ #elif defined CONFIG_M686
+@@ -35,6 +77,30 @@
+ #define MODULE_PROC_FAMILY "K7 "
+ #elif defined CONFIG_MK8
+ #define MODULE_PROC_FAMILY "K8 "
++#elif defined CONFIG_MK8SSE3
++#define MODULE_PROC_FAMILY "K8SSE3 "
++#elif defined CONFIG_MK10
++#define MODULE_PROC_FAMILY "K10 "
++#elif defined CONFIG_MBARCELONA
++#define MODULE_PROC_FAMILY "BARCELONA "
++#elif defined CONFIG_MBOBCAT
++#define MODULE_PROC_FAMILY "BOBCAT "
++#elif defined CONFIG_MBULLDOZER
++#define MODULE_PROC_FAMILY "BULLDOZER "
++#elif defined CONFIG_MPILEDRIVER
++#define MODULE_PROC_FAMILY "PILEDRIVER "
++#elif defined CONFIG_MSTEAMROLLER
++#define MODULE_PROC_FAMILY "STEAMROLLER "
++#elif defined CONFIG_MJAGUAR
++#define MODULE_PROC_FAMILY "JAGUAR "
++#elif defined CONFIG_MEXCAVATOR
++#define MODULE_PROC_FAMILY "EXCAVATOR "
++#elif defined CONFIG_MZEN
++#define MODULE_PROC_FAMILY "ZEN "
++#elif defined CONFIG_MZEN2
++#define MODULE_PROC_FAMILY "ZEN2 "
++#elif defined CONFIG_MZEN3
++#define MODULE_PROC_FAMILY "ZEN3 "
+ #elif defined CONFIG_MELAN
+ #define MODULE_PROC_FAMILY "ELAN "
+ #elif defined CONFIG_MCRUSOE
+--
+2.35.1
+
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-03 9:31 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-03 9:31 UTC (permalink / raw
To: gentoo-commits
commit: 47fadfe6806d9429b6e567e2f4123e0984621a41
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 3 09:30:51 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Oct 3 09:30:51 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47fadfe6
Remove unneeded patch
Removed:
2700_revert-drm-i915-dma-resv-obj-fix.patch
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 --
2700_revert-drm-i915-dma-resv-obj-fix.patch | 107 ----------------------------
2 files changed, 111 deletions(-)
diff --git a/0000_README b/0000_README
index b3a5a14c..b1b7f794 100644
--- a/0000_README
+++ b/0000_README
@@ -59,10 +59,6 @@ Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
-Patch: 2700_revert-drm-i915-dma-resv-obj-fix.patch
-From: https://bugs.gentoo.org/866023
-Desc: Revert Revert for drm i915 thanks to Luigi 'Comio' Mantellini
-
Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
From: https://bugs.gentoo.org/710790
Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
diff --git a/2700_revert-drm-i915-dma-resv-obj-fix.patch b/2700_revert-drm-i915-dma-resv-obj-fix.patch
deleted file mode 100644
index a9fcaf4a..00000000
--- a/2700_revert-drm-i915-dma-resv-obj-fix.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From d481c481ca7813d688ffcb1c5418b48f83d945c1 Mon Sep 17 00:00:00 2001
-From: Luigi 'Comio' Mantellini <luigi.mantellini@gmail.com>
-Date: Sun, 28 Aug 2022 09:17:35 +0200
-Subject: [PATCH] Revert "drm/i915: Individualize fences before adding to
- dma_resv obj"
-
-This reverts commit 842d9346b2fdda4d2fb8ccb5b87faef1ac01ab51.
----
- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 3 +-
- drivers/gpu/drm/i915/i915_vma.c | 48 ++++++++-----------
- 2 files changed, 21 insertions(+), 30 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-index 30fe847c6664..c326bd2b444f 100644
---- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-@@ -999,8 +999,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
- }
- }
-
-- /* Reserve enough slots to accommodate composite fences */
-- err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
-+ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
- if (err)
- return err;
-
-diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
-index 16460b169ed2..e71826f0e4b1 100644
---- a/drivers/gpu/drm/i915/i915_vma.c
-+++ b/drivers/gpu/drm/i915/i915_vma.c
-@@ -23,7 +23,6 @@
- */
-
- #include <linux/sched/mm.h>
--#include <linux/dma-fence-array.h>
- #include <drm/drm_gem.h>
-
- #include "display/intel_frontbuffer.h"
-@@ -1839,21 +1838,6 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
- if (unlikely(err))
- return err;
-
-- /*
-- * Reserve fences slot early to prevent an allocation after preparing
-- * the workload and associating fences with dma_resv.
-- */
-- if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
-- struct dma_fence *curr;
-- int idx;
--
-- dma_fence_array_for_each(curr, idx, fence)
-- ;
-- err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
-- if (unlikely(err))
-- return err;
-- }
--
- if (flags & EXEC_OBJECT_WRITE) {
- struct intel_frontbuffer *front;
-
-@@ -1863,23 +1847,31 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
- i915_active_add_request(&front->write, rq);
- intel_frontbuffer_put(front);
- }
-- }
-
-- if (fence) {
-- struct dma_fence *curr;
-- enum dma_resv_usage usage;
-- int idx;
-+ if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-+ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-+ if (unlikely(err))
-+ return err;
-+ }
-
-- obj->read_domains = 0;
-- if (flags & EXEC_OBJECT_WRITE) {
-- usage = DMA_RESV_USAGE_WRITE;
-+ if (fence) {
-+ dma_resv_add_fence(vma->obj->base.resv, fence,
-+ DMA_RESV_USAGE_WRITE);
- obj->write_domain = I915_GEM_DOMAIN_RENDER;
-- } else {
-- usage = DMA_RESV_USAGE_READ;
-+ obj->read_domains = 0;
-+ }
-+ } else {
-+ if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-+ err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-+ if (unlikely(err))
-+ return err;
- }
-
-- dma_fence_array_for_each(curr, idx, fence)
-- dma_resv_add_fence(vma->obj->base.resv, curr, usage);
-+ if (fence) {
-+ dma_resv_add_fence(vma->obj->base.resv, fence,
-+ DMA_RESV_USAGE_READ);
-+ obj->write_domain = 0;
-+ }
- }
-
- if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
---
-2.37.2
-
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-12 11:16 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-12 11:16 UTC (permalink / raw
To: gentoo-commits
commit: 8490dd01d19bf4575c039ed85c60163a5c2bad17
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 12 11:16:28 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Oct 12 11:16:28 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8490dd01
Linux patch 6.0.1
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1000_linux-6.0.1.patch | 771 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 775 insertions(+)
diff --git a/0000_README b/0000_README
index b1b7f794..d41088d3 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,10 @@ EXPERIMENTAL
Individual Patch Descriptions:
--------------------------------------------------------------------------
+Patch: 1000_linux-6.0.1.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.1
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1000_linux-6.0.1.patch b/1000_linux-6.0.1.patch
new file mode 100644
index 00000000..9165364b
--- /dev/null
+++ b/1000_linux-6.0.1.patch
@@ -0,0 +1,771 @@
+diff --git a/Documentation/process/code-of-conduct-interpretation.rst b/Documentation/process/code-of-conduct-interpretation.rst
+index e899f14a4ba24..4f8a06b00f608 100644
+--- a/Documentation/process/code-of-conduct-interpretation.rst
++++ b/Documentation/process/code-of-conduct-interpretation.rst
+@@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're
+ uncertain how to handle situations that come up. It will not be
+ considered a violation report unless you want it to be. If you are
+ uncertain about approaching the TAB or any other maintainers, please
+-reach out to our conflict mediator, Mishi Choudhary <mishi@linux.com>.
++reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>.
+
+ In the end, "be kind to each other" is really what the end goal is for
+ everybody. We know everyone is human and we all fail at times, but the
+diff --git a/Makefile b/Makefile
+index 8478e13e9424a..3193969f1eb37 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 0
++SUBLEVEL = 1
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+@@ -831,8 +831,8 @@ endif
+ # Initialize all stack variables with a zero value.
+ ifdef CONFIG_INIT_STACK_ALL_ZERO
+ KBUILD_CFLAGS += -ftrivial-auto-var-init=zero
+-ifdef CONFIG_CC_IS_CLANG
+-# https://bugs.llvm.org/show_bug.cgi?id=45497
++ifdef CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
++# https://github.com/llvm/llvm-project/issues/44842
+ KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
+ endif
+ endif
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 0be8a2403212d..87455d12970f3 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -92,10 +92,10 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
+ */
+ static struct riscv_isa_ext_data isa_ext_arr[] = {
+ __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
++ __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+ __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
+ __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
+ __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
+- __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+ __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
+ };
+
+diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
+index 856081761b0fc..2cf7971d7f6c9 100644
+--- a/arch/sparc/include/asm/smp_32.h
++++ b/arch/sparc/include/asm/smp_32.h
+@@ -33,9 +33,6 @@ extern volatile unsigned long cpu_callin_map[NR_CPUS];
+ extern cpumask_t smp_commenced_mask;
+ extern struct linux_prom_registers smp_penguin_ctable;
+
+-typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+- unsigned long, unsigned long);
+-
+ void cpu_panic(void);
+
+ /*
+@@ -57,7 +54,7 @@ void smp_bogo(struct seq_file *);
+ void smp_info(struct seq_file *);
+
+ struct sparc32_ipi_ops {
+- void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++ void (*cross_call)(void *func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4);
+ void (*resched)(int cpu);
+@@ -66,28 +63,28 @@ struct sparc32_ipi_ops {
+ };
+ extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
+
+-static inline void xc0(smpfunc_t func)
++static inline void xc0(void *func)
+ {
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
+ }
+
+-static inline void xc1(smpfunc_t func, unsigned long arg1)
++static inline void xc1(void *func, unsigned long arg1)
+ {
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0);
+ }
+-static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
++static inline void xc2(void *func, unsigned long arg1, unsigned long arg2)
+ {
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0);
+ }
+
+-static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
++static inline void xc3(void *func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3)
+ {
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+ arg1, arg2, arg3, 0);
+ }
+
+-static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
++static inline void xc4(void *func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4)
+ {
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
+index 1eed26d423fb2..991e9ad3d3e8f 100644
+--- a/arch/sparc/kernel/leon_smp.c
++++ b/arch/sparc/kernel/leon_smp.c
+@@ -359,7 +359,7 @@ void leonsmp_ipi_interrupt(void)
+ }
+
+ static struct smp_funcall {
+- smpfunc_t func;
++ void *func;
+ unsigned long arg1;
+ unsigned long arg2;
+ unsigned long arg3;
+@@ -372,7 +372,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+
+ /* Cross calls must be serialized, at least currently. */
+-static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+ {
+@@ -384,7 +384,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+
+ {
+ /* If you make changes here, make sure gcc generates proper code... */
+- register smpfunc_t f asm("i0") = func;
++ register void *f asm("i0") = func;
+ register unsigned long a1 asm("i1") = arg1;
+ register unsigned long a2 asm("i2") = arg2;
+ register unsigned long a3 asm("i3") = arg3;
+@@ -444,11 +444,13 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void leon_cross_call_irq(void)
+ {
++ void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++ unsigned long) = ccall_info.func;
+ int i = smp_processor_id();
+
+ ccall_info.processors_in[i] = 1;
+- ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+- ccall_info.arg4, ccall_info.arg5);
++ func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++ ccall_info.arg5);
+ ccall_info.processors_out[i] = 1;
+ }
+
+diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
+index ff30f03beb7c7..9a62a5cf33370 100644
+--- a/arch/sparc/kernel/sun4d_smp.c
++++ b/arch/sparc/kernel/sun4d_smp.c
+@@ -268,7 +268,7 @@ static void sun4d_ipi_resched(int cpu)
+ }
+
+ static struct smp_funcall {
+- smpfunc_t func;
++ void *func;
+ unsigned long arg1;
+ unsigned long arg2;
+ unsigned long arg3;
+@@ -281,7 +281,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+
+ /* Cross calls must be serialized, at least currently. */
+-static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+ {
+@@ -296,7 +296,7 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ * If you make changes here, make sure
+ * gcc generates proper code...
+ */
+- register smpfunc_t f asm("i0") = func;
++ register void *f asm("i0") = func;
+ register unsigned long a1 asm("i1") = arg1;
+ register unsigned long a2 asm("i2") = arg2;
+ register unsigned long a3 asm("i3") = arg3;
+@@ -353,11 +353,13 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void smp4d_cross_call_irq(void)
+ {
++ void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++ unsigned long) = ccall_info.func;
+ int i = hard_smp_processor_id();
+
+ ccall_info.processors_in[i] = 1;
+- ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+- ccall_info.arg4, ccall_info.arg5);
++ func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++ ccall_info.arg5);
+ ccall_info.processors_out[i] = 1;
+ }
+
+diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
+index 228a6527082dc..056df034e79ee 100644
+--- a/arch/sparc/kernel/sun4m_smp.c
++++ b/arch/sparc/kernel/sun4m_smp.c
+@@ -157,7 +157,7 @@ static void sun4m_ipi_mask_one(int cpu)
+ }
+
+ static struct smp_funcall {
+- smpfunc_t func;
++ void *func;
+ unsigned long arg1;
+ unsigned long arg2;
+ unsigned long arg3;
+@@ -170,7 +170,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+
+ /* Cross calls must be serialized, at least currently. */
+-static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+ {
+@@ -230,11 +230,13 @@ static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void smp4m_cross_call_irq(void)
+ {
++ void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++ unsigned long) = ccall_info.func;
+ int i = smp_processor_id();
+
+ ccall_info.processors_in[i] = 1;
+- ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+- ccall_info.arg4, ccall_info.arg5);
++ func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++ ccall_info.arg5);
+ ccall_info.processors_out[i] = 1;
+ }
+
+diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
+index a9aa6a92c7fee..13f027afc875c 100644
+--- a/arch/sparc/mm/srmmu.c
++++ b/arch/sparc/mm/srmmu.c
+@@ -1636,19 +1636,19 @@ static void __init get_srmmu_type(void)
+ /* Local cross-calls. */
+ static void smp_flush_page_for_dma(unsigned long page)
+ {
+- xc1((smpfunc_t) local_ops->page_for_dma, page);
++ xc1(local_ops->page_for_dma, page);
+ local_ops->page_for_dma(page);
+ }
+
+ static void smp_flush_cache_all(void)
+ {
+- xc0((smpfunc_t) local_ops->cache_all);
++ xc0(local_ops->cache_all);
+ local_ops->cache_all();
+ }
+
+ static void smp_flush_tlb_all(void)
+ {
+- xc0((smpfunc_t) local_ops->tlb_all);
++ xc0(local_ops->tlb_all);
+ local_ops->tlb_all();
+ }
+
+@@ -1659,7 +1659,7 @@ static void smp_flush_cache_mm(struct mm_struct *mm)
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc1((smpfunc_t) local_ops->cache_mm, (unsigned long) mm);
++ xc1(local_ops->cache_mm, (unsigned long)mm);
+ local_ops->cache_mm(mm);
+ }
+ }
+@@ -1671,7 +1671,7 @@ static void smp_flush_tlb_mm(struct mm_struct *mm)
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask)) {
+- xc1((smpfunc_t) local_ops->tlb_mm, (unsigned long) mm);
++ xc1(local_ops->tlb_mm, (unsigned long)mm);
+ if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
+ cpumask_copy(mm_cpumask(mm),
+ cpumask_of(smp_processor_id()));
+@@ -1691,8 +1691,8 @@ static void smp_flush_cache_range(struct vm_area_struct *vma,
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc3((smpfunc_t) local_ops->cache_range,
+- (unsigned long) vma, start, end);
++ xc3(local_ops->cache_range, (unsigned long)vma, start,
++ end);
+ local_ops->cache_range(vma, start, end);
+ }
+ }
+@@ -1708,8 +1708,8 @@ static void smp_flush_tlb_range(struct vm_area_struct *vma,
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc3((smpfunc_t) local_ops->tlb_range,
+- (unsigned long) vma, start, end);
++ xc3(local_ops->tlb_range, (unsigned long)vma, start,
++ end);
+ local_ops->tlb_range(vma, start, end);
+ }
+ }
+@@ -1723,8 +1723,7 @@ static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc2((smpfunc_t) local_ops->cache_page,
+- (unsigned long) vma, page);
++ xc2(local_ops->cache_page, (unsigned long)vma, page);
+ local_ops->cache_page(vma, page);
+ }
+ }
+@@ -1738,8 +1737,7 @@ static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc2((smpfunc_t) local_ops->tlb_page,
+- (unsigned long) vma, page);
++ xc2(local_ops->tlb_page, (unsigned long)vma, page);
+ local_ops->tlb_page(vma, page);
+ }
+ }
+@@ -1753,7 +1751,7 @@ static void smp_flush_page_to_ram(unsigned long page)
+ * XXX This experiment failed, research further... -DaveM
+ */
+ #if 1
+- xc1((smpfunc_t) local_ops->page_to_ram, page);
++ xc1(local_ops->page_to_ram, page);
+ #endif
+ local_ops->page_to_ram(page);
+ }
+@@ -1764,8 +1762,7 @@ static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
+ cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ if (!cpumask_empty(&cpu_mask))
+- xc2((smpfunc_t) local_ops->sig_insns,
+- (unsigned long) mm, insn_addr);
++ xc2(local_ops->sig_insns, (unsigned long)mm, insn_addr);
+ local_ops->sig_insns(mm, insn_addr);
+ }
+
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
+index 9be1376f9a627..285ecbf107c95 100644
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -32,9 +32,16 @@ MODULE_PARM_DESC(ignore_wake,
+ "controller@pin combos on which to ignore the ACPI wake flag "
+ "ignore_wake=controller@pin[,controller@pin[,...]]");
+
++static char *ignore_interrupt;
++module_param(ignore_interrupt, charp, 0444);
++MODULE_PARM_DESC(ignore_interrupt,
++ "controller@pin combos on which to ignore interrupt "
++ "ignore_interrupt=controller@pin[,controller@pin[,...]]");
++
+ struct acpi_gpiolib_dmi_quirk {
+ bool no_edge_events_on_boot;
+ char *ignore_wake;
++ char *ignore_interrupt;
+ };
+
+ /**
+@@ -317,14 +324,15 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
+ return desc;
+ }
+
+-static bool acpi_gpio_in_ignore_list(const char *controller_in, unsigned int pin_in)
++static bool acpi_gpio_in_ignore_list(const char *ignore_list, const char *controller_in,
++ unsigned int pin_in)
+ {
+ const char *controller, *pin_str;
+ unsigned int pin;
+ char *endp;
+ int len;
+
+- controller = ignore_wake;
++ controller = ignore_list;
+ while (controller) {
+ pin_str = strchr(controller, '@');
+ if (!pin_str)
+@@ -348,7 +356,7 @@ static bool acpi_gpio_in_ignore_list(const char *controller_in, unsigned int pin
+
+ return false;
+ err:
+- pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_wake: %s\n", ignore_wake);
++ pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list);
+ return false;
+ }
+
+@@ -360,7 +368,7 @@ static bool acpi_gpio_irq_is_wake(struct device *parent,
+ if (agpio->wake_capable != ACPI_WAKE_CAPABLE)
+ return false;
+
+- if (acpi_gpio_in_ignore_list(dev_name(parent), pin)) {
++ if (acpi_gpio_in_ignore_list(ignore_wake, dev_name(parent), pin)) {
+ dev_info(parent, "Ignoring wakeup on pin %u\n", pin);
+ return false;
+ }
+@@ -427,6 +435,11 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
+ goto fail_unlock_irq;
+ }
+
++ if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
++ dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
++ return AE_OK;
++ }
++
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (!event)
+ goto fail_unlock_irq;
+@@ -1563,6 +1576,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
+ .ignore_wake = "INT33FF:01@0",
+ },
+ },
++ {
++ /*
++ * Interrupt storm caused from edge triggered floating pin
++ * Found in BIOS UX325UAZ.300
++ * https://bugzilla.kernel.org/show_bug.cgi?id=216208
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"),
++ },
++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
++ .ignore_interrupt = "AMDI0030:00@18",
++ },
++ },
+ {} /* Terminating entry */
+ };
+
+@@ -1585,6 +1612,9 @@ static int __init acpi_gpio_setup_params(void)
+ if (ignore_wake == NULL && quirk && quirk->ignore_wake)
+ ignore_wake = quirk->ignore_wake;
+
++ if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt)
++ ignore_interrupt = quirk->ignore_interrupt;
++
+ return 0;
+ }
+
+diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
+index 66430553cc451..36752cf2cac97 100644
+--- a/drivers/hwmon/aquacomputer_d5next.c
++++ b/drivers/hwmon/aquacomputer_d5next.c
+@@ -110,7 +110,7 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0
+ static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
+
+ /* Fan speed registers in Quadro control report (from 0-100%) */
+-static u16 quadro_ctrl_fan_offsets[] = { 0x36, 0x8b, 0xe0, 0x135 };
++static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 };
+
+ /* Labels for D5 Next */
+ static const char *const label_d5next_temp[] = {
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index cfe804bc8d205..148ea636ef979 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -412,7 +412,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ if (entry->hash != 0xffff) {
+ ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
+ ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
+- MTK_FOE_STATE_UNBIND);
++ MTK_FOE_STATE_INVALID);
+ dma_wmb();
+ }
+ entry->hash = 0xffff;
+diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
+index f48a23adbc35d..094e812e9e692 100644
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -1268,6 +1268,11 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
+ {
+ /* don't do anything here: "fault" will set up page table entries */
+ vma->vm_ops = &mon_bin_vm_ops;
++
++ if (vma->vm_flags & VM_WRITE)
++ return -EPERM;
++
++ vma->vm_flags &= ~VM_MAYWRITE;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_private_data = filp->private_data;
+ mon_bin_vma_open(vma);
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 52d59be920342..787e63fd7f99b 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1319,8 +1319,7 @@ static u32 get_ftdi_divisor(struct tty_struct *tty,
+ case 38400: div_value = ftdi_sio_b38400; break;
+ case 57600: div_value = ftdi_sio_b57600; break;
+ case 115200: div_value = ftdi_sio_b115200; break;
+- } /* baud */
+- if (div_value == 0) {
++ default:
+ dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n",
+ __func__, baud);
+ div_value = ftdi_sio_b9600;
+diff --git a/fs/coredump.c b/fs/coredump.c
+index 1ab4f5b76a1e7..3538f3a63965d 100644
+--- a/fs/coredump.c
++++ b/fs/coredump.c
+@@ -841,7 +841,7 @@ static int dump_emit_page(struct coredump_params *cprm, struct page *page)
+ };
+ struct iov_iter iter;
+ struct file *file = cprm->file;
+- loff_t pos = file->f_pos;
++ loff_t pos;
+ ssize_t n;
+
+ if (cprm->to_skip) {
+@@ -853,6 +853,7 @@ static int dump_emit_page(struct coredump_params *cprm, struct page *page)
+ return 0;
+ if (dump_interrupted())
+ return 0;
++ pos = file->f_pos;
+ iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE);
+ n = __kernel_write_iter(cprm->file, &iter, &pos);
+ if (n != PAGE_SIZE)
+diff --git a/fs/inode.c b/fs/inode.c
+index ba1de23c13c1e..b608528efd3a4 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -192,8 +192,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ inode->i_wb_frn_history = 0;
+ #endif
+
+- if (security_inode_alloc(inode))
+- goto out;
+ spin_lock_init(&inode->i_lock);
+ lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
+
+@@ -228,11 +226,12 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ inode->i_fsnotify_mask = 0;
+ #endif
+ inode->i_flctx = NULL;
++
++ if (unlikely(security_inode_alloc(inode)))
++ return -ENOMEM;
+ this_cpu_inc(nr_inodes);
+
+ return 0;
+-out:
+- return -ENOMEM;
+ }
+ EXPORT_SYMBOL(inode_init_always);
+
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index 647722e847b41..f787c3f524b03 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -95,7 +95,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
+ struct xdp_umem *umem);
+ int xp_assign_dev(struct xsk_buff_pool *pool, struct net_device *dev,
+ u16 queue_id, u16 flags);
+-int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem,
++int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
+ struct net_device *dev, u16 queue_id);
+ int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs);
+ void xp_destroy(struct xsk_buff_pool *pool);
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 1f961f9982d27..3814b0fd3a2c5 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1627,26 +1627,12 @@ bpf_base_func_proto(enum bpf_func_id func_id)
+ return &bpf_ringbuf_discard_proto;
+ case BPF_FUNC_ringbuf_query:
+ return &bpf_ringbuf_query_proto;
+- case BPF_FUNC_ringbuf_reserve_dynptr:
+- return &bpf_ringbuf_reserve_dynptr_proto;
+- case BPF_FUNC_ringbuf_submit_dynptr:
+- return &bpf_ringbuf_submit_dynptr_proto;
+- case BPF_FUNC_ringbuf_discard_dynptr:
+- return &bpf_ringbuf_discard_dynptr_proto;
+ case BPF_FUNC_for_each_map_elem:
+ return &bpf_for_each_map_elem_proto;
+ case BPF_FUNC_loop:
+ return &bpf_loop_proto;
+ case BPF_FUNC_strncmp:
+ return &bpf_strncmp_proto;
+- case BPF_FUNC_dynptr_from_mem:
+- return &bpf_dynptr_from_mem_proto;
+- case BPF_FUNC_dynptr_read:
+- return &bpf_dynptr_read_proto;
+- case BPF_FUNC_dynptr_write:
+- return &bpf_dynptr_write_proto;
+- case BPF_FUNC_dynptr_data:
+- return &bpf_dynptr_data_proto;
+ default:
+ break;
+ }
+@@ -1675,6 +1661,20 @@ bpf_base_func_proto(enum bpf_func_id func_id)
+ return &bpf_timer_cancel_proto;
+ case BPF_FUNC_kptr_xchg:
+ return &bpf_kptr_xchg_proto;
++ case BPF_FUNC_ringbuf_reserve_dynptr:
++ return &bpf_ringbuf_reserve_dynptr_proto;
++ case BPF_FUNC_ringbuf_submit_dynptr:
++ return &bpf_ringbuf_submit_dynptr_proto;
++ case BPF_FUNC_ringbuf_discard_dynptr:
++ return &bpf_ringbuf_discard_dynptr_proto;
++ case BPF_FUNC_dynptr_from_mem:
++ return &bpf_dynptr_from_mem_proto;
++ case BPF_FUNC_dynptr_read:
++ return &bpf_dynptr_read_proto;
++ case BPF_FUNC_dynptr_write:
++ return &bpf_dynptr_write_proto;
++ case BPF_FUNC_dynptr_data:
++ return &bpf_dynptr_data_proto;
+ default:
+ break;
+ }
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 27760627370db..f798acd43a280 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -598,7 +598,7 @@ void bpf_map_free_kptrs(struct bpf_map *map, void *map_value)
+ if (off_desc->type == BPF_KPTR_UNREF) {
+ u64 *p = (u64 *)btf_id_ptr;
+
+- WRITE_ONCE(p, 0);
++ WRITE_ONCE(*p, 0);
+ continue;
+ }
+ old_ptr = xchg(btf_id_ptr, 0);
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index b3a5a3cc93720..9873d2e679885 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -597,6 +597,15 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
+
+ /* Cancel these to avoid queueing non-chained pending work */
+ hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++ /* Wait for
++ *
++ * if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
++ * queue_delayed_work(&hdev->{cmd,ncmd}_timer)
++ *
++ * inside RCU section to see the flag or complete scheduling.
++ */
++ synchronize_rcu();
++ /* Explicitly cancel works in case scheduled after setting the flag. */
+ cancel_delayed_work(&hdev->cmd_timer);
+ cancel_delayed_work(&hdev->ncmd_timer);
+
+@@ -4056,12 +4065,14 @@ static void hci_cmd_work(struct work_struct *work)
+ if (res < 0)
+ __hci_cmd_sync_cancel(hdev, -res);
+
++ rcu_read_lock();
+ if (test_bit(HCI_RESET, &hdev->flags) ||
+ hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+ cancel_delayed_work(&hdev->cmd_timer);
+ else
+- schedule_delayed_work(&hdev->cmd_timer,
+- HCI_CMD_TIMEOUT);
++ queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
++ HCI_CMD_TIMEOUT);
++ rcu_read_unlock();
+ } else {
+ skb_queue_head(&hdev->cmd_q, skb);
+ queue_work(hdev->workqueue, &hdev->cmd_work);
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 6643c9c20fa46..d6f0e6ca0e7e0 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3766,16 +3766,18 @@ static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
+ {
+ cancel_delayed_work(&hdev->cmd_timer);
+
++ rcu_read_lock();
+ if (!test_bit(HCI_RESET, &hdev->flags)) {
+ if (ncmd) {
+ cancel_delayed_work(&hdev->ncmd_timer);
+ atomic_set(&hdev->cmd_cnt, 1);
+ } else {
+ if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+- schedule_delayed_work(&hdev->ncmd_timer,
+- HCI_NCMD_TIMEOUT);
++ queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
++ HCI_NCMD_TIMEOUT);
+ }
+ }
++ rcu_read_unlock();
+ }
+
+ static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 5b4ce6ba1bc7f..7bada4e8460ba 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -954,8 +954,8 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+ goto out_unlock;
+ }
+
+- err = xp_assign_dev_shared(xs->pool, umem_xs->umem,
+- dev, qid);
++ err = xp_assign_dev_shared(xs->pool, umem_xs, dev,
++ qid);
+ if (err) {
+ xp_destroy(xs->pool);
+ xs->pool = NULL;
+diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
+index a71a8c6edf553..ed6c71826d31f 100644
+--- a/net/xdp/xsk_buff_pool.c
++++ b/net/xdp/xsk_buff_pool.c
+@@ -212,17 +212,18 @@ err_unreg_pool:
+ return err;
+ }
+
+-int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem,
++int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
+ struct net_device *dev, u16 queue_id)
+ {
+ u16 flags;
++ struct xdp_umem *umem = umem_xs->umem;
+
+ /* One fill and completion ring required for each queue id. */
+ if (!pool->fq || !pool->cq)
+ return -EINVAL;
+
+ flags = umem->zc ? XDP_ZEROCOPY : XDP_COPY;
+- if (pool->uses_need_wakeup)
++ if (umem_xs->pool->uses_need_wakeup)
+ flags |= XDP_USE_NEED_WAKEUP;
+
+ return xp_assign_dev(pool, dev, queue_id, flags);
+diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
+index 6ae482158bc41..52bd7df84fd64 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -64,6 +64,7 @@ KBUILD_CFLAGS += -Wno-sign-compare
+ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
+ KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
+ KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
++KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
+ endif
+
+ endif
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index bd2aabb2c60f9..995bc42003e6c 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -22,11 +22,17 @@ menu "Memory initialization"
+ config CC_HAS_AUTO_VAR_INIT_PATTERN
+ def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
+
+-config CC_HAS_AUTO_VAR_INIT_ZERO
+- # GCC ignores the -enable flag, so we can test for the feature with
+- # a single invocation using the flag, but drop it as appropriate in
+- # the Makefile, depending on the presence of Clang.
++config CC_HAS_AUTO_VAR_INIT_ZERO_BARE
++ def_bool $(cc-option,-ftrivial-auto-var-init=zero)
++
++config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
++ # Clang 16 and later warn about using the -enable flag, but it
++ # is required before then.
+ def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang)
++ depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE
++
++config CC_HAS_AUTO_VAR_INIT_ZERO
++ def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
+
+ choice
+ prompt "Initialize kernel stack variables at function entry"
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-15 10:03 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-15 10:03 UTC (permalink / raw
To: gentoo-commits
commit: 58312dccbb21fc15f32fa785cf6cf9ac33621b65
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 15 10:03:13 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct 15 10:03:13 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=58312dcc
Linux patch 6.0.2
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1001_linux-6.0.2.patch | 1404 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1408 insertions(+)
diff --git a/0000_README b/0000_README
index d41088d3..5fd3d6cf 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch: 1000_linux-6.0.1.patch
From: http://www.kernel.org
Desc: Linux 6.0.1
+Patch: 1001_linux-6.0.2.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.2
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1001_linux-6.0.2.patch b/1001_linux-6.0.2.patch
new file mode 100644
index 00000000..7b3df1df
--- /dev/null
+++ b/1001_linux-6.0.2.patch
@@ -0,0 +1,1404 @@
+diff --git a/Makefile b/Makefile
+index 3193969f1eb37..aa449693ad09d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
+index 4d7aaab827023..3537b0500f4d0 100644
+--- a/arch/powerpc/include/asm/paca.h
++++ b/arch/powerpc/include/asm/paca.h
+@@ -263,7 +263,6 @@ struct paca_struct {
+ u64 l1d_flush_size;
+ #endif
+ #ifdef CONFIG_PPC_PSERIES
+- struct rtas_args *rtas_args_reentrant;
+ u8 *mce_data_buf; /* buffer to hold per cpu rtas errlog */
+ #endif /* CONFIG_PPC_PSERIES */
+
+diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
+index 00531af17ce05..56319aea646e6 100644
+--- a/arch/powerpc/include/asm/rtas.h
++++ b/arch/powerpc/include/asm/rtas.h
+@@ -240,7 +240,6 @@ extern struct rtas_t rtas;
+ extern int rtas_token(const char *service);
+ extern int rtas_service_present(const char *service);
+ extern int rtas_call(int token, int, int, int *, ...);
+-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...);
+ void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
+ int nret, ...);
+ extern void __noreturn rtas_restart(char *cmd);
+diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
+index ba593fd601245..dfd097b79160a 100644
+--- a/arch/powerpc/kernel/paca.c
++++ b/arch/powerpc/kernel/paca.c
+@@ -16,7 +16,6 @@
+ #include <asm/kexec.h>
+ #include <asm/svm.h>
+ #include <asm/ultravisor.h>
+-#include <asm/rtas.h>
+
+ #include "setup.h"
+
+@@ -170,30 +169,6 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
+ }
+ #endif /* CONFIG_PPC_64S_HASH_MMU */
+
+-#ifdef CONFIG_PPC_PSERIES
+-/**
+- * new_rtas_args() - Allocates rtas args
+- * @cpu: CPU number
+- * @limit: Memory limit for this allocation
+- *
+- * Allocates a struct rtas_args and return it's pointer,
+- * if not in Hypervisor mode
+- *
+- * Return: Pointer to allocated rtas_args
+- * NULL if CPU in Hypervisor Mode
+- */
+-static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
+-{
+- limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX);
+-
+- if (early_cpu_has_feature(CPU_FTR_HVMODE))
+- return NULL;
+-
+- return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES,
+- limit, cpu);
+-}
+-#endif /* CONFIG_PPC_PSERIES */
+-
+ /* The Paca is an array with one entry per processor. Each contains an
+ * lppaca, which contains the information shared between the
+ * hypervisor and Linux.
+@@ -232,10 +207,6 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
+ /* For now -- if we have threads this will be adjusted later */
+ new_paca->tcd_ptr = &new_paca->tcd;
+ #endif
+-
+-#ifdef CONFIG_PPC_PSERIES
+- new_paca->rtas_args_reentrant = NULL;
+-#endif
+ }
+
+ /* Put the paca pointer into r13 and SPRG_PACA */
+@@ -307,9 +278,6 @@ void __init allocate_paca(int cpu)
+ #endif
+ #ifdef CONFIG_PPC_64S_HASH_MMU
+ paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
+-#endif
+-#ifdef CONFIG_PPC_PSERIES
+- paca->rtas_args_reentrant = new_rtas_args(cpu, limit);
+ #endif
+ paca_struct_size += sizeof(struct paca_struct);
+ }
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 6931339722948..0b8a858aa8479 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -43,7 +43,6 @@
+ #include <asm/time.h>
+ #include <asm/mmu.h>
+ #include <asm/topology.h>
+-#include <asm/paca.h>
+
+ /* This is here deliberately so it's only used in this file */
+ void enter_rtas(unsigned long);
+@@ -932,59 +931,6 @@ void rtas_activate_firmware(void)
+ pr_err("ibm,activate-firmware failed (%i)\n", fwrc);
+ }
+
+-#ifdef CONFIG_PPC_PSERIES
+-/**
+- * rtas_call_reentrant() - Used for reentrant rtas calls
+- * @token: Token for desired reentrant RTAS call
+- * @nargs: Number of Input Parameters
+- * @nret: Number of Output Parameters
+- * @outputs: Array of outputs
+- * @...: Inputs for desired RTAS call
+- *
+- * According to LoPAR documentation, only "ibm,int-on", "ibm,int-off",
+- * "ibm,get-xive" and "ibm,set-xive" are currently reentrant.
+- * Reentrant calls need their own rtas_args buffer, so not using rtas.args, but
+- * PACA one instead.
+- *
+- * Return: -1 on error,
+- * First output value of RTAS call if (nret > 0),
+- * 0 otherwise,
+- */
+-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...)
+-{
+- va_list list;
+- struct rtas_args *args;
+- unsigned long flags;
+- int i, ret = 0;
+-
+- if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
+- return -1;
+-
+- local_irq_save(flags);
+- preempt_disable();
+-
+- /* We use the per-cpu (PACA) rtas args buffer */
+- args = local_paca->rtas_args_reentrant;
+-
+- va_start(list, outputs);
+- va_rtas_call_unlocked(args, token, nargs, nret, list);
+- va_end(list);
+-
+- if (nret > 1 && outputs)
+- for (i = 0; i < nret - 1; ++i)
+- outputs[i] = be32_to_cpu(args->rets[i + 1]);
+-
+- if (nret > 0)
+- ret = be32_to_cpu(args->rets[0]);
+-
+- local_irq_restore(flags);
+- preempt_enable();
+-
+- return ret;
+-}
+-
+-#endif /* CONFIG_PPC_PSERIES */
+-
+ /**
+ * get_pseries_errorlog() - Find a specific pseries error log in an RTAS
+ * extended event log.
+diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
+index 9e7007f9aca5c..f8320f8e5bc79 100644
+--- a/arch/powerpc/sysdev/xics/ics-rtas.c
++++ b/arch/powerpc/sysdev/xics/ics-rtas.c
+@@ -36,8 +36,8 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
+
+ server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
+
+- call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+- server, DEFAULT_PRIORITY);
++ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
++ DEFAULT_PRIORITY);
+ if (call_status != 0) {
+ printk(KERN_ERR
+ "%s: ibm_set_xive irq %u server %x returned %d\n",
+@@ -46,7 +46,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
+ }
+
+ /* Now unmask the interrupt (often a no-op) */
+- call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
++ call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq);
+ if (call_status != 0) {
+ printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
+ __func__, hw_irq, call_status);
+@@ -68,7 +68,7 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
+ if (hw_irq == XICS_IPI)
+ return;
+
+- call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
++ call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq);
+ if (call_status != 0) {
+ printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
+ __func__, hw_irq, call_status);
+@@ -76,8 +76,8 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
+ }
+
+ /* Have to set XIVE to 0xff to be able to remove a slot */
+- call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+- xics_default_server, 0xff);
++ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq,
++ xics_default_server, 0xff);
+ if (call_status != 0) {
+ printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
+ __func__, hw_irq, call_status);
+@@ -108,7 +108,7 @@ static int ics_rtas_set_affinity(struct irq_data *d,
+ if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+ return -1;
+
+- status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);
++ status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq);
+
+ if (status) {
+ printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
+@@ -126,8 +126,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
+ pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq,
+ hw_irq, irq_server);
+
+- status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
+- hw_irq, irq_server, xics_status[1]);
++ status = rtas_call(ibm_set_xive, 3, 1, NULL,
++ hw_irq, irq_server, xics_status[1]);
+
+ if (status) {
+ printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
+@@ -158,7 +158,7 @@ static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
+ return -EINVAL;
+
+ /* Check if RTAS knows about this interrupt */
+- rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
++ rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq);
+ if (rc)
+ return -ENXIO;
+
+@@ -174,7 +174,7 @@ static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
+ {
+ int rc, status[2];
+
+- rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
++ rc = rtas_call(ibm_get_xive, 1, 3, status, vec);
+ if (rc)
+ return -1;
+ return status[0];
+diff --git a/drivers/char/mem.c b/drivers/char/mem.c
+index 32a932a065a6a..5611d127363e4 100644
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -712,8 +712,8 @@ static const struct memdev {
+ #endif
+ [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
+ [7] = { "full", 0666, &full_fops, 0 },
+- [8] = { "random", 0666, &random_fops, 0 },
+- [9] = { "urandom", 0666, &urandom_fops, 0 },
++ [8] = { "random", 0666, &random_fops, FMODE_NOWAIT },
++ [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT },
+ #ifdef CONFIG_PRINTK
+ [11] = { "kmsg", 0644, &kmsg_fops, 0 },
+ #endif
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 79d7d4e4e5828..060f999dcffb3 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -920,20 +920,23 @@ EXPORT_SYMBOL_GPL(unregister_random_vmfork_notifier);
+ #endif
+
+ struct fast_pool {
+- struct work_struct mix;
+ unsigned long pool[4];
+ unsigned long last;
+ unsigned int count;
++ struct timer_list mix;
+ };
+
++static void mix_interrupt_randomness(struct timer_list *work);
++
+ static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
+ #ifdef CONFIG_64BIT
+ #define FASTMIX_PERM SIPHASH_PERMUTATION
+- .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }
++ .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 },
+ #else
+ #define FASTMIX_PERM HSIPHASH_PERMUTATION
+- .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }
++ .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 },
+ #endif
++ .mix = __TIMER_INITIALIZER(mix_interrupt_randomness, 0)
+ };
+
+ /*
+@@ -975,7 +978,7 @@ int __cold random_online_cpu(unsigned int cpu)
+ }
+ #endif
+
+-static void mix_interrupt_randomness(struct work_struct *work)
++static void mix_interrupt_randomness(struct timer_list *work)
+ {
+ struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
+ /*
+@@ -1006,7 +1009,7 @@ static void mix_interrupt_randomness(struct work_struct *work)
+ local_irq_enable();
+
+ mix_pool_bytes(pool, sizeof(pool));
+- credit_init_bits(max(1u, (count & U16_MAX) / 64));
++ credit_init_bits(clamp_t(unsigned int, (count & U16_MAX) / 64, 1, sizeof(pool) * 8));
+
+ memzero_explicit(pool, sizeof(pool));
+ }
+@@ -1029,10 +1032,11 @@ void add_interrupt_randomness(int irq)
+ if (new_count < 1024 && !time_is_before_jiffies(fast_pool->last + HZ))
+ return;
+
+- if (unlikely(!fast_pool->mix.func))
+- INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
+ fast_pool->count |= MIX_INFLIGHT;
+- queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
++ if (!timer_pending(&fast_pool->mix)) {
++ fast_pool->mix.expires = jiffies;
++ add_timer_on(&fast_pool->mix, raw_smp_processor_id());
++ }
+ }
+ EXPORT_SYMBOL_GPL(add_interrupt_randomness);
+
+@@ -1347,6 +1351,11 @@ static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
+ {
+ int ret;
+
++ if (!crng_ready() &&
++ ((kiocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) ||
++ (kiocb->ki_filp->f_flags & O_NONBLOCK)))
++ return -EAGAIN;
++
+ ret = wait_for_random_bytes();
+ if (ret != 0)
+ return ret;
+diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+index 095ed2a404d2f..85b0f30712e16 100644
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -333,13 +333,13 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ qat_req->out.dh.out_tab[1] = 0;
+ /* Mapping in.in.b or in.in_g2.xa is the same */
+ qat_req->phy_in = dma_map_single(dev, &qat_req->in.dh.in.b,
+- sizeof(qat_req->in.dh.in.b),
++ sizeof(struct qat_dh_input_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ goto unmap_dst;
+
+ qat_req->phy_out = dma_map_single(dev, &qat_req->out.dh.r,
+- sizeof(qat_req->out.dh.r),
++ sizeof(struct qat_dh_output_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ goto unmap_in_params;
+@@ -730,13 +730,13 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ qat_req->in.rsa.in_tab[3] = 0;
+ qat_req->out.rsa.out_tab[1] = 0;
+ qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m,
+- sizeof(qat_req->in.rsa.enc.m),
++ sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ goto unmap_dst;
+
+ qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.enc.c,
+- sizeof(qat_req->out.rsa.enc.c),
++ sizeof(struct qat_rsa_output_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ goto unmap_in_params;
+@@ -876,13 +876,13 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ qat_req->in.rsa.in_tab[3] = 0;
+ qat_req->out.rsa.out_tab[1] = 0;
+ qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.dec.c,
+- sizeof(qat_req->in.rsa.dec.c),
++ sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ goto unmap_dst;
+
+ qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.dec.m,
+- sizeof(qat_req->out.rsa.dec.m),
++ sizeof(struct qat_rsa_output_params),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ goto unmap_in_params;
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 18190b529bca3..3da5fd5b5aaf4 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -113,6 +113,8 @@ static const struct xpad_device {
+ u8 xtype;
+ } xpad_device[] = {
+ { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
++ { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 },
++ { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 },
+ { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
+@@ -244,6 +246,7 @@ static const struct xpad_device {
+ { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
+ { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
++ { 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
+ { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
+ { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
+@@ -260,6 +263,7 @@ static const struct xpad_device {
+ { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
+ { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
++ { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
+@@ -325,6 +329,7 @@ static const struct xpad_device {
+ { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
++ { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
+@@ -334,6 +339,14 @@ static const struct xpad_device {
+ { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
++ { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 },
++ { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
++ { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
++ { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
++ { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
++ { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
++ { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
++ { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
+ { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
+ { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
+ { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
+@@ -419,6 +432,7 @@ static const signed short xpad_abs_triggers[] = {
+ static const struct usb_device_id xpad_table[] = {
+ { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
+ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */
++ XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */
+ XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */
+ XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
+ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */
+@@ -429,6 +443,7 @@ static const struct usb_device_id xpad_table[] = {
+ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
+ XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */
+ XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */
++ XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */
+ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
+ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
+ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
+@@ -450,8 +465,12 @@ static const struct usb_device_id xpad_table[] = {
+ XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */
+ XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
+ XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
++ XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */
++ XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */
++ XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */
+ XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */
+ XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */
++ XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */
+ XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */
+ { }
+ };
+@@ -1972,7 +1991,6 @@ static struct usb_driver xpad_driver = {
+ .disconnect = xpad_disconnect,
+ .suspend = xpad_suspend,
+ .resume = xpad_resume,
+- .reset_resume = xpad_resume,
+ .id_table = xpad_table,
+ };
+
+diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
+index 8f786a225dcf8..11530b4ec3892 100644
+--- a/drivers/misc/pci_endpoint_test.c
++++ b/drivers/misc/pci_endpoint_test.c
+@@ -332,6 +332,22 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
+ return false;
+ }
+
++static int pci_endpoint_test_validate_xfer_params(struct device *dev,
++ struct pci_endpoint_test_xfer_param *param, size_t alignment)
++{
++ if (!param->size) {
++ dev_dbg(dev, "Data size is zero\n");
++ return -EINVAL;
++ }
++
++ if (param->size > SIZE_MAX - alignment) {
++ dev_dbg(dev, "Maximum transfer data size exceeded\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
+ unsigned long arg)
+ {
+@@ -363,9 +379,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
+ return false;
+ }
+
++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
++ if (err)
++ return false;
++
+ size = param.size;
+- if (size > SIZE_MAX - alignment)
+- goto err;
+
+ use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ if (use_dma)
+@@ -497,9 +515,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
+ return false;
+ }
+
++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
++ if (err)
++ return false;
++
+ size = param.size;
+- if (size > SIZE_MAX - alignment)
+- goto err;
+
+ use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ if (use_dma)
+@@ -595,9 +615,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
+ return false;
+ }
+
++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment);
++ if (err)
++ return false;
++
+ size = param.size;
+- if (size > SIZE_MAX - alignment)
+- goto err;
+
+ use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ if (use_dma)
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 1f301a5fb3969..ee34814bd12b5 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -4526,6 +4526,8 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+
+ rx_status.band = channel->band;
+ rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
++ goto out;
+ rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+
+ hdr = (void *)skb->data;
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 67d3335e9cc84..57cc2bb5b1a2b 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2834,6 +2834,8 @@ static void nvme_reset_work(struct work_struct *work)
+ nvme_start_admin_queue(&dev->ctrl);
+ }
+
++ dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1);
++
+ /*
+ * Limit the max command size to prevent iod->sg allocations going
+ * over a single page.
+@@ -2846,7 +2848,6 @@ static void nvme_reset_work(struct work_struct *work)
+ * Don't limit the IOMMU merged segment size.
+ */
+ dma_set_max_seg_size(dev->dev, 0xffffffff);
+- dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1);
+
+ mutex_unlock(&dev->shutdown_lock);
+
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index 5dd2932382ee3..bb69fa8b956a3 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -193,8 +193,6 @@ extern int ql2xsecenable;
+ extern int ql2xenforce_iocb_limit;
+ extern int ql2xabts_wait_nvme;
+ extern u32 ql2xnvme_queues;
+-extern int ql2xrspq_follow_inptr;
+-extern int ql2xrspq_follow_inptr_legacy;
+
+ extern int qla2x00_loop_reset(scsi_qla_host_t *);
+ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 76e79f350a226..e19fde304e5c6 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3764,7 +3764,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ struct purex_entry_24xx *purex_entry;
+ struct purex_item *pure_item;
+ u16 rsp_in = 0, cur_ring_index;
+- int follow_inptr, is_shadow_hba;
++ int is_shadow_hba;
+
+ if (!ha->flags.fw_started)
+ return;
+@@ -3774,25 +3774,18 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ qla_cpu_update(rsp->qpair, smp_processor_id());
+ }
+
+-#define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \
++#define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \
+ do { \
+- if (_update) { \
+- _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \
++ _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \
+ rd_reg_dword_relaxed((_rsp)->rsp_q_in); \
+- } \
+ } while (0)
+
+ is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha);
+- follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr :
+- ql2xrspq_follow_inptr_legacy;
+
+- __update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in);
++ __update_rsp_in(is_shadow_hba, rsp, rsp_in);
+
+- while ((likely(follow_inptr &&
+- rsp->ring_index != rsp_in &&
+- rsp->ring_ptr->signature != RESPONSE_PROCESSED)) ||
+- (!follow_inptr &&
+- rsp->ring_ptr->signature != RESPONSE_PROCESSED)) {
++ while (rsp->ring_index != rsp_in &&
++ rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
+ pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
+ cur_ring_index = rsp->ring_index;
+
+@@ -3906,8 +3899,7 @@ process_err:
+ }
+ pure_item = qla27xx_copy_fpin_pkt(vha,
+ (void **)&pkt, &rsp);
+- __update_rsp_in(follow_inptr, is_shadow_hba,
+- rsp, rsp_in);
++ __update_rsp_in(is_shadow_hba, rsp, rsp_in);
+ if (!pure_item)
+ break;
+ qla24xx_queue_purex_item(vha, pure_item,
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 0bd0fd1042dfe..1c7fb6484db20 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -338,16 +338,6 @@ module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
+ MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling,
+ "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n");
+
+-int ql2xrspq_follow_inptr = 1;
+-module_param(ql2xrspq_follow_inptr, int, 0644);
+-MODULE_PARM_DESC(ql2xrspq_follow_inptr,
+- "Follow RSP IN pointer for RSP updates for HBAs 27xx and newer (default: 1).");
+-
+-int ql2xrspq_follow_inptr_legacy = 1;
+-module_param(ql2xrspq_follow_inptr_legacy, int, 0644);
+-MODULE_PARM_DESC(ql2xrspq_follow_inptr_legacy,
+- "Follow RSP IN pointer for RSP updates for HBAs older than 27XX. (default: 1).");
+-
+ static void qla2x00_clear_drv_active(struct qla_hw_data *);
+ static void qla2x00_free_device(scsi_qla_host_t *);
+ static int qla2xxx_map_queues(struct Scsi_Host *shost);
+diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
+index e6420f2127ce1..8def242675ef3 100644
+--- a/drivers/scsi/stex.c
++++ b/drivers/scsi/stex.c
+@@ -665,16 +665,17 @@ static int stex_queuecommand_lck(struct scsi_cmnd *cmd)
+ return 0;
+ case PASSTHRU_CMD:
+ if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
+- struct st_drvver ver;
++ const struct st_drvver ver = {
++ .major = ST_VER_MAJOR,
++ .minor = ST_VER_MINOR,
++ .oem = ST_OEM,
++ .build = ST_BUILD_VER,
++ .signature[0] = PASSTHRU_SIGNATURE,
++ .console_id = host->max_id - 1,
++ .host_no = hba->host->host_no,
++ };
+ size_t cp_len = sizeof(ver);
+
+- ver.major = ST_VER_MAJOR;
+- ver.minor = ST_VER_MINOR;
+- ver.oem = ST_OEM;
+- ver.build = ST_BUILD_VER;
+- ver.signature[0] = PASSTHRU_SIGNATURE;
+- ver.console_id = host->max_id - 1;
+- ver.host_no = hba->host->host_no;
+ cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len);
+ if (sizeof(ver) == cp_len)
+ cmd->result = DID_OK << 16;
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index d0237b30c9bef..219d797e22301 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -23,7 +23,6 @@
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/of.h>
+-#include <linux/of_graph.h>
+ #include <linux/acpi.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+@@ -86,7 +85,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
+ * mode. If the controller supports DRD but the dr_mode is not
+ * specified or set to OTG, then set the mode to peripheral.
+ */
+- if (mode == USB_DR_MODE_OTG && !dwc->edev &&
++ if (mode == USB_DR_MODE_OTG &&
+ (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
+ !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
+ !DWC3_VER_IS_PRIOR(DWC3, 330A))
+@@ -1668,46 +1667,6 @@ static void dwc3_check_params(struct dwc3 *dwc)
+ }
+ }
+
+-static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+-{
+- struct device *dev = dwc->dev;
+- struct device_node *np_phy;
+- struct extcon_dev *edev = NULL;
+- const char *name;
+-
+- if (device_property_read_bool(dev, "extcon"))
+- return extcon_get_edev_by_phandle(dev, 0);
+-
+- /*
+- * Device tree platforms should get extcon via phandle.
+- * On ACPI platforms, we get the name from a device property.
+- * This device property is for kernel internal use only and
+- * is expected to be set by the glue code.
+- */
+- if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
+- return extcon_get_extcon_dev(name);
+-
+- /*
+- * Try to get an extcon device from the USB PHY controller's "port"
+- * node. Check if it has the "port" node first, to avoid printing the
+- * error message from underlying code, as it's a valid case: extcon
+- * device (and "port" node) may be missing in case of "usb-role-switch"
+- * or OTG mode.
+- */
+- np_phy = of_parse_phandle(dev->of_node, "phys", 0);
+- if (of_graph_is_present(np_phy)) {
+- struct device_node *np_conn;
+-
+- np_conn = of_graph_get_remote_node(np_phy, -1, -1);
+- if (np_conn)
+- edev = extcon_find_edev_by_node(np_conn);
+- of_node_put(np_conn);
+- }
+- of_node_put(np_phy);
+-
+- return edev;
+-}
+-
+ static int dwc3_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1844,13 +1803,6 @@ static int dwc3_probe(struct platform_device *pdev)
+ goto err2;
+ }
+
+- dwc->edev = dwc3_get_extcon(dwc);
+- if (IS_ERR(dwc->edev)) {
+- ret = PTR_ERR(dwc->edev);
+- dev_err_probe(dwc->dev, ret, "failed to get extcon\n");
+- goto err3;
+- }
+-
+ ret = dwc3_get_dr_mode(dwc);
+ if (ret)
+ goto err3;
+diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
+index 039bf241769af..8cad9e7d33687 100644
+--- a/drivers/usb/dwc3/drd.c
++++ b/drivers/usb/dwc3/drd.c
+@@ -8,6 +8,7 @@
+ */
+
+ #include <linux/extcon.h>
++#include <linux/of_graph.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/property.h>
+@@ -438,6 +439,51 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
+ return NOTIFY_DONE;
+ }
+
++static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
++{
++ struct device *dev = dwc->dev;
++ struct device_node *np_phy;
++ struct extcon_dev *edev = NULL;
++ const char *name;
++
++ if (device_property_read_bool(dev, "extcon"))
++ return extcon_get_edev_by_phandle(dev, 0);
++
++ /*
++ * Device tree platforms should get extcon via phandle.
++ * On ACPI platforms, we get the name from a device property.
++ * This device property is for kernel internal use only and
++ * is expected to be set by the glue code.
++ */
++ if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
++ edev = extcon_get_extcon_dev(name);
++ if (!edev)
++ return ERR_PTR(-EPROBE_DEFER);
++
++ return edev;
++ }
++
++ /*
++ * Try to get an extcon device from the USB PHY controller's "port"
++ * node. Check if it has the "port" node first, to avoid printing the
++ * error message from underlying code, as it's a valid case: extcon
++ * device (and "port" node) may be missing in case of "usb-role-switch"
++ * or OTG mode.
++ */
++ np_phy = of_parse_phandle(dev->of_node, "phys", 0);
++ if (of_graph_is_present(np_phy)) {
++ struct device_node *np_conn;
++
++ np_conn = of_graph_get_remote_node(np_phy, -1, -1);
++ if (np_conn)
++ edev = extcon_find_edev_by_node(np_conn);
++ of_node_put(np_conn);
++ }
++ of_node_put(np_phy);
++
++ return edev;
++}
++
+ #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
+ #define ROLE_SWITCH 1
+ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
+@@ -542,6 +588,10 @@ int dwc3_drd_init(struct dwc3 *dwc)
+ device_property_read_bool(dwc->dev, "usb-role-switch"))
+ return dwc3_setup_role_switch(dwc);
+
++ dwc->edev = dwc3_get_extcon(dwc);
++ if (IS_ERR(dwc->edev))
++ return PTR_ERR(dwc->edev);
++
+ if (dwc->edev) {
+ dwc->edev_nb.notifier_call = dwc3_drd_notifier;
+ ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
+diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
+index 586ef5551e76e..b1e844bf31f81 100644
+--- a/drivers/usb/serial/qcserial.c
++++ b/drivers/usb/serial/qcserial.c
+@@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = {
+ {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
+ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
+ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
++ {DEVICE_SWI(0x413c, 0x81c2)}, /* Dell Wireless 5811e */
+ {DEVICE_SWI(0x413c, 0x81cb)}, /* Dell Wireless 5816e QDL */
+ {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */
+ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */
+diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
+index 67f63cfeade5c..232dd7b6cca14 100644
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -328,6 +328,7 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
+ struct inode *inode;
+ struct nilfs_inode_info *ii;
+ struct nilfs_root *root;
++ struct buffer_head *bh;
+ int err = -ENOMEM;
+ ino_t ino;
+
+@@ -343,11 +344,25 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
+ ii->i_state = BIT(NILFS_I_NEW);
+ ii->i_root = root;
+
+- err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh);
++ err = nilfs_ifile_create_inode(root->ifile, &ino, &bh);
+ if (unlikely(err))
+ goto failed_ifile_create_inode;
+ /* reference count of i_bh inherits from nilfs_mdt_read_block() */
+
++ if (unlikely(ino < NILFS_USER_INO)) {
++ nilfs_warn(sb,
++ "inode bitmap is inconsistent for reserved inodes");
++ do {
++ brelse(bh);
++ err = nilfs_ifile_create_inode(root->ifile, &ino, &bh);
++ if (unlikely(err))
++ goto failed_ifile_create_inode;
++ } while (ino < NILFS_USER_INO);
++
++ nilfs_info(sb, "repaired inode bitmap for reserved inodes");
++ }
++ ii->i_bh = bh;
++
+ atomic64_inc(&root->inodes_count);
+ inode_init_owner(&init_user_ns, inode, dir, mode);
+ inode->i_ino = ino;
+@@ -440,6 +455,8 @@ int nilfs_read_inode_common(struct inode *inode,
+ inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+ inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
+ inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
++ if (nilfs_is_metadata_file_inode(inode) && !S_ISREG(inode->i_mode))
++ return -EIO; /* this inode is for metadata and corrupted */
+ if (inode->i_nlink == 0)
+ return -ESTALE; /* this inode is deleted */
+
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 0afe0832c7547..56d2c6fc61753 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -875,9 +875,11 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
+ nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
+ nilfs_cpfile_put_checkpoint(
+ nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
+- } else
+- WARN_ON(err == -EINVAL || err == -ENOENT);
+-
++ } else if (err == -EINVAL || err == -ENOENT) {
++ nilfs_error(sci->sc_super,
++ "checkpoint creation failed due to metadata corruption.");
++ err = -EIO;
++ }
+ return err;
+ }
+
+@@ -891,7 +893,11 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
+ err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0,
+ &raw_cp, &bh_cp);
+ if (unlikely(err)) {
+- WARN_ON(err == -EINVAL || err == -ENOENT);
++ if (err == -EINVAL || err == -ENOENT) {
++ nilfs_error(sci->sc_super,
++ "checkpoint finalization failed due to metadata corruption.");
++ err = -EIO;
++ }
+ goto failed_ibh;
+ }
+ raw_cp->cp_snapshot_list.ssl_next = 0;
+@@ -2786,10 +2792,9 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
+ inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL);
+
+ err = nilfs_segctor_start_thread(nilfs->ns_writer);
+- if (err) {
+- kfree(nilfs->ns_writer);
+- nilfs->ns_writer = NULL;
+- }
++ if (unlikely(err))
++ nilfs_detach_log_writer(sb);
++
+ return err;
+ }
+
+diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
+index bac55decf900a..7d3622db38edc 100644
+--- a/include/scsi/scsi_cmnd.h
++++ b/include/scsi/scsi_cmnd.h
+@@ -201,7 +201,7 @@ static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd)
+ for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
+
+ static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
+- void *buf, int buflen)
++ const void *buf, int buflen)
+ {
+ return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
+ buf, buflen);
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index e192e1ec02610..9583643b70332 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1704,6 +1704,14 @@ struct ieee802_11_elems {
+
+ /* whether a parse error occurred while retrieving these elements */
+ bool parse_error;
++
++ /*
++ * scratch buffer that can be used for various element parsing related
++ * tasks, e.g., element de-fragmentation etc.
++ */
++ size_t scratch_len;
++ u8 *scratch_pos;
++ u8 scratch[];
+ };
+
+ static inline struct ieee80211_local *hw_to_local(
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 45d7e71661e3f..211de01bf6153 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1967,10 +1967,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+
+ if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
+ mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
+- NUM_DEFAULT_BEACON_KEYS) {
+- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+- skb->data,
+- skb->len);
++ NUM_DEFAULT_BEACON_KEYS) {
++ if (rx->sdata->dev)
++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
++ skb->data,
++ skb->len);
+ return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+ }
+
+@@ -2121,7 +2122,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+ /* either the frame has been decrypted or will be dropped */
+ status->flag |= RX_FLAG_DECRYPTED;
+
+- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE))
++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE &&
++ rx->sdata->dev))
+ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+ skb->data, skb->len);
+
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index efcefb2dd8826..4fc3d545e6667 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1442,6 +1442,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
+ if (elem->datalen < 2)
+ continue;
++ if (elem->data[0] < 1 || elem->data[0] > 8)
++ continue;
+
+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 new_bssid[ETH_ALEN];
+@@ -1501,24 +1503,26 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
+ const struct element *non_inherit = NULL;
+ u8 *nontransmitted_profile;
+ int nontransmitted_profile_len = 0;
++ size_t scratch_len = params->len;
+
+- elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
++ elems = kzalloc(sizeof(*elems) + scratch_len, GFP_ATOMIC);
+ if (!elems)
+ return NULL;
+ elems->ie_start = params->start;
+ elems->total_len = params->len;
+-
+- nontransmitted_profile = kmalloc(params->len, GFP_ATOMIC);
+- if (nontransmitted_profile) {
+- nontransmitted_profile_len =
+- ieee802_11_find_bssid_profile(params->start, params->len,
+- elems, params->bss,
+- nontransmitted_profile);
+- non_inherit =
+- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+- nontransmitted_profile,
+- nontransmitted_profile_len);
+- }
++ elems->scratch_len = scratch_len;
++ elems->scratch_pos = elems->scratch;
++
++ nontransmitted_profile = elems->scratch_pos;
++ nontransmitted_profile_len =
++ ieee802_11_find_bssid_profile(params->start, params->len,
++ elems, params->bss,
++ nontransmitted_profile);
++ elems->scratch_pos += nontransmitted_profile_len;
++ elems->scratch_len -= nontransmitted_profile_len;
++ non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
++ nontransmitted_profile,
++ nontransmitted_profile_len);
+
+ elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit);
+
+@@ -1552,8 +1556,6 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
+ offsetofend(struct ieee80211_bssid_index, dtim_count))
+ elems->dtim_count = elems->bssid_index->dtim_count;
+
+- kfree(nontransmitted_profile);
+-
+ return elems;
+ }
+
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index c2fc2a7b25285..b6b5e496fa403 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -295,11 +295,12 @@ __must_hold(&net->mctp.keys_lock)
+ mctp_dev_release_key(key->dev, key);
+ spin_unlock_irqrestore(&key->lock, flags);
+
+- hlist_del(&key->hlist);
+- hlist_del(&key->sklist);
+-
+- /* unref for the lists */
+- mctp_key_unref(key);
++ if (!hlist_unhashed(&key->hlist)) {
++ hlist_del_init(&key->hlist);
++ hlist_del_init(&key->sklist);
++ /* unref for the lists */
++ mctp_key_unref(key);
++ }
+
+ kfree_skb(skb);
+ }
+@@ -373,9 +374,17 @@ static int mctp_ioctl_alloctag(struct mctp_sock *msk, unsigned long arg)
+
+ ctl.tag = tag | MCTP_TAG_OWNER | MCTP_TAG_PREALLOC;
+ if (copy_to_user((void __user *)arg, &ctl, sizeof(ctl))) {
+- spin_lock_irqsave(&key->lock, flags);
+- __mctp_key_remove(key, net, flags, MCTP_TRACE_KEY_DROPPED);
++ unsigned long fl2;
++ /* Unwind our key allocation: the keys list lock needs to be
++ * taken before the individual key locks, and we need a valid
++ * flags value (fl2) to pass to __mctp_key_remove, hence the
++ * second spin_lock_irqsave() rather than a plain spin_lock().
++ */
++ spin_lock_irqsave(&net->mctp.keys_lock, flags);
++ spin_lock_irqsave(&key->lock, fl2);
++ __mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_DROPPED);
+ mctp_key_unref(key);
++ spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
+ return -EFAULT;
+ }
+
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 3b24b8d18b5b5..2155f15a074cd 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -228,12 +228,12 @@ __releases(&key->lock)
+
+ if (!key->manual_alloc) {
+ spin_lock_irqsave(&net->mctp.keys_lock, flags);
+- hlist_del(&key->hlist);
+- hlist_del(&key->sklist);
++ if (!hlist_unhashed(&key->hlist)) {
++ hlist_del_init(&key->hlist);
++ hlist_del_init(&key->sklist);
++ mctp_key_unref(key);
++ }
+ spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
+-
+- /* unref for the lists */
+- mctp_key_unref(key);
+ }
+
+ /* and one for the local reference */
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 0134e5d5c81a4..39fb9cc25cdca 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
+ lockdep_assert_held(&rdev->bss_lock);
+
+ bss->refcount++;
+- if (bss->pub.hidden_beacon_bss) {
+- bss = container_of(bss->pub.hidden_beacon_bss,
+- struct cfg80211_internal_bss,
+- pub);
+- bss->refcount++;
+- }
+- if (bss->pub.transmitted_bss) {
+- bss = container_of(bss->pub.transmitted_bss,
+- struct cfg80211_internal_bss,
+- pub);
+- bss->refcount++;
+- }
++
++ if (bss->pub.hidden_beacon_bss)
++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
++
++ if (bss->pub.transmitted_bss)
++ bss_from_pub(bss->pub.transmitted_bss)->refcount++;
+ }
+
+ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
+@@ -304,7 +298,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+ tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+
+- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
++ while (tmp_old + 2 - ie <= ielen &&
++ tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+ if (tmp_old[0] == 0) {
+ tmp_old++;
+ continue;
+@@ -364,7 +359,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ * copied to new ie, skip ssid, capability, bssid-index ie
+ */
+ tmp_new = sub_copy;
+- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
++ while (tmp_new + 2 - sub_copy <= subie_len &&
++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
+ if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
+ tmp_new[0] == WLAN_EID_SSID)) {
+ memcpy(pos, tmp_new, tmp_new[1] + 2);
+@@ -427,6 +423,15 @@ cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
+
+ rcu_read_unlock();
+
++ /*
++ * This is a bit weird - it's not on the list, but already on another
++ * one! The only way that could happen is if there's some BSSID/SSID
++ * shared by multiple APs in their multi-BSSID profiles, potentially
++ * with hidden SSID mixed in ... ignore it.
++ */
++ if (!list_empty(&nontrans_bss->nontrans_list))
++ return -EINVAL;
++
+ /* add to the list */
+ list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
+ return 0;
+@@ -1602,6 +1607,23 @@ struct cfg80211_non_tx_bss {
+ u8 bssid_index;
+ };
+
++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
++ const struct cfg80211_bss_ies *new_ies,
++ const struct cfg80211_bss_ies *old_ies)
++{
++ struct cfg80211_internal_bss *bss;
++
++ /* Assign beacon IEs to all sub entries */
++ list_for_each_entry(bss, &known->hidden_list, hidden_list) {
++ const struct cfg80211_bss_ies *ies;
++
++ ies = rcu_access_pointer(bss->pub.beacon_ies);
++ WARN_ON(ies != old_ies);
++
++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
++ }
++}
++
+ static bool
+ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ struct cfg80211_internal_bss *known,
+@@ -1625,7 +1647,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+ } else if (rcu_access_pointer(new->pub.beacon_ies)) {
+ const struct cfg80211_bss_ies *old;
+- struct cfg80211_internal_bss *bss;
+
+ if (known->pub.hidden_beacon_bss &&
+ !list_empty(&known->hidden_list)) {
+@@ -1653,16 +1674,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ if (old == rcu_access_pointer(known->pub.ies))
+ rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+
+- /* Assign beacon IEs to all sub entries */
+- list_for_each_entry(bss, &known->hidden_list, hidden_list) {
+- const struct cfg80211_bss_ies *ies;
+-
+- ies = rcu_access_pointer(bss->pub.beacon_ies);
+- WARN_ON(ies != old);
+-
+- rcu_assign_pointer(bss->pub.beacon_ies,
+- new->pub.beacon_ies);
+- }
++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
+
+ if (old)
+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+@@ -1739,6 +1751,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
+ new->refcount = 1;
+ INIT_LIST_HEAD(&new->hidden_list);
+ INIT_LIST_HEAD(&new->pub.nontrans_list);
++ /* we'll set this later if it was non-NULL */
++ new->pub.transmitted_bss = NULL;
+
+ if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
+ hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
+@@ -2021,10 +2035,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
+ spin_lock_bh(&rdev->bss_lock);
+ if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
+ &res->pub)) {
+- if (__cfg80211_unlink_bss(rdev, res))
++ if (__cfg80211_unlink_bss(rdev, res)) {
+ rdev->bss_generation++;
++ res = NULL;
++ }
+ }
+ spin_unlock_bh(&rdev->bss_lock);
++
++ if (!res)
++ return NULL;
+ }
+
+ trace_cfg80211_return_bss(&res->pub);
+@@ -2143,6 +2162,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
+ if (elem->datalen < 4)
+ continue;
++ if (elem->data[0] < 1 || (int)elem->data[0] > 8)
++ continue;
+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 profile_len;
+
+@@ -2279,7 +2300,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
+ size_t new_ie_len;
+ struct cfg80211_bss_ies *new_ies;
+ const struct cfg80211_bss_ies *old;
+- u8 cpy_len;
++ size_t cpy_len;
+
+ lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
+
+@@ -2346,6 +2367,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
+ } else {
+ old = rcu_access_pointer(nontrans_bss->beacon_ies);
+ rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
++ new_ies, old);
+ rcu_assign_pointer(nontrans_bss->ies, new_ies);
+ if (old)
+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
+index 093894a640dca..b78753d27d8ea 100644
+--- a/security/integrity/platform_certs/load_uefi.c
++++ b/security/integrity/platform_certs/load_uefi.c
+@@ -31,7 +31,7 @@ static const struct dmi_system_id uefi_skip_cert[] = {
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") },
+- { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") },
++ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "Macmini8,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 6f30c374f896e..1631e1de84046 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2554,7 +2554,8 @@ static const struct pci_device_id azx_ids[] = {
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
+ /* Poulsbo */
+ { PCI_DEVICE(0x8086, 0x811b),
+- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
++ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE |
++ AZX_DCAPS_POSFIX_LPIB },
+ /* Oaktrail */
+ { PCI_DEVICE(0x8086, 0x080a),
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f9d46ae4c7b71..3dc19174670eb 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6741,6 +6741,11 @@ static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixu
+ cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2);
+ }
+
++static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
++{
++ cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2);
++}
++
+ static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+ cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
+@@ -7132,6 +7137,8 @@ enum {
+ ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ ALC245_FIXUP_CS35L41_SPI_2,
+ ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
++ ALC245_FIXUP_CS35L41_SPI1_2,
++ ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED,
+ ALC245_FIXUP_CS35L41_SPI_4,
+ ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
+ ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+@@ -8979,6 +8986,16 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC285_FIXUP_HP_GPIO_LED,
+ },
++ [ALC245_FIXUP_CS35L41_SPI1_2] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = cs35l41_fixup_spi1_two,
++ },
++ [ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = cs35l41_fixup_spi1_two,
++ .chained = true,
++ .chain_id = ALC285_FIXUP_HP_GPIO_LED,
++ },
+ [ALC245_FIXUP_CS35L41_SPI_4] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_spi_four,
+@@ -9341,6 +9358,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-21 13:14 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-21 13:14 UTC (permalink / raw
To: gentoo-commits
commit: c9bd447eacb73b2cbe152115f2b1795409415cb8
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 21 13:13:33 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Oct 21 13:13:33 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c9bd447e
Linux patch 6.0.3
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1002_linux-6.0.3.patch | 32375 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 32379 insertions(+)
diff --git a/0000_README b/0000_README
index 5fd3d6cf..e5b9be05 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch: 1001_linux-6.0.2.patch
From: http://www.kernel.org
Desc: Linux 6.0.2
+Patch: 1002_linux-6.0.3.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.3
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1002_linux-6.0.3.patch b/1002_linux-6.0.3.patch
new file mode 100644
index 00000000..562d06c9
--- /dev/null
+++ b/1002_linux-6.0.3.patch
@@ -0,0 +1,32375 @@
+diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
+index e81ba6f5e1c87..6e1b925f30bf0 100644
+--- a/Documentation/ABI/testing/sysfs-bus-iio
++++ b/Documentation/ABI/testing/sysfs-bus-iio
+@@ -196,7 +196,7 @@ Description:
+ Raw capacitance measurement from channel Y. Units after
+ application of scale and offset are nanofarads.
+
+-What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw
++What: /sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw
+ KernelVersion: 3.2
+ Contact: linux-iio@vger.kernel.org
+ Description:
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 426fa892d311a..2bc11a61c4d01 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -3805,6 +3805,10 @@
+
+ nox2apic [X86-64,APIC] Do not enable x2APIC mode.
+
++ NOTE: this parameter will be ignored on systems with the
++ LEGACY_XAPIC_DISABLED bit set in the
++ IA32_XAPIC_DISABLE_STATUS MSR.
++
+ nps_mtm_hs_ctr= [KNL,ARC]
+ This parameter sets the maximum duration, in
+ cycles, each HW thread of the CTOP can run
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index fda97b3fcf018..b8ae278a4c873 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -76,6 +76,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A55 | #1530923 | ARM64_ERRATUM_1530923 |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM | Cortex-A55 | #2441007 | ARM64_ERRATUM_2441007 |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A57 | #852523 | N/A |
+diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
+index 6cd6953e175b3..b2ef2449aed99 100644
+--- a/Documentation/filesystems/vfs.rst
++++ b/Documentation/filesystems/vfs.rst
+@@ -274,6 +274,9 @@ or bottom half).
+ This is specifically for the inode itself being marked dirty,
+ not its data. If the update needs to be persisted by fdatasync(),
+ then I_DIRTY_DATASYNC will be set in the flags argument.
++ I_DIRTY_TIME will be set in the flags in case lazytime is enabled
++ and struct inode has times updated since the last ->dirty_inode
++ call.
+
+ ``write_inode``
+ this method is called when the VFS needs to write an inode to
+diff --git a/Documentation/trace/coresight/coresight-cpu-debug.rst b/Documentation/trace/coresight/coresight-cpu-debug.rst
+index 993dd294b81ba..836b35532667c 100644
+--- a/Documentation/trace/coresight/coresight-cpu-debug.rst
++++ b/Documentation/trace/coresight/coresight-cpu-debug.rst
+@@ -117,7 +117,8 @@ divide into below cases:
+ Device Tree Bindings
+ --------------------
+
+-See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
++See Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml for
++details.
+
+
+ How to use the module
+diff --git a/Makefile b/Makefile
+index aa449693ad09d..d4297b3d0735a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 87badeae3181e..11ecf09aadc86 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1671,7 +1671,6 @@ config CMDLINE
+ choice
+ prompt "Kernel command line type" if CMDLINE != ""
+ default CMDLINE_FROM_BOOTLOADER
+- depends on ATAGS
+
+ config CMDLINE_FROM_BOOTLOADER
+ bool "Use bootloader kernel arguments if available"
+diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
+index cb2e069dc73fd..abfed1aa2baa8 100644
+--- a/arch/arm/boot/compressed/misc.c
++++ b/arch/arm/boot/compressed/misc.c
+@@ -23,7 +23,9 @@ unsigned int __machine_arch_type;
+ #include <linux/types.h>
+ #include <linux/linkage.h>
+ #include "misc.h"
++#ifdef CONFIG_ARCH_EP93XX
+ #include "misc-ep93xx.h"
++#endif
+
+ static void putstr(const char *ptr);
+
+diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
+index 1bcb68ac4b011..3fcb3e62dc569 100644
+--- a/arch/arm/boot/compressed/vmlinux.lds.S
++++ b/arch/arm/boot/compressed/vmlinux.lds.S
+@@ -23,6 +23,7 @@ SECTIONS
+ *(.ARM.extab*)
+ *(.note.*)
+ *(.rel.*)
++ *(.printk_index)
+ /*
+ * Discard any r/w data - this produces a link error if we have any,
+ * which is required for PIC decompression. Local data generates
+@@ -57,6 +58,7 @@ SECTIONS
+ *(.rodata)
+ *(.rodata.*)
+ *(.data.rel.ro)
++ *(.data.rel.ro.*)
+ }
+ .piggydata : {
+ *(.piggydata)
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index d1e0db6e57307..a41902e3815cd 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -476,7 +476,7 @@
+ marvell,function = "spi0";
+ };
+
+- spi0cs1_pins: spi0cs1-pins {
++ spi0cs2_pins: spi0cs2-pins {
+ marvell,pins = "mpp26";
+ marvell,function = "spi0";
+ };
+@@ -511,7 +511,7 @@
+ };
+ };
+
+- /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */
++ /* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */
+ };
+
+ &uart0 {
+diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
+index b967397a46c5b..8e1c19a8ad06d 100644
+--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
++++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
+@@ -586,7 +586,7 @@
+ clocks = <&camera 1>;
+ clock-names = "extclk";
+ samsung,camclk-out = <1>;
+- gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>;
++ gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
+
+ port {
+ is_s5k6a3_ep: endpoint {
+diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
+index 6db09dba07ffd..a3905e27b9cd9 100644
+--- a/arch/arm/boot/dts/exynos4412-origen.dts
++++ b/arch/arm/boot/dts/exynos4412-origen.dts
+@@ -95,7 +95,7 @@
+ };
+
+ &ehci {
+- samsung,vbus-gpio = <&gpx3 5 1>;
++ samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
+ phy-names = "hsic0", "hsic1";
+diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
+index e7d9bfbfd0e4d..e7be05f205d32 100644
+--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
++++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
+@@ -90,6 +90,7 @@
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&rgmii_phy>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
+index 8e0ed209ede06..dc919e09a505f 100644
+--- a/arch/arm/boot/dts/imx6dl.dtsi
++++ b/arch/arm/boot/dts/imx6dl.dtsi
+@@ -84,6 +84,9 @@
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
++ ranges = <0 0x00900000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
+index 0b40f52268b3c..75586299d9cab 100644
+--- a/arch/arm/boot/dts/imx6q-arm2.dts
++++ b/arch/arm/boot/dts/imx6q-arm2.dts
+@@ -178,6 +178,7 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts
+index c63f371ede8b9..78d941fef5dfb 100644
+--- a/arch/arm/boot/dts/imx6q-evi.dts
++++ b/arch/arm/boot/dts/imx6q-evi.dts
+@@ -146,6 +146,7 @@
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6q-mccmon6.dts b/arch/arm/boot/dts/imx6q-mccmon6.dts
+index 55692c73943d6..64ab01018b71e 100644
+--- a/arch/arm/boot/dts/imx6q-mccmon6.dts
++++ b/arch/arm/boot/dts/imx6q-mccmon6.dts
+@@ -100,6 +100,7 @@
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
+index 3b77eae40e395..df86049a695b1 100644
+--- a/arch/arm/boot/dts/imx6q.dtsi
++++ b/arch/arm/boot/dts/imx6q.dtsi
+@@ -163,6 +163,9 @@
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x40000>;
++ ranges = <0 0x00900000 0x40000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+index 6b791d515e294..683f6e58ab230 100644
+--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+@@ -263,6 +263,10 @@
+ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ };
+
++&hdmi {
++ ddc-i2c-bus = <&i2c2>;
++};
++
+ &i2c_intern {
+ pmic@8 {
+ compatible = "fsl,pfuze100";
+@@ -387,7 +391,7 @@
+
+ /* HDMI_CTRL */
+ &i2c2 {
+- clock-frequency = <375000>;
++ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+index 0ad4cb4f1e828..a53a5d0766a51 100644
+--- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+@@ -192,6 +192,7 @@
+ phy-mode = "rgmii";
+ phy-handle = <ðphy>;
+ phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+index beaa2dcd436ce..57c21a01f126d 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+@@ -334,6 +334,7 @@
+ phy-mode = "rgmii";
+ phy-handle = <ðphy>;
+ phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
+index ee7e2371f94bd..000e9dc97b1ac 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
+@@ -263,6 +263,7 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+index 904d5d051d63c..731759bdd7f57 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+@@ -267,6 +267,7 @@
+ phy-mode = "rgmii";
+ phy-handle = <ðphy>;
+ phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+index 1368a47620372..3dbb460ef102e 100644
+--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+@@ -295,6 +295,7 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii-id";
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
+index 7dc3f0005b0f0..0a36e1bce375d 100644
+--- a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
+@@ -7,6 +7,7 @@
+ #include <dt-bindings/gpio/gpio.h>
+
+ &fec {
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
+index d6ba4b2a60f6f..c096d25a6f5b5 100644
+--- a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
+@@ -192,6 +192,7 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
++ /delete-property/ interrupts;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
+index 0503655138363..fc164991d2ae8 100644
+--- a/arch/arm/boot/dts/imx6qp.dtsi
++++ b/arch/arm/boot/dts/imx6qp.dtsi
+@@ -9,12 +9,18 @@
+ ocram2: sram@940000 {
+ compatible = "mmio-sram";
+ reg = <0x00940000 0x20000>;
++ ranges = <0 0x00940000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+ ocram3: sram@960000 {
+ compatible = "mmio-sram";
+ reg = <0x00960000 0x20000>;
++ ranges = <0 0x00960000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
+index 06a515121dfc5..01122ddfdc0d3 100644
+--- a/arch/arm/boot/dts/imx6sl.dtsi
++++ b/arch/arm/boot/dts/imx6sl.dtsi
+@@ -61,10 +61,10 @@
+ <792000 1175000>,
+ <396000 975000>;
+ fsl,soc-operating-points =
+- /* ARM kHz SOC-PU uV */
+- <996000 1225000>,
+- <792000 1175000>,
+- <396000 1175000>;
++ /* ARM kHz SOC-PU uV */
++ <996000 1225000>,
++ <792000 1175000>,
++ <396000 1175000>;
+ clock-latency = <61036>; /* two CLK32 periods */
+ #cooling-cells = <2>;
+ clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
+@@ -115,6 +115,9 @@
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
++ ranges = <0 0x00900000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6SL_CLK_OCRAM>;
+ };
+
+@@ -222,7 +225,7 @@
+
+ uart5: serial@2018000 {
+ compatible = "fsl,imx6sl-uart",
+- "fsl,imx6q-uart", "fsl,imx21-uart";
++ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02018000 0x4000>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+@@ -235,7 +238,7 @@
+
+ uart1: serial@2020000 {
+ compatible = "fsl,imx6sl-uart",
+- "fsl,imx6q-uart", "fsl,imx21-uart";
++ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+@@ -248,7 +251,7 @@
+
+ uart2: serial@2024000 {
+ compatible = "fsl,imx6sl-uart",
+- "fsl,imx6q-uart", "fsl,imx21-uart";
++ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02024000 0x4000>;
+ interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+@@ -309,7 +312,7 @@
+
+ uart3: serial@2034000 {
+ compatible = "fsl,imx6sl-uart",
+- "fsl,imx6q-uart", "fsl,imx21-uart";
++ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02034000 0x4000>;
+ interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+@@ -322,7 +325,7 @@
+
+ uart4: serial@2038000 {
+ compatible = "fsl,imx6sl-uart",
+- "fsl,imx6q-uart", "fsl,imx21-uart";
++ "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02038000 0x4000>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SL_CLK_UART>,
+@@ -711,7 +714,7 @@
+ #power-domain-cells = <0>;
+ power-supply = <®_pu>;
+ clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
+- <&clks IMX6SL_CLK_GPU2D_PODF>;
++ <&clks IMX6SL_CLK_GPU2D_PODF>;
+ };
+
+ pd_disp: power-domain@2 {
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index d4a000c3dde70..2873369a57c02 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -115,6 +115,9 @@
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
++ ranges = <0 0x00900000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ };
+
+ intc: interrupt-controller@a01000 {
+diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+index 35861bbea94e6..c84ea1fac5e98 100644
+--- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
++++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+@@ -226,7 +226,7 @@
+ &iomuxc {
+ pinctrl_bt_reg: btreggrp {
+ fsl,pins =
+- <MX6SX_PAD_KEY_ROW2__GPIO2_IO_17 0x15059>;
++ <MX6SX_PAD_KEY_ROW2__GPIO2_IO_17 0x15059>;
+ };
+
+ pinctrl_enet1: enet1grp {
+@@ -306,7 +306,6 @@
+ >;
+ };
+
+-
+ pinctrl_uart1: uart1grp {
+ fsl,pins =
+ <MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1>,
+@@ -347,24 +346,23 @@
+
+ pinctrl_otg1_reg: otg1grp {
+ fsl,pins =
+- <MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0>;
++ <MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0>;
+ };
+
+-
+ pinctrl_otg2_reg: otg2grp {
+ fsl,pins =
+- <MX6SX_PAD_NAND_RE_B__GPIO4_IO_12 0x10b0>;
++ <MX6SX_PAD_NAND_RE_B__GPIO4_IO_12 0x10b0>;
+ };
+
+ pinctrl_usb_otg1: usbotg1grp {
+ fsl,pins =
+- <MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059>,
+- <MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC 0x10b0>;
++ <MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059>,
++ <MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC 0x10b0>;
+ };
+
+ pinctrl_usb_otg2: usbot2ggrp {
+ fsl,pins =
+- <MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC 0x10b0>;
++ <MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC 0x10b0>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
+index 4d075e2bf7496..2611eef3b2a20 100644
+--- a/arch/arm/boot/dts/imx6sx.dtsi
++++ b/arch/arm/boot/dts/imx6sx.dtsi
+@@ -164,12 +164,18 @@
+ ocram_s: sram@8f8000 {
+ compatible = "mmio-sram";
+ reg = <0x008f8000 0x4000>;
++ ranges = <0 0x008f8000 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6SX_CLK_OCRAM_S>;
+ };
+
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
++ ranges = <0 0x00900000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ clocks = <&clks IMX6SX_CLK_OCRAM>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
+index 78f4224a9bf4e..e93b9cd9c27b2 100644
+--- a/arch/arm/boot/dts/imx7d-sdb.dts
++++ b/arch/arm/boot/dts/imx7d-sdb.dts
+@@ -206,12 +206,7 @@
+ interrupt-parent = <&gpio2>;
+ interrupts = <29 0>;
+ pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+- ti,x-min = /bits/ 16 <0>;
+- ti,x-max = /bits/ 16 <0>;
+- ti,y-min = /bits/ 16 <0>;
+- ti,y-max = /bits/ 16 <0>;
+- ti,pressure-max = /bits/ 16 <0>;
+- ti,x-plate-ohms = /bits/ 16 <400>;
++ touchscreen-max-pressure = <255>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+index 7b151acb99846..88b70ba1c8fee 100644
+--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi
++++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+@@ -10,6 +10,11 @@
+
+ ocp@f1000000 {
+ pinctrl: pin-controller@10000 {
++ /* Non-default UART pins */
++ pmx_uart0: pmx-uart0 {
++ marvell,pins = "mpp4", "mpp5";
++ };
++
+ pmx_power_hdd: pmx-power-hdd {
+ marvell,pins = "mpp10";
+ marvell,function = "gpo";
+@@ -213,22 +218,11 @@
+ &mdio {
+ status = "okay";
+
+- ethphy0: ethernet-phy@0 {
+- reg = <0>;
+- };
+-
+ ethphy1: ethernet-phy@8 {
+ reg = <8>;
+ };
+ };
+
+-ð0 {
+- status = "okay";
+- ethernet0-port@0 {
+- phy-handle = <ðphy0>;
+- };
+-};
+-
+ ð1 {
+ status = "okay";
+ ethernet1-port@0 {
+diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
+index 3e78f921b8b2d..39be2d1aa27b8 100644
+--- a/arch/arm/include/asm/stacktrace.h
++++ b/arch/arm/include/asm/stacktrace.h
+@@ -21,6 +21,9 @@ struct stackframe {
+ struct llist_node *kr_cur;
+ struct task_struct *tsk;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++ bool ex_frame;
++#endif
+ };
+
+ static __always_inline
+@@ -34,6 +37,9 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
+ frame->kr_cur = NULL;
+ frame->tsk = current;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++ frame->ex_frame = in_entry_text(frame->pc);
++#endif
+ }
+
+ extern int unwind_frame(struct stackframe *frame);
+diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
+index 8aac1e10b117a..38f1ea9c724d5 100644
+--- a/arch/arm/kernel/return_address.c
++++ b/arch/arm/kernel/return_address.c
+@@ -47,6 +47,7 @@ here:
+ frame.kr_cur = NULL;
+ frame.tsk = current;
+ #endif
++ frame.ex_frame = false;
+
+ walk_stackframe(&frame, save_return_addr, &data);
+
+diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
+index d0fa2037460ac..85443b5d19221 100644
+--- a/arch/arm/kernel/stacktrace.c
++++ b/arch/arm/kernel/stacktrace.c
+@@ -9,6 +9,8 @@
+ #include <asm/stacktrace.h>
+ #include <asm/traps.h>
+
++#include "reboot.h"
++
+ #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+ /*
+ * Unwind the current stack frame and store the new register values in the
+@@ -39,29 +41,74 @@
+ * Note that with framepointer enabled, even the leaf functions have the same
+ * prologue and epilogue, therefore we can ignore the LR value in this case.
+ */
+-int notrace unwind_frame(struct stackframe *frame)
++
++extern unsigned long call_with_stack_end;
++
++static int frame_pointer_check(struct stackframe *frame)
+ {
+ unsigned long high, low;
+ unsigned long fp = frame->fp;
++ unsigned long pc = frame->pc;
++
++ /*
++ * call_with_stack() is the only place we allow SP to jump from one
++ * stack to another, with FP and SP pointing to different stacks,
++ * skipping the FP boundary check at this point.
++ */
++ if (pc >= (unsigned long)&call_with_stack &&
++ pc < (unsigned long)&call_with_stack_end)
++ return 0;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE);
+
+-#ifdef CONFIG_CC_IS_CLANG
+ /* check current frame pointer is within bounds */
++#ifdef CONFIG_CC_IS_CLANG
+ if (fp < low + 4 || fp > high - 4)
+ return -EINVAL;
+-
+- frame->sp = frame->fp;
+- frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
+- frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4));
+ #else
+- /* check current frame pointer is within bounds */
+ if (fp < low + 12 || fp > high - 4)
+ return -EINVAL;
++#endif
++
++ return 0;
++}
++
++int notrace unwind_frame(struct stackframe *frame)
++{
++ unsigned long fp = frame->fp;
++
++ if (frame_pointer_check(frame))
++ return -EINVAL;
++
++ /*
++ * When we unwind through an exception stack, include the saved PC
++ * value into the stack trace.
++ */
++ if (frame->ex_frame) {
++ struct pt_regs *regs = (struct pt_regs *)frame->sp;
++
++ /*
++ * We check that 'regs + sizeof(struct pt_regs)' (that is,
++ * ®s[1]) does not exceed the bottom of the stack to avoid
++ * accessing data outside the task's stack. This may happen
++ * when frame->ex_frame is a false positive.
++ */
++ if ((unsigned long)®s[1] > ALIGN(frame->sp, THREAD_SIZE))
++ return -EINVAL;
++
++ frame->pc = regs->ARM_pc;
++ frame->ex_frame = false;
++ return 0;
++ }
+
+ /* restore the registers from the stack frame */
++#ifdef CONFIG_CC_IS_CLANG
++ frame->sp = frame->fp;
++ frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
++ frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4));
++#else
+ frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 12));
+ frame->sp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 8));
+ frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 4));
+@@ -72,6 +119,9 @@ int notrace unwind_frame(struct stackframe *frame)
+ (void *)frame->fp, &frame->kr_cur);
+ #endif
+
++ if (in_entry_text(frame->pc))
++ frame->ex_frame = true;
++
+ return 0;
+ }
+ #endif
+@@ -102,7 +152,6 @@ static int save_trace(struct stackframe *frame, void *d)
+ {
+ struct stack_trace_data *data = d;
+ struct stack_trace *trace = data->trace;
+- struct pt_regs *regs;
+ unsigned long addr = frame->pc;
+
+ if (data->no_sched_functions && in_sched_functions(addr))
+@@ -113,19 +162,6 @@ static int save_trace(struct stackframe *frame, void *d)
+ }
+
+ trace->entries[trace->nr_entries++] = addr;
+-
+- if (trace->nr_entries >= trace->max_entries)
+- return 1;
+-
+- if (!in_entry_text(frame->pc))
+- return 0;
+-
+- regs = (struct pt_regs *)frame->sp;
+- if ((unsigned long)®s[1] > ALIGN(frame->sp, THREAD_SIZE))
+- return 0;
+-
+- trace->entries[trace->nr_entries++] = regs->ARM_pc;
+-
+ return trace->nr_entries >= trace->max_entries;
+ }
+
+@@ -167,6 +203,9 @@ here:
+ frame.kr_cur = NULL;
+ frame.tsk = tsk;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++ frame.ex_frame = false;
++#endif
+
+ walk_stackframe(&frame, save_trace, &data);
+ }
+@@ -188,6 +227,9 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+ frame.kr_cur = NULL;
+ frame.tsk = current;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++ frame.ex_frame = in_entry_text(frame.pc);
++#endif
+
+ walk_stackframe(&frame, save_trace, &data);
+ }
+diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
+index 0a268a6c513c8..5030d4e8d1267 100644
+--- a/arch/arm/lib/call_with_stack.S
++++ b/arch/arm/lib/call_with_stack.S
+@@ -46,4 +46,6 @@ UNWIND( .setfp fpreg, sp )
+ pop {fpreg, pc}
+ UNWIND( .fnend )
+ #endif
++ .globl call_with_stack_end
++call_with_stack_end:
+ ENDPROC(call_with_stack)
+diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
+index 089c9c644cce2..bfc7476f14114 100644
+--- a/arch/arm/mm/dma-mapping.c
++++ b/arch/arm/mm/dma-mapping.c
+@@ -1769,8 +1769,16 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
+ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *iommu, bool coherent)
+ {
+- dev->archdata.dma_coherent = coherent;
+- dev->dma_coherent = coherent;
++ /*
++ * Due to legacy code that sets the ->dma_coherent flag from a bus
++ * notifier we can't just assign coherent to the ->dma_coherent flag
++ * here, but instead have to make sure we only set but never clear it
++ * for now.
++ */
++ if (coherent) {
++ dev->archdata.dma_coherent = true;
++ dev->dma_coherent = true;
++ }
+
+ /*
+ * Don't override the dma_ops if they have already been set. Ideally
+diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
+index fb688003d156e..712da6a81b23f 100644
+--- a/arch/arm/mm/dump.c
++++ b/arch/arm/mm/dump.c
+@@ -346,7 +346,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+ addr = start + i * PMD_SIZE;
+ domain = get_domain_name(pmd);
+ if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
+- note_page(st, addr, 3, pmd_val(*pmd), domain);
++ note_page(st, addr, 4, pmd_val(*pmd), domain);
+ else
+ walk_pte(st, pmd, addr, domain);
+
+diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c
+index 29caee9c79ce3..46d9f4a622cbc 100644
+--- a/arch/arm/mm/kasan_init.c
++++ b/arch/arm/mm/kasan_init.c
+@@ -268,12 +268,17 @@ void __init kasan_init(void)
+
+ /*
+ * 1. The module global variables are in MODULES_VADDR ~ MODULES_END,
+- * so we need to map this area.
++ * so we need to map this area if CONFIG_KASAN_VMALLOC=n. With
++ * VMALLOC support KASAN will manage this region dynamically,
++ * refer to kasan_populate_vmalloc() and ARM's implementation of
++ * module_alloc().
+ * 2. PKMAP_BASE ~ PKMAP_BASE+PMD_SIZE's shadow and MODULES_VADDR
+ * ~ MODULES_END's shadow is in the same PMD_SIZE, so we can't
+ * use kasan_populate_zero_shadow.
+ */
+- create_mapping((void *)MODULES_VADDR, (void *)(PKMAP_BASE + PMD_SIZE));
++ if (!IS_ENABLED(CONFIG_KASAN_VMALLOC) && IS_ENABLED(CONFIG_MODULES))
++ create_mapping((void *)MODULES_VADDR, (void *)(MODULES_END));
++ create_mapping((void *)PKMAP_BASE, (void *)(PKMAP_BASE + PMD_SIZE));
+
+ /*
+ * KAsan may reuse the contents of kasan_early_shadow_pte directly, so
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index a49f0b9c0f752..463fc2a8448f0 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -300,7 +300,11 @@ static struct mem_type mem_types[] __ro_after_init = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_XN | L_PTE_RDONLY,
+ .prot_l1 = PMD_TYPE_TABLE,
++#ifdef CONFIG_ARM_LPAE
++ .prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2,
++#else
+ .prot_sect = PMD_TYPE_SECT,
++#endif
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_ROM] = {
+diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
+index 4e3f25de13c19..830b0be038c6b 100644
+--- a/arch/arm/plat-orion/Makefile
++++ b/arch/arm/plat-orion/Makefile
+@@ -2,7 +2,7 @@
+ #
+ # Makefile for the linux kernel.
+ #
+-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
++ccflags-y := -I$(srctree)/$(src)/include
+
+ orion-gpio-$(CONFIG_GPIOLIB) += gpio.o
+ obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 1ce7685ad5de1..3795eb5ba1cdd 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -632,6 +632,23 @@ config ARM64_ERRATUM_1530923
+ config ARM64_WORKAROUND_REPEAT_TLBI
+ bool
+
++config ARM64_ERRATUM_2441007
++ bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
++ default y
++ select ARM64_WORKAROUND_REPEAT_TLBI
++ help
++ This option adds a workaround for ARM Cortex-A55 erratum #2441007.
++
++ Under very rare circumstances, affected Cortex-A55 CPUs
++ may not handle a race between a break-before-make sequence on one
++ CPU, and another CPU accessing the same page. This could allow a
++ store to a page that has been unmapped.
++
++ Work around this by adding the affected CPUs to the list that needs
++ TLB sequences to be done twice.
++
++ If unsure, say Y.
++
+ config ARM64_ERRATUM_1286807
+ bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
+ default y
+diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+index 91c9bd1b47ddf..bde6a6bb8dfcf 100644
+--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
++++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+@@ -795,7 +795,7 @@
+ reg = <0x27>;
+ interrupt-parent = <&gpa1>;
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+- en-gpios = <&gpf1 4 GPIO_ACTIVE_HIGH>;
++ en-gpios = <&gpf1 4 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&gpj0 2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
+index 23be1ec538ba6..c54536c0a2ba1 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
+@@ -321,6 +321,7 @@
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+@@ -333,6 +334,7 @@
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+@@ -345,6 +347,7 @@
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+index 8f90eb02550d8..6307af803429e 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+@@ -86,7 +86,6 @@
+ pinctrl-0 = <&pinctrl_pmic>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+
+ regulators {
+ reg_vdd_soc: BUCK1 {
+@@ -229,7 +228,6 @@
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x141
+- MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x141
+ >;
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index fe178b7d063cb..522ab47426c35 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -1189,7 +1189,7 @@
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb3_phy0>, <&usb3_phy0>;
+ phy-names = "usb2-phy", "usb3-phy";
+- snps,dis-u2-freeclk-exists-quirk;
++ snps,gfladj-refclk-lpm-sel-quirk;
+ };
+
+ };
+@@ -1231,7 +1231,7 @@
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb3_phy1>, <&usb3_phy1>;
+ phy-names = "usb2-phy", "usb3-phy";
+- snps,dis-u2-freeclk-exists-quirk;
++ snps,gfladj-refclk-lpm-sel-quirk;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+index 9eec8a7eecfc8..127fc7f904c87 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -1077,6 +1077,7 @@
+ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gauge>;
++ power-supplies = <&bq25895>;
+ maxim,over-heat-temp = <700>;
+ maxim,over-volt = <4500>;
+ maxim,rsns-microohm = <5000>;
+diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+index 80b44c7df56aa..881bf948d1dff 100644
+--- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+@@ -117,8 +117,8 @@
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-1 = <&i2c0_gpio>;
+- scl_gpio = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+- sda_gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>;
++ scl-gpios = <&gpio0 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&gpio0 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+ };
+
+@@ -136,8 +136,8 @@
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-1 = <&i2c1_gpio>;
+- scl_gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+- sda_gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
++ scl-gpios = <&gpio0 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index d53675fc15959..b9bf43215ada9 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -199,7 +199,7 @@
+
+ pcie_qmp0: phy@86000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+- reg = <0x00086000 0x1000>;
++ reg = <0x00086000 0x1c4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+@@ -227,7 +227,7 @@
+
+ pcie_qmp1: phy@8e000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+- reg = <0x0008e000 0x1000>;
++ reg = <0x0008e000 0x1c4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+index e0bbb67717fec..f28e71487d5c7 100644
+--- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+@@ -30,9 +30,8 @@
+ #interrupt-cells = <2>;
+ };
+
+- pm8350c_pwm: pwm@e800 {
++ pm8350c_pwm: pwm {
+ compatible = "qcom,pm8350c-pwm";
+- reg = <0xe800>;
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+index 9398f0349944e..ca5f5ad32ce5f 100644
+--- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+@@ -35,7 +35,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1208000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l5a: ldo5 {
+@@ -43,7 +42,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l7a: ldo7 {
+@@ -51,7 +49,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l13a: ldo13 {
+@@ -59,7 +56,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+
+@@ -72,7 +68,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l2c: ldo2 {
+@@ -80,7 +75,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l3c: ldo3 {
+@@ -96,7 +90,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1208000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l6c: ldo6 {
+@@ -112,7 +105,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l10c: ldo10 {
+@@ -141,7 +133,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l7g: ldo7 {
+@@ -149,7 +140,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l8g: ldo8 {
+@@ -157,7 +147,6 @@
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
+index 8290d036044a1..edfcd47e1a00f 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
+@@ -24,8 +24,6 @@
+ };
+
+ &pm6150_adc {
+- status = "disabled";
+-
+ /delete-node/ skin-temp-thermistor@4e;
+ /delete-node/ charger-thermistor@4f;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+index 2cf7d5212c61c..002663d752da3 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+@@ -55,8 +55,6 @@ ap_ts_pen_1v8: &i2c4 {
+ };
+
+ &pm6150_adc {
+- status = "disabled";
+-
+ /delete-node/ charger-thermistor@4f;
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dts b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
+index 6d3ff80582ae9..e2e37a0292ad6 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dts
++++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
+@@ -78,7 +78,7 @@
+ };
+
+ &pmk8350_vadc {
+- pmr735a_die_temp {
++ pmr735a-die-temp@403 {
+ reg = <PMR735A_ADC7_DIE_TEMP>;
+ label = "pmr735a_die_temp";
+ qcom,pre-scaling = <1 1>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+index a74e0b730db61..27c47ddbdf02d 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+@@ -264,7 +264,7 @@
+ };
+
+ &pmk8350_vadc {
+- pmk8350_die_temp {
++ pmk8350-die-temp@3 {
+ reg = <PMK8350_ADC7_DIE_TEMP>;
+ label = "pmk8350_die_temp";
+ qcom,pre-scaling = <1 1>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index dac3b69e314f1..51ed691075ad3 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -2168,9 +2168,8 @@
+ lpasscc: lpasscc@3000000 {
+ compatible = "qcom,sc7280-lpasscc";
+ reg = <0 0x03000000 0 0x40>,
+- <0 0x03c04000 0 0x4>,
+- <0 0x03389000 0 0x24>;
+- reg-names = "qdsp6ss", "top_cc", "cc";
++ <0 0x03c04000 0 0x4>;
++ reg-names = "qdsp6ss", "top_cc";
+ clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>;
+ clock-names = "iface";
+ #clock-cells = <1>;
+@@ -2192,13 +2191,13 @@
+ reg = <0 0x03380000 0 0x30000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&rpmhcc RPMH_CXO_CLK_A>,
+- <&lpasscore LPASS_CORE_CC_CORE_CLK>;
++ <&lpass_core LPASS_CORE_CC_CORE_CLK>;
+ clock-names = "bi_tcxo", "bi_tcxo_ao", "iface";
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+- lpasscore: clock-controller@3900000 {
++ lpass_core: clock-controller@3900000 {
+ compatible = "qcom,sc7280-lpasscorecc";
+ reg = <0 0x03900000 0 0x50000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+index 45058ad0a1c8a..6792e88b2c6c5 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+@@ -87,7 +87,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+@@ -97,7 +96,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l6b: ldo6 {
+@@ -105,7 +103,6 @@
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ regulator-boot-on;
+ };
+ };
+@@ -119,7 +116,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l7c: ldo7 {
+@@ -135,7 +131,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+
+@@ -158,7 +153,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l6d: ldo6 {
+@@ -166,7 +160,6 @@
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l7d: ldo7 {
+@@ -174,7 +167,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l9d: ldo9 {
+@@ -182,7 +174,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+index 4c404e2eafbac..f0ab207cc8e9e 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+@@ -79,7 +79,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ regulator-boot-on;
+ };
+
+@@ -88,7 +87,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l6b: ldo6 {
+@@ -96,7 +94,6 @@
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ regulator-boot-on;
+ regulator-always-on; // FIXME: VDD_A_EDP_0_0P9
+ };
+@@ -111,7 +108,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l12c: ldo12 {
+@@ -119,7 +115,6 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l13c: ldo13 {
+@@ -127,7 +122,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+
+@@ -142,7 +136,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l4d: ldo4 {
+@@ -150,7 +143,6 @@
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l7d: ldo7 {
+@@ -158,7 +150,6 @@
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+
+ vreg_l9d: ldo9 {
+@@ -166,7 +157,6 @@
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+- regulator-allow-set-load;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+index ae90b97aecb8e..24836b6b9bbc9 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+@@ -60,9 +60,8 @@
+ #interrupt-cells = <2>;
+ };
+
+- pmc8280c_lpg: lpg@e800 {
++ pmc8280c_lpg: pwm {
+ compatible = "qcom,pm8350c-pwm";
+- reg = <0xe800>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+index 7713e8060c5b6..de2d10e0315af 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+@@ -536,42 +536,42 @@
+ reg = <ADC5_XO_THERM_100K_PU>;
+ label = "xo_therm";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+
+ adc-chan@4d {
+ reg = <ADC5_AMUX_THM1_100K_PU>;
+ label = "msm_therm";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+
+ adc-chan@4f {
+ reg = <ADC5_AMUX_THM3_100K_PU>;
+ label = "pa_therm1";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+
+ adc-chan@51 {
+ reg = <ADC5_AMUX_THM5_100K_PU>;
+ label = "quiet_therm";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+
+ adc-chan@83 {
+ reg = <ADC5_VPH_PWR>;
+ label = "vph_pwr";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+
+ adc-chan@85 {
+ reg = <ADC5_VCOIN>;
+ label = "vcoin";
+ qcom,ratiometric;
+- qcom,hw-settle-time-us = <200>;
++ qcom,hw-settle-time = <200>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index 7747081b98875..dba7c2693ff50 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -617,7 +617,7 @@
+ pins = "gpio6", "gpio10";
+ function = "gpio";
+ drive-strength = <8>;
+- bias-disable = <0>;
++ bias-disable;
+ };
+
+ sde_dsi_suspend: sde-dsi-suspend {
+diff --git a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
+index cb9bbd234b7bc..b702ab1605bb0 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
+@@ -223,7 +223,7 @@
+ gpio-reserved-ranges = <44 4>;
+
+ ts_int_default: ts-int-default {
+- pin = "gpio23";
++ pins = "gpio23";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 4978c5ba5dd08..8a6c0f3e7bb70 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -3117,7 +3117,7 @@
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8450-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0xe10>;
++ reg = <0 0x01d87000 0 0x1c4>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+index 40201a16d653c..af84d4797972e 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+@@ -334,8 +334,8 @@
+ compatible = "renesas,r9a07g043-sci", "renesas,sci";
+ reg = <0 0x1004d000 0 0x400>;
+ interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G043_SCI0_CLKP>;
+@@ -349,8 +349,8 @@
+ compatible = "renesas,r9a07g043-sci", "renesas,sci";
+ reg = <0 0x1004d400 0 0x400>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G043_SCI1_CLKP>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+index 3652e511160fb..265140b20dadd 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+@@ -394,8 +394,8 @@
+ compatible = "renesas,r9a07g044-sci", "renesas,sci";
+ reg = <0 0x1004d000 0 0x400>;
+ interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G044_SCI0_CLKP>;
+@@ -409,8 +409,8 @@
+ compatible = "renesas,r9a07g044-sci", "renesas,sci";
+ reg = <0 0x1004d400 0 0x400>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G044_SCI1_CLKP>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+index 4d6b9d7684c94..d0eeca4f6aa1b 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+@@ -399,8 +399,8 @@
+ compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ reg = <0 0x1004d000 0 0x400>;
+ interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCI0_CLKP>;
+@@ -414,8 +414,8 @@
+ compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ reg = <0 0x1004d400 0 0x400>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCI1_CLKP>;
+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 121975dc82397..7e8552fd2b6ae 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
+@@ -134,15 +134,17 @@
+ >;
+ };
+
+- main_usbss0_pins_default: main-usbss0-pins-default {
++ vdd_sd_dv_pins_default: vdd-sd-dv-pins-default {
+ pinctrl-single,pins = <
+- J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
++ J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
+ >;
+ };
++};
+
+- vdd_sd_dv_pins_default: vdd-sd-dv-pins-default {
++&main_pmx1 {
++ main_usbss0_pins_default: main-usbss0-pins-default {
+ pinctrl-single,pins = <
+- J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
++ 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 16684a2f054d9..e12a53f1857f8 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+@@ -295,7 +295,16 @@
+ main_pmx0: pinctrl@11c000 {
+ compatible = "pinctrl-single";
+ /* Proxy 0 addressing */
+- reg = <0x00 0x11c000 0x00 0x2b4>;
++ reg = <0x00 0x11c000 0x00 0x10c>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ main_pmx1: pinctrl@11c11c {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x11c11c 0x00 0xc>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
+index aa523591a44e5..760c62f8e22f8 100644
+--- a/arch/arm64/include/asm/mte.h
++++ b/arch/arm64/include/asm/mte.h
+@@ -42,7 +42,9 @@ void mte_sync_tags(pte_t old_pte, pte_t pte);
+ void mte_copy_page_tags(void *kto, const void *kfrom);
+ void mte_thread_init_user(void);
+ void mte_thread_switch(struct task_struct *next);
++void mte_cpu_setup(void);
+ void mte_suspend_enter(void);
++void mte_suspend_exit(void);
+ long set_mte_ctrl(struct task_struct *task, unsigned long arg);
+ long get_mte_ctrl(struct task_struct *task);
+ int mte_ptrace_copy_tags(struct task_struct *child, long request,
+@@ -72,6 +74,9 @@ static inline void mte_thread_switch(struct task_struct *next)
+ static inline void mte_suspend_enter(void)
+ {
+ }
++static inline void mte_suspend_exit(void)
++{
++}
+ static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+ {
+ return 0;
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index 53b973b6059f7..bc857d19acd43 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -214,6 +214,11 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
+ ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
+ },
+ #endif
++#ifdef CONFIG_ARM64_ERRATUM_2441007
++ {
++ ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
++ },
++#endif
+ #ifdef CONFIG_ARM64_ERRATUM_2441009
+ {
+ /* Cortex-A510 r0p0 -> r1p1. Fixed in r1p2 */
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index af4de817d7123..d7a077b5ccd1c 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -2034,7 +2034,8 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused)
+ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
+ {
+ sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
+- isb();
++
++ mte_cpu_setup();
+
+ /*
+ * Clear the tags in the zero page. This needs to be done via the
+diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
+index ea5dc7c90f465..b49ba9a24bcc8 100644
+--- a/arch/arm64/kernel/ftrace.c
++++ b/arch/arm64/kernel/ftrace.c
+@@ -217,11 +217,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
+ unsigned long pc = rec->ip;
+ u32 old = 0, new;
+
++ new = aarch64_insn_gen_nop();
++
++ /*
++ * When using mcount, callsites in modules may have been initalized to
++ * call an arbitrary module PLT (which redirects to the _mcount stub)
++ * rather than the ftrace PLT we'll use at runtime (which redirects to
++ * the ftrace trampoline). We can ignore the old PLT when initializing
++ * the callsite.
++ *
++ * Note: 'mod' is only set at module load time.
++ */
++ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) &&
++ IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && mod) {
++ return aarch64_insn_patch_text_nosync((void *)pc, new);
++ }
++
+ if (!ftrace_find_callable_addr(rec, mod, &addr))
+ return -EINVAL;
+
+ old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
+- new = aarch64_insn_gen_nop();
+
+ return ftrace_modify_code(pc, old, new, true);
+ }
+diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
+index b2b730233274b..7467217c1eaf3 100644
+--- a/arch/arm64/kernel/mte.c
++++ b/arch/arm64/kernel/mte.c
+@@ -48,7 +48,12 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
+ if (!pte_is_tagged)
+ return;
+
+- mte_clear_page_tags(page_address(page));
++ /*
++ * Test PG_mte_tagged again in case it was racing with another
++ * set_pte_at().
++ */
++ if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++ mte_clear_page_tags(page_address(page));
+ }
+
+ void mte_sync_tags(pte_t old_pte, pte_t pte)
+@@ -64,7 +69,7 @@ void mte_sync_tags(pte_t old_pte, pte_t pte)
+
+ /* if PG_mte_tagged is set, tags have already been initialised */
+ for (i = 0; i < nr_pages; i++, page++) {
+- if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++ if (!test_bit(PG_mte_tagged, &page->flags))
+ mte_sync_page_tags(page, old_pte, check_swap,
+ pte_is_tagged);
+ }
+@@ -285,6 +290,49 @@ void mte_thread_switch(struct task_struct *next)
+ mte_check_tfsr_el1();
+ }
+
++void mte_cpu_setup(void)
++{
++ u64 rgsr;
++
++ /*
++ * CnP must be enabled only after the MAIR_EL1 register has been set
++ * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may
++ * lead to the wrong memory type being used for a brief window during
++ * CPU power-up.
++ *
++ * CnP is not a boot feature so MTE gets enabled before CnP, but let's
++ * make sure that is the case.
++ */
++ BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT);
++ BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT);
++
++ /* Normal Tagged memory type at the corresponding MAIR index */
++ sysreg_clear_set(mair_el1,
++ MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED),
++ MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED,
++ MT_NORMAL_TAGGED));
++
++ write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1);
++
++ /*
++ * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
++ * RGSR_EL1.SEED must be non-zero for IRG to produce
++ * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
++ * must initialize it.
++ */
++ rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) <<
++ SYS_RGSR_EL1_SEED_SHIFT;
++ if (rgsr == 0)
++ rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT;
++ write_sysreg_s(rgsr, SYS_RGSR_EL1);
++
++ /* clear any pending tag check faults in TFSR*_EL1 */
++ write_sysreg_s(0, SYS_TFSR_EL1);
++ write_sysreg_s(0, SYS_TFSRE0_EL1);
++
++ local_flush_tlb_all();
++}
++
+ void mte_suspend_enter(void)
+ {
+ if (!system_supports_mte())
+@@ -301,6 +349,14 @@ void mte_suspend_enter(void)
+ mte_check_tfsr_el1();
+ }
+
++void mte_suspend_exit(void)
++{
++ if (!system_supports_mte())
++ return;
++
++ mte_cpu_setup();
++}
++
+ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+ {
+ u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) &
+diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
+index 9135fe0f3df53..8b02d310838f9 100644
+--- a/arch/arm64/kernel/suspend.c
++++ b/arch/arm64/kernel/suspend.c
+@@ -43,6 +43,8 @@ void notrace __cpu_suspend_exit(void)
+ {
+ unsigned int cpu = smp_processor_id();
+
++ mte_suspend_exit();
++
+ /*
+ * We are resuming from reset with the idmap active in TTBR0_EL1.
+ * We must uninstall the idmap and restore the expected MMU
+diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
+index 44ebf5b2fc4b7..817d788cd8666 100644
+--- a/arch/arm64/kernel/topology.c
++++ b/arch/arm64/kernel/topology.c
+@@ -22,46 +22,6 @@
+ #include <asm/cputype.h>
+ #include <asm/topology.h>
+
+-void store_cpu_topology(unsigned int cpuid)
+-{
+- struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
+- u64 mpidr;
+-
+- if (cpuid_topo->package_id != -1)
+- goto topology_populated;
+-
+- mpidr = read_cpuid_mpidr();
+-
+- /* Uniprocessor systems can rely on default topology values */
+- if (mpidr & MPIDR_UP_BITMASK)
+- return;
+-
+- /*
+- * This would be the place to create cpu topology based on MPIDR.
+- *
+- * However, it cannot be trusted to depict the actual topology; some
+- * pieces of the architecture enforce an artificial cap on Aff0 values
+- * (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an
+- * artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up
+- * having absolutely no relationship to the actual underlying system
+- * topology, and cannot be reasonably used as core / package ID.
+- *
+- * If the MT bit is set, Aff0 *could* be used to define a thread ID, but
+- * we still wouldn't be able to obtain a sane core ID. This means we
+- * need to entirely ignore MPIDR for any topology deduction.
+- */
+- cpuid_topo->thread_id = -1;
+- cpuid_topo->core_id = cpuid;
+- cpuid_topo->package_id = cpu_to_node(cpuid);
+-
+- pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
+- cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
+- cpuid_topo->thread_id, mpidr);
+-
+-topology_populated:
+- update_siblings_masks(cpuid);
+-}
+-
+ #ifdef CONFIG_ACPI
+ static bool __init acpi_cpu_is_threaded(int cpu)
+ {
+diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
+index 4334dec93bd44..bed803d8e1585 100644
+--- a/arch/arm64/mm/mteswap.c
++++ b/arch/arm64/mm/mteswap.c
+@@ -53,7 +53,12 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
+ if (!tags)
+ return false;
+
+- mte_restore_page_tags(page_address(page), tags);
++ /*
++ * Test PG_mte_tagged again in case it was racing with another
++ * set_pte_at().
++ */
++ if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++ mte_restore_page_tags(page_address(page), tags);
+
+ return true;
+ }
+diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
+index 7837a69524c53..f38bccdd374a5 100644
+--- a/arch/arm64/mm/proc.S
++++ b/arch/arm64/mm/proc.S
+@@ -48,17 +48,19 @@
+
+ #ifdef CONFIG_KASAN_HW_TAGS
+ #define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
+-#else
++#elif defined(CONFIG_ARM64_MTE)
+ /*
+ * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
+ * TBI being enabled at EL1.
+ */
+ #define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1
++#else
++#define TCR_MTE_FLAGS 0
+ #endif
+
+ /*
+ * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
+- * changed during __cpu_setup to Normal Tagged if the system supports MTE.
++ * changed during mte_cpu_setup to Normal Tagged if the system supports MTE.
+ */
+ #define MAIR_EL1_SET \
+ (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) | \
+@@ -426,46 +428,8 @@ SYM_FUNC_START(__cpu_setup)
+ mov_q mair, MAIR_EL1_SET
+ mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
+ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+- TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS
+-
+-#ifdef CONFIG_ARM64_MTE
+- /*
+- * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported
+- * (ID_AA64PFR1_EL1[11:8] > 1).
+- */
+- mrs x10, ID_AA64PFR1_EL1
+- ubfx x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4
+- cmp x10, #ID_AA64PFR1_MTE
+- b.lt 1f
+-
+- /* Normal Tagged memory type at the corresponding MAIR index */
+- mov x10, #MAIR_ATTR_NORMAL_TAGGED
+- bfi mair, x10, #(8 * MT_NORMAL_TAGGED), #8
++ TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+
+- mov x10, #KERNEL_GCR_EL1
+- msr_s SYS_GCR_EL1, x10
+-
+- /*
+- * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
+- * RGSR_EL1.SEED must be non-zero for IRG to produce
+- * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
+- * must initialize it.
+- */
+- mrs x10, CNTVCT_EL0
+- ands x10, x10, #SYS_RGSR_EL1_SEED_MASK
+- csinc x10, x10, xzr, ne
+- lsl x10, x10, #SYS_RGSR_EL1_SEED_SHIFT
+- msr_s SYS_RGSR_EL1, x10
+-
+- /* clear any pending tag check faults in TFSR*_EL1 */
+- msr_s SYS_TFSR_EL1, xzr
+- msr_s SYS_TFSRE0_EL1, xzr
+-
+- /* set the TCR_EL1 bits */
+- mov_q x10, TCR_MTE_FLAGS
+- orr tcr, tcr, x10
+-1:
+-#endif
+ tcr_clear_errata_bits tcr, x9, x5
+
+ #ifdef CONFIG_ARM64_VA_BITS_52
+diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
+index d6579ec3ea324..4c7b1f50e3b7d 100644
+--- a/arch/ia64/mm/numa.c
++++ b/arch/ia64/mm/numa.c
+@@ -75,5 +75,6 @@ int memory_add_physaddr_to_nid(u64 addr)
+ return 0;
+ return nid;
+ }
++EXPORT_SYMBOL(memory_add_physaddr_to_nid);
+ #endif
+ #endif
+diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
+index e62fa8f2149b3..7e7ef67cff8b2 100644
+--- a/arch/m68k/kernel/setup_mm.c
++++ b/arch/m68k/kernel/setup_mm.c
+@@ -109,10 +109,9 @@ extern void paging_init(void);
+
+ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ {
++ const struct bi_record *first_record = record;
+ uint16_t tag;
+
+- save_bootinfo(record);
+-
+ while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
+ int unknown = 0;
+ const void *data = record->data;
+@@ -182,6 +181,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ record = (struct bi_record *)((unsigned long)record + size);
+ }
+
++ save_bootinfo(first_record);
++
+ m68k_realnum_memory = m68k_num_memory;
+ #ifdef CONFIG_SINGLE_MEMORY_CHUNK
+ if (m68k_num_memory > 1) {
+diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
+index ab203e66ba0dd..a9bea411d9282 100644
+--- a/arch/mips/bcm47xx/prom.c
++++ b/arch/mips/bcm47xx/prom.c
+@@ -86,7 +86,7 @@ static __init void prom_init_mem(void)
+ pr_debug("Assume 128MB RAM\n");
+ break;
+ }
+- if (!memcmp(prom_init, prom_init + mem, 32))
++ if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32))
+ break;
+ }
+ lowmem = mem;
+@@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void)
+
+ off = EXTVBASE + __pa(off);
+ for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
+- if (!memcmp(prom_init, (void *)(off + extmem), 16))
++ if (!memcmp((void *)prom_init, (void *)(off + extmem), 16))
+ break;
+ }
+ extmem -= lowmem;
+diff --git a/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts b/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
+index 34006e6677806..0d01e542a0a6e 100644
+--- a/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
++++ b/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
+@@ -83,12 +83,12 @@
+
+ &gmac1 {
+ status = "okay";
+- phy-handle = <ðphy7>;
++ phy-handle = <ðphy5>;
+ };
+
+ &mdio {
+- ethphy7: ethernet-phy@7 {
+- reg = <7>;
++ ethphy5: ethernet-phy@5 {
++ reg = <5>;
+ phy-mode = "rgmii-rxid";
+ };
+ };
+diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
+index e762886d1dda9..5143d1cf8984c 100644
+--- a/arch/mips/sgi-ip27/ip27-xtalk.c
++++ b/arch/mips/sgi-ip27/ip27-xtalk.c
+@@ -27,15 +27,18 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ {
+ struct xtalk_bridge_platform_data *bd;
+ struct sgi_w1_platform_data *wd;
+- struct platform_device *pdev;
++ struct platform_device *pdev_wd;
++ struct platform_device *pdev_bd;
+ struct resource w1_res;
+ unsigned long offset;
+
+ offset = NODE_OFFSET(nasid);
+
+ wd = kzalloc(sizeof(*wd), GFP_KERNEL);
+- if (!wd)
+- goto no_mem;
++ if (!wd) {
++ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++ return;
++ }
+
+ snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
+ offset + (widget << SWIN_SIZE_BITS));
+@@ -46,24 +49,35 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ w1_res.end = w1_res.start + 3;
+ w1_res.flags = IORESOURCE_MEM;
+
+- pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
+- if (!pdev) {
+- kfree(wd);
+- goto no_mem;
++ pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
++ if (!pdev_wd) {
++ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++ goto err_kfree_wd;
++ }
++ if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
++ pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget);
++ goto err_put_pdev_wd;
++ }
++ if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
++ pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
++ goto err_put_pdev_wd;
++ }
++ if (platform_device_add(pdev_wd)) {
++ pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
++ goto err_put_pdev_wd;
+ }
+- platform_device_add_resources(pdev, &w1_res, 1);
+- platform_device_add_data(pdev, wd, sizeof(*wd));
+ /* platform_device_add_data() duplicates the data */
+ kfree(wd);
+- platform_device_add(pdev);
+
+ bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+- if (!bd)
+- goto no_mem;
+- pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
+- if (!pdev) {
+- kfree(bd);
+- goto no_mem;
++ if (!bd) {
++ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++ goto err_unregister_pdev_wd;
++ }
++ pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
++ if (!pdev_bd) {
++ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++ goto err_kfree_bd;
+ }
+
+
+@@ -84,15 +98,31 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ bd->io.flags = IORESOURCE_IO;
+ bd->io_offset = offset;
+
+- platform_device_add_data(pdev, bd, sizeof(*bd));
++ if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
++ pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
++ goto err_put_pdev_bd;
++ }
++ if (platform_device_add(pdev_bd)) {
++ pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
++ goto err_put_pdev_bd;
++ }
+ /* platform_device_add_data() duplicates the data */
+ kfree(bd);
+- platform_device_add(pdev);
+ pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget);
+ return;
+
+-no_mem:
+- pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++err_put_pdev_bd:
++ platform_device_put(pdev_bd);
++err_kfree_bd:
++ kfree(bd);
++err_unregister_pdev_wd:
++ platform_device_unregister(pdev_wd);
++ return;
++err_put_pdev_wd:
++ platform_device_put(pdev_wd);
++err_kfree_wd:
++ kfree(wd);
++ return;
+ }
+
+ static int probe_one_port(nasid_t nasid, int widget, int masterwid)
+diff --git a/arch/mips/sgi-ip30/ip30-xtalk.c b/arch/mips/sgi-ip30/ip30-xtalk.c
+index 8129524421cb0..7ceb2b23ea1cf 100644
+--- a/arch/mips/sgi-ip30/ip30-xtalk.c
++++ b/arch/mips/sgi-ip30/ip30-xtalk.c
+@@ -40,12 +40,15 @@ static void bridge_platform_create(int widget, int masterwid)
+ {
+ struct xtalk_bridge_platform_data *bd;
+ struct sgi_w1_platform_data *wd;
+- struct platform_device *pdev;
++ struct platform_device *pdev_wd;
++ struct platform_device *pdev_bd;
+ struct resource w1_res;
+
+ wd = kzalloc(sizeof(*wd), GFP_KERNEL);
+- if (!wd)
+- goto no_mem;
++ if (!wd) {
++ pr_warn("xtalk:%x bridge create out of memory\n", widget);
++ return;
++ }
+
+ snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
+ IP30_SWIN_BASE(widget));
+@@ -56,24 +59,35 @@ static void bridge_platform_create(int widget, int masterwid)
+ w1_res.end = w1_res.start + 3;
+ w1_res.flags = IORESOURCE_MEM;
+
+- pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
+- if (!pdev) {
+- kfree(wd);
+- goto no_mem;
++ pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
++ if (!pdev_wd) {
++ pr_warn("xtalk:%x bridge create out of memory\n", widget);
++ goto err_kfree_wd;
++ }
++ if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
++ pr_warn("xtalk:%x bridge failed to add platform resources.\n", widget);
++ goto err_put_pdev_wd;
++ }
++ if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
++ pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
++ goto err_put_pdev_wd;
++ }
++ if (platform_device_add(pdev_wd)) {
++ pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
++ goto err_put_pdev_wd;
+ }
+- platform_device_add_resources(pdev, &w1_res, 1);
+- platform_device_add_data(pdev, wd, sizeof(*wd));
+ /* platform_device_add_data() duplicates the data */
+ kfree(wd);
+- platform_device_add(pdev);
+
+ bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+- if (!bd)
+- goto no_mem;
+- pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
+- if (!pdev) {
+- kfree(bd);
+- goto no_mem;
++ if (!bd) {
++ pr_warn("xtalk:%x bridge create out of memory\n", widget);
++ goto err_unregister_pdev_wd;
++ }
++ pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
++ if (!pdev_bd) {
++ pr_warn("xtalk:%x bridge create out of memory\n", widget);
++ goto err_kfree_bd;
+ }
+
+ bd->bridge_addr = IP30_RAW_SWIN_BASE(widget);
+@@ -93,15 +107,31 @@ static void bridge_platform_create(int widget, int masterwid)
+ bd->io.flags = IORESOURCE_IO;
+ bd->io_offset = IP30_SWIN_BASE(widget);
+
+- platform_device_add_data(pdev, bd, sizeof(*bd));
++ if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
++ pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
++ goto err_put_pdev_bd;
++ }
++ if (platform_device_add(pdev_bd)) {
++ pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
++ goto err_put_pdev_bd;
++ }
+ /* platform_device_add_data() duplicates the data */
+ kfree(bd);
+- platform_device_add(pdev);
+ pr_info("xtalk:%x bridge widget\n", widget);
+ return;
+
+-no_mem:
+- pr_warn("xtalk:%x bridge create out of memory\n", widget);
++err_put_pdev_bd:
++ platform_device_put(pdev_bd);
++err_kfree_bd:
++ kfree(bd);
++err_unregister_pdev_wd:
++ platform_device_unregister(pdev_wd);
++ return;
++err_put_pdev_wd:
++ platform_device_put(pdev_wd);
++err_kfree_wd:
++ kfree(wd);
++ return;
+ }
+
+ static unsigned int __init xbow_widget_active(s8 wid)
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index df7b931865d22..ecd0288544698 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -192,6 +192,11 @@ extern void __update_cache(pte_t pte);
+ #define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */
+ #define _PAGE_HPAGE_BIT 21 /* (0x400) Software: Huge Page */
+ #define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */
++#ifdef CONFIG_HUGETLB_PAGE
++#define _PAGE_SPECIAL_BIT _PAGE_DMB_BIT /* DMB feature is currently unused */
++#else
++#define _PAGE_SPECIAL_BIT _PAGE_HPAGE_BIT /* use unused HUGE PAGE bit */
++#endif
+
+ /* N.B. The bits are defined in terms of a 32 bit word above, so the */
+ /* following macro is ok for both 32 and 64 bit. */
+@@ -219,7 +224,7 @@ extern void __update_cache(pte_t pte);
+ #define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT))
+ #define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT))
+ #define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT))
+-#define _PAGE_SPECIAL (_PAGE_DMB)
++#define _PAGE_SPECIAL (1 << xlate_pabit(_PAGE_SPECIAL_BIT))
+
+ #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL)
+diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
+index df8102fb435fc..0e5ebfe8d9d29 100644
+--- a/arch/parisc/kernel/entry.S
++++ b/arch/parisc/kernel/entry.S
+@@ -499,6 +499,10 @@
+ * Finally, _PAGE_READ goes in the top bit of PL1 (so we
+ * trigger an access rights trap in user space if the user
+ * tries to read an unreadable page */
++#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
++ /* need to drop DMB bit, as it's used as SPECIAL flag */
++ depi 0,_PAGE_SPECIAL_BIT,1,\pte
++#endif
+ depd \pte,8,7,\prot
+
+ /* PAGE_USER indicates the page can be read with user privileges,
+@@ -529,6 +533,10 @@
+ * makes the tlb entry for the differently formatted pa11
+ * insertion instructions */
+ .macro make_insert_tlb_11 spc,pte,prot
++#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
++ /* need to drop DMB bit, as it's used as SPECIAL flag */
++ depi 0,_PAGE_SPECIAL_BIT,1,\pte
++#endif
+ zdep \spc,30,15,\prot
+ dep \pte,8,7,\prot
+ extru,= \pte,_PAGE_NO_CACHE_BIT,1,%r0
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 4c466acdc70d4..cbe7bb029aec8 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -828,7 +828,7 @@ config DATA_SHIFT
+ default 24 if STRICT_KERNEL_RWX && PPC64
+ range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
+ range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
+- range 20 24 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_FSL_BOOKE
++ range 20 24 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && FSL_BOOKE
+ default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+ default 18 if (DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
+ default 23 if STRICT_KERNEL_RWX && PPC_8xx
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index 02742facf8951..140a5e6471fef 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -152,7 +152,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8
+ CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8)
+ else
+ CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5))
+-CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4)
++CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4
+ endif
+ else ifdef CONFIG_PPC_BOOK3E_64
+ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
+diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
+index a9cd2ea4a8617..d32d95aea5d6f 100644
+--- a/arch/powerpc/boot/Makefile
++++ b/arch/powerpc/boot/Makefile
+@@ -34,6 +34,7 @@ endif
+
+ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
++ $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \
+ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+ $(LINUXINCLUDE)
+
+diff --git a/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
+new file mode 100644
+index 0000000000000..7e2a90cde72e5
+--- /dev/null
++++ b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
+@@ -0,0 +1,51 @@
++/*
++ * e500v1 Power ISA Device Tree Source (include)
++ *
++ * Copyright 2012 Freescale Semiconductor Inc.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * * Neither the name of Freescale Semiconductor nor the
++ * names of its contributors may be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") as published by the Free Software
++ * Foundation, either version 2 of that License or (at your option) any
++ * later version.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/ {
++ cpus {
++ power-isa-version = "2.03";
++ power-isa-b; // Base
++ power-isa-e; // Embedded
++ power-isa-atb; // Alternate Time Base
++ power-isa-cs; // Cache Specification
++ power-isa-e.le; // Embedded.Little-Endian
++ power-isa-e.pm; // Embedded.Performance Monitor
++ power-isa-ecl; // Embedded Cache Locking
++ power-isa-mmc; // Memory Coherence
++ power-isa-sp; // Signal Processing Engine
++ power-isa-sp.fs; // SPE.Embedded Float Scalar Single
++ power-isa-sp.fv; // SPE.Embedded Float Vector
++ mmu-type = "power-embedded";
++ };
++};
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
+index 18a885130538a..e03ae130162ba 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
+@@ -7,7 +7,7 @@
+
+ /dts-v1/;
+
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+
+ / {
+ model = "MPC8540ADS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
+index ac381e7b1c60e..a2a6c5cf852e9 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
+@@ -7,7 +7,7 @@
+
+ /dts-v1/;
+
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+
+ / {
+ model = "MPC8541CDS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
+index 9f58db2a7e661..901b6ff06dfbb 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
+@@ -7,7 +7,7 @@
+
+ /dts-v1/;
+
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+
+ / {
+ model = "MPC8555CDS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
+index a24722ccaebf1..c2f9aea78b29f 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
+@@ -7,7 +7,7 @@
+
+ /dts-v1/;
+
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+
+ / {
+ model = "MPC8560ADS";
+diff --git a/arch/powerpc/boot/dts/turris1x.dts b/arch/powerpc/boot/dts/turris1x.dts
+index 12e08271e61f0..045af668e9284 100644
+--- a/arch/powerpc/boot/dts/turris1x.dts
++++ b/arch/powerpc/boot/dts/turris1x.dts
+@@ -147,7 +147,7 @@
+
+ port@0 {
+ reg = <0>;
+- label = "cpu1";
++ label = "cpu";
+ ethernet = <&enet1>;
+ phy-mode = "rgmii-id";
+
+@@ -184,7 +184,7 @@
+
+ port@6 {
+ reg = <6>;
+- label = "cpu0";
++ label = "cpu";
+ ethernet = <&enet0>;
+ phy-mode = "rgmii-id";
+
+@@ -263,21 +263,21 @@
+ };
+
+ partition@20000 {
+- /* 1.7 MB for Rescue Linux Kernel Image */
++ /* 1.7 MB for Linux Kernel Image */
+ reg = <0x00020000 0x001a0000>;
+- label = "rescue-kernel";
++ label = "kernel";
+ };
+
+ partition@1c0000 {
+ /* 1.5 MB for Rescue JFFS2 Root File System */
+ reg = <0x001c0000 0x00180000>;
+- label = "rescue-rootfs";
++ label = "rescue";
+ };
+
+ partition@340000 {
+- /* 11 MB for TAR.XZ Backup with content of NAND Root File System */
++ /* 11 MB for TAR.XZ Archive with Factory content of NAND Root File System */
+ reg = <0x00340000 0x00b00000>;
+- label = "backup-rootfs";
++ label = "factory";
+ };
+
+ partition@e40000 {
+diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
+index b571d084c148b..c05e37af9f1e8 100644
+--- a/arch/powerpc/configs/pseries_defconfig
++++ b/arch/powerpc/configs/pseries_defconfig
+@@ -40,6 +40,7 @@ CONFIG_PPC_SPLPAR=y
+ CONFIG_DTL=y
+ CONFIG_PPC_SMLPAR=y
+ CONFIG_IBMEBUS=y
++CONFIG_LIBNVDIMM=m
+ CONFIG_PAPR_SCM=m
+ CONFIG_PPC_SVM=y
+ # CONFIG_PPC_PMAC is not set
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index 8069dbc4b8d18..b61555e30c7c8 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -195,7 +195,8 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs)
+ * so avoid recursion.
+ */
+ if (TRAP(regs) != INTERRUPT_PROGRAM) {
+- CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
++ CT_WARN_ON(ct_state() != CONTEXT_KERNEL &&
++ ct_state() != CONTEXT_IDLE);
+ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+ BUG_ON(is_implicit_soft_masked(regs));
+ }
+diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
+index a2b13e55254fb..da40219b303a6 100644
+--- a/arch/powerpc/include/asm/syscalls.h
++++ b/arch/powerpc/include/asm/syscalls.h
+@@ -8,6 +8,18 @@
+ #include <linux/types.h>
+ #include <linux/compat.h>
+
++/*
++ * long long munging:
++ * The 32 bit ABI passes long longs in an odd even register pair.
++ * High and low parts are swapped depending on endian mode,
++ * so define a macro (similar to mips linux32) to handle that.
++ */
++#ifdef __LITTLE_ENDIAN__
++#define merge_64(low, high) (((u64)high << 32) | low)
++#else
++#define merge_64(high, low) (((u64)high << 32) | low)
++#endif
++
+ struct rtas_args;
+
+ asmlinkage long sys_mmap(unsigned long addr, size_t len,
+diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
+index 0e75cb03244ad..f9db0a172401a 100644
+--- a/arch/powerpc/kernel/interrupt.c
++++ b/arch/powerpc/kernel/interrupt.c
+@@ -431,16 +431,6 @@ again:
+
+ if (unlikely(stack_store))
+ __hard_EE_RI_disable();
+- /*
+- * Returning to a kernel context with local irqs disabled.
+- * Here, if EE was enabled in the interrupted context, enable
+- * it on return as well. A problem exists here where a soft
+- * masked interrupt may have cleared MSR[EE] and set HARD_DIS
+- * here, and it will still exist on return to the caller. This
+- * will be resolved by the masked interrupt firing again.
+- */
+- if (regs->msr & MSR_EE)
+- local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+ #endif /* CONFIG_PPC64 */
+ }
+
+diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
+index ce25b28cf418e..2ca1c037ea258 100644
+--- a/arch/powerpc/kernel/interrupt_64.S
++++ b/arch/powerpc/kernel/interrupt_64.S
+@@ -559,15 +559,54 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
+ ld r11,SOFTE(r1)
+ cmpwi r11,IRQS_ENABLED
+ stb r11,PACAIRQSOFTMASK(r13)
+- bne 1f
++ beq .Linterrupt_return_\srr\()_soft_enabled
++
++ /*
++ * Returning to soft-disabled context.
++ * Check if a MUST_HARD_MASK interrupt has become pending, in which
++ * case we need to disable MSR[EE] in the return context.
++ */
++ ld r12,_MSR(r1)
++ andi. r10,r12,MSR_EE
++ beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled
++ lbz r11,PACAIRQHAPPENED(r13)
++ andi. r10,r11,PACA_IRQ_MUST_HARD_MASK
++ beq .Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending
++
++ /* Must clear MSR_EE from _MSR */
++#ifdef CONFIG_PPC_BOOK3S
++ li r10,0
++ /* Clear valid before changing _MSR */
++ .ifc \srr,srr
++ stb r10,PACASRR_VALID(r13)
++ .else
++ stb r10,PACAHSRR_VALID(r13)
++ .endif
++#endif
++ xori r12,r12,MSR_EE
++ std r12,_MSR(r1)
++ b .Lfast_kernel_interrupt_return_\srr\()
++
++.Linterrupt_return_\srr\()_soft_enabled:
++ /*
++ * In the soft-enabled case, need to double-check that we have no
++ * pending interrupts that might have come in before we reached the
++ * restart section of code, and restart the exit so those can be
++ * handled.
++ *
++ * If there are none, it is be possible that the interrupt still
++ * has PACA_IRQ_HARD_DIS set, which needs to be cleared for the
++ * interrupted context. This clear will not clobber a new pending
++ * interrupt coming in, because we're in the restart section, so
++ * such would return to the restart location.
++ */
+ #ifdef CONFIG_PPC_BOOK3S
+ lbz r11,PACAIRQHAPPENED(r13)
+ andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
+ bne- interrupt_return_\srr\()_kernel_restart
+ #endif
+ li r11,0
+- stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
+-1:
++ stb r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS
+
+ .Lfast_kernel_interrupt_return_\srr\():
+ cmpdi cr1,r3,0
+diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
+index 912d4f8a13beb..bd7b1a0354594 100644
+--- a/arch/powerpc/kernel/kprobes.c
++++ b/arch/powerpc/kernel/kprobes.c
+@@ -161,7 +161,13 @@ int arch_prepare_kprobe(struct kprobe *p)
+ preempt_disable();
+ prev = get_kprobe(p->addr - 1);
+ preempt_enable_no_resched();
+- if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
++
++ /*
++ * When prev is a ftrace-based kprobe, we don't have an insn, and it
++ * doesn't probe for prefixed instruction.
++ */
++ if (prev && !kprobe_ftrace(prev) &&
++ ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
+ printk("Cannot register a kprobe on the second word of prefixed instruction\n");
+ ret = -EINVAL;
+ }
+diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
+index 7a35fc25a3046..38561d6a20792 100644
+--- a/arch/powerpc/kernel/pci_dn.c
++++ b/arch/powerpc/kernel/pci_dn.c
+@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
+ INIT_LIST_HEAD(&pdn->list);
+ parent = of_get_parent(dn);
+ pdn->parent = parent ? PCI_DN(parent) : NULL;
++ of_node_put(parent);
+ if (pdn->parent)
+ list_add_tail(&pdn->list, &pdn->parent->child_list);
+
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 2b2d0b0fbb30d..ce8fc6575eaa2 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -182,8 +182,10 @@ static void __init fixup_boot_paca(void)
+ get_paca()->cpu_start = 1;
+ /* Allow percpu accesses to work until we setup percpu data */
+ get_paca()->data_offset = 0;
+- /* Mark interrupts disabled in PACA */
++ /* Mark interrupts soft and hard disabled in PACA */
+ irq_soft_mask_set(IRQS_DISABLED);
++ get_paca()->irq_happened = PACA_IRQ_HARD_DIS;
++ WARN_ON(mfmsr() & MSR_EE);
+ }
+
+ static void __init configure_exceptions(void)
+diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
+index 16ff0399a2574..719bfc6d1e3f5 100644
+--- a/arch/powerpc/kernel/sys_ppc32.c
++++ b/arch/powerpc/kernel/sys_ppc32.c
+@@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
+ return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
+ }
+
+-/*
+- * long long munging:
+- * The 32 bit ABI passes long longs in an odd even register pair.
+- * High and low parts are swapped depending on endian mode,
+- * so define a macro (similar to mips linux32) to handle that.
+- */
+-#ifdef __LITTLE_ENDIAN__
+-#define merge_64(low, high) ((u64)high << 32) | low
+-#else
+-#define merge_64(high, low) ((u64)high << 32) | low
+-#endif
+-
+ compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
+ u32 reg6, u32 pos1, u32 pos2)
+ {
+@@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
+ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2,
+ u32 len1, u32 len2)
+ {
+- return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2,
++ return ksys_fallocate(fd, mode, merge_64(offset1, offset2),
+ merge_64(len1, len2));
+ }
+
+diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
+index fc999140bc27e..abc3fbb3c4902 100644
+--- a/arch/powerpc/kernel/syscalls.c
++++ b/arch/powerpc/kernel/syscalls.c
+@@ -98,8 +98,8 @@ long ppc64_personality(unsigned long personality)
+ long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
+ u32 len_high, u32 len_low)
+ {
+- return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low,
+- (u64)len_high << 32 | len_low, advice);
++ return ksys_fadvise64_64(fd, merge_64(offset_high, offset_low),
++ merge_64(len_high, len_low), advice);
+ }
+
+ SYSCALL_DEFINE0(switch_endian)
+diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
+index 39b84e7452e1b..aa3bb8da1cb9b 100644
+--- a/arch/powerpc/math-emu/math_efp.c
++++ b/arch/powerpc/math-emu/math_efp.c
+@@ -17,6 +17,7 @@
+
+ #include <linux/types.h>
+ #include <linux/prctl.h>
++#include <linux/module.h>
+
+ #include <linux/uaccess.h>
+ #include <asm/reg.h>
+diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
+index 55a8fbfdb5b28..3510b55b36f8c 100644
+--- a/arch/powerpc/platforms/powernv/opal.c
++++ b/arch/powerpc/platforms/powernv/opal.c
+@@ -892,6 +892,7 @@ static void opal_export_attrs(void)
+ kobj = kobject_create_and_add("exports", opal_kobj);
+ if (!kobj) {
+ pr_warn("kobject_create_and_add() of exports failed\n");
++ of_node_put(np);
+ return;
+ }
+
+diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
+index 7e6e6dd2e33e9..1a2cbc156e8f3 100644
+--- a/arch/powerpc/platforms/pseries/vas.c
++++ b/arch/powerpc/platforms/pseries/vas.c
+@@ -333,7 +333,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
+ * So no unpacking needs to be done.
+ */
+ rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, domain,
+- VPHN_FLAG_VCPU, smp_processor_id());
++ VPHN_FLAG_VCPU, hard_smp_processor_id());
+ if (rc != H_SUCCESS) {
+ pr_err("H_HOME_NODE_ASSOCIATIVITY error: %d\n", rc);
+ goto out;
+diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
+index ef9a5999fa93d..73c2d70706c0a 100644
+--- a/arch/powerpc/sysdev/fsl_msi.c
++++ b/arch/powerpc/sysdev/fsl_msi.c
+@@ -209,8 +209,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+ dev_err(&pdev->dev,
+ "node %pOF has an invalid fsl,msi phandle %u\n",
+ hose->dn, np->phandle);
++ of_node_put(np);
+ return -EINVAL;
+ }
++ of_node_put(np);
+ }
+
+ msi_for_each_desc(entry, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 59d18881f35be..cea22ccb57cb9 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -52,7 +52,7 @@ config RISCV
+ select COMMON_CLK
+ select CPU_PM if CPU_IDLE
+ select EDAC_SUPPORT
+- select GENERIC_ARCH_TOPOLOGY if SMP
++ select GENERIC_ARCH_TOPOLOGY
+ select GENERIC_ATOMIC64 if !64BIT
+ select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_EARLY_IOREMAP
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index 3fa8ef3368224..e7d52a2301e26 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -37,6 +37,7 @@ else
+ endif
+
+ ifeq ($(CONFIG_LD_IS_LLD),y)
++ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0)
+ KBUILD_CFLAGS += -mno-relax
+ KBUILD_AFLAGS += -mno-relax
+ ifndef CONFIG_AS_IS_LLVM
+@@ -44,6 +45,7 @@ ifndef CONFIG_AS_IS_LLVM
+ KBUILD_AFLAGS += -Wa,-mno-relax
+ endif
+ endif
++endif
+
+ # ISA string setting
+ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
+diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
+index 69605a4742706..92080a2279372 100644
+--- a/arch/riscv/include/asm/io.h
++++ b/arch/riscv/include/asm/io.h
+@@ -101,9 +101,9 @@ __io_reads_ins(reads, u32, l, __io_br(), __io_ar(addr))
+ __io_reads_ins(ins, u8, b, __io_pbr(), __io_par(addr))
+ __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr))
+ __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr))
+-#define insb(addr, buffer, count) __insb((void __iomem *)(long)addr, buffer, count)
+-#define insw(addr, buffer, count) __insw((void __iomem *)(long)addr, buffer, count)
+-#define insl(addr, buffer, count) __insl((void __iomem *)(long)addr, buffer, count)
++#define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count)
++#define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count)
++#define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count)
+
+ __io_writes_outs(writes, u8, b, __io_bw(), __io_aw())
+ __io_writes_outs(writes, u16, w, __io_bw(), __io_aw())
+@@ -115,22 +115,22 @@ __io_writes_outs(writes, u32, l, __io_bw(), __io_aw())
+ __io_writes_outs(outs, u8, b, __io_pbw(), __io_paw())
+ __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw())
+ __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw())
+-#define outsb(addr, buffer, count) __outsb((void __iomem *)(long)addr, buffer, count)
+-#define outsw(addr, buffer, count) __outsw((void __iomem *)(long)addr, buffer, count)
+-#define outsl(addr, buffer, count) __outsl((void __iomem *)(long)addr, buffer, count)
++#define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count)
++#define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count)
++#define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count)
+
+ #ifdef CONFIG_64BIT
+ __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr))
+ #define readsq(addr, buffer, count) __readsq(addr, buffer, count)
+
+ __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr))
+-#define insq(addr, buffer, count) __insq((void __iomem *)addr, buffer, count)
++#define insq(addr, buffer, count) __insq(PCI_IOBASE + (addr), buffer, count)
+
+ __io_writes_outs(writes, u64, q, __io_bw(), __io_aw())
+ #define writesq(addr, buffer, count) __writesq(addr, buffer, count)
+
+ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
+-#define outsq(addr, buffer, count) __outsq((void __iomem *)addr, buffer, count)
++#define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count)
+ #endif
+
+ #include <asm-generic/io.h>
+diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
+index cedcf8ea3c766..0099dc1161683 100644
+--- a/arch/riscv/include/asm/mmu.h
++++ b/arch/riscv/include/asm/mmu.h
+@@ -16,7 +16,6 @@ typedef struct {
+ atomic_long_t id;
+ #endif
+ void *vdso;
+- void *vdso_info;
+ #ifdef CONFIG_SMP
+ /* A local icache flush is needed before user execution can resume. */
+ cpumask_t icache_stale_mask;
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 2dfc463b86bb3..ad76bb59b0590 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -252,10 +252,10 @@ static void __init parse_dtb(void)
+ pr_info("Machine model: %s\n", name);
+ dump_stack_set_arch_desc("%s (DT)", name);
+ }
+- return;
++ } else {
++ pr_err("No DTB passed to the kernel\n");
+ }
+
+- pr_err("No DTB passed to the kernel\n");
+ #ifdef CONFIG_CMDLINE_FORCE
+ strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ pr_info("Forcing kernel command line to: %s\n", boot_command_line);
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index a752c7b416838..3373df413c882 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -49,6 +49,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ unsigned int curr_cpuid;
+
+ curr_cpuid = smp_processor_id();
++ store_cpu_topology(curr_cpuid);
+ numa_store_cpu_info(curr_cpuid);
+ numa_add_cpu(curr_cpuid);
+
+@@ -162,9 +163,9 @@ asmlinkage __visible void smp_callin(void)
+ mmgrab(mm);
+ current->active_mm = mm;
+
++ store_cpu_topology(curr_cpuid);
+ notify_cpu_starting(curr_cpuid);
+ numa_add_cpu(curr_cpuid);
+- update_siblings_masks(curr_cpuid);
+ set_cpu_online(curr_cpuid, 1);
+
+ /*
+diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
+index 571556bb9261a..5d3f2fbeb33c7 100644
+--- a/arch/riscv/kernel/sys_riscv.c
++++ b/arch/riscv/kernel/sys_riscv.c
+@@ -18,9 +18,6 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
+ if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
+ return -EINVAL;
+
+- if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
+- return -EINVAL;
+-
+ return ksys_mmap_pgoff(addr, len, prot, flags, fd,
+ offset >> (PAGE_SHIFT - page_shift_offset));
+ }
+diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
+index 69b05b6c181b6..4abc9aebdfae2 100644
+--- a/arch/riscv/kernel/vdso.c
++++ b/arch/riscv/kernel/vdso.c
+@@ -60,6 +60,11 @@ struct __vdso_info {
+ struct vm_special_mapping *cm;
+ };
+
++static struct __vdso_info vdso_info;
++#ifdef CONFIG_COMPAT
++static struct __vdso_info compat_vdso_info;
++#endif
++
+ static int vdso_mremap(const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+ {
+@@ -114,15 +119,18 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
+ {
+ struct mm_struct *mm = task->mm;
+ struct vm_area_struct *vma;
+- struct __vdso_info *vdso_info = mm->context.vdso_info;
+
+ mmap_read_lock(mm);
+
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ unsigned long size = vma->vm_end - vma->vm_start;
+
+- if (vma_is_special_mapping(vma, vdso_info->dm))
++ if (vma_is_special_mapping(vma, vdso_info.dm))
+ zap_page_range(vma, vma->vm_start, size);
++#ifdef CONFIG_COMPAT
++ if (vma_is_special_mapping(vma, compat_vdso_info.dm))
++ zap_page_range(vma, vma->vm_start, size);
++#endif
+ }
+
+ mmap_read_unlock(mm);
+@@ -264,7 +272,6 @@ static int __setup_additional_pages(struct mm_struct *mm,
+
+ vdso_base += VVAR_SIZE;
+ mm->context.vdso = (void *)vdso_base;
+- mm->context.vdso_info = (void *)vdso_info;
+
+ ret =
+ _install_special_mapping(mm, vdso_base, vdso_text_len,
+diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
+index f2fbd1400b7c9..d86f7cebd4a7e 100644
+--- a/arch/riscv/mm/fault.c
++++ b/arch/riscv/mm/fault.c
+@@ -184,7 +184,8 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)
+ }
+ break;
+ case EXC_LOAD_PAGE_FAULT:
+- if (!(vma->vm_flags & VM_READ)) {
++ /* Write implies read */
++ if (!(vma->vm_flags & (VM_READ | VM_WRITE))) {
+ return true;
+ }
+ break;
+diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
+index 8edb824049b9e..0cb0ca149ac34 100644
+--- a/arch/sh/include/asm/sections.h
++++ b/arch/sh/include/asm/sections.h
+@@ -4,7 +4,7 @@
+
+ #include <asm-generic/sections.h>
+
+-extern long __machvec_start, __machvec_end;
++extern char __machvec_start[], __machvec_end[];
+ extern char __uncached_start, __uncached_end;
+ extern char __start_eh_frame[], __stop_eh_frame[];
+
+diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
+index d606679a211e1..57efaf5b82ae0 100644
+--- a/arch/sh/kernel/machvec.c
++++ b/arch/sh/kernel/machvec.c
+@@ -20,8 +20,8 @@
+ #define MV_NAME_SIZE 32
+
+ #define for_each_mv(mv) \
+- for ((mv) = (struct sh_machine_vector *)&__machvec_start; \
+- (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \
++ for ((mv) = (struct sh_machine_vector *)__machvec_start; \
++ (mv) && (unsigned long)(mv) < (unsigned long)__machvec_end; \
+ (mv)++)
+
+ static struct sh_machine_vector * __init get_mv_byname(const char *name)
+@@ -87,8 +87,8 @@ void __init sh_mv_setup(void)
+ if (!machvec_selected) {
+ unsigned long machvec_size;
+
+- machvec_size = ((unsigned long)&__machvec_end -
+- (unsigned long)&__machvec_start);
++ machvec_size = ((unsigned long)__machvec_end -
++ (unsigned long)__machvec_start);
+
+ /*
+ * Sanity check for machvec section alignment. Ensure
+@@ -102,7 +102,7 @@ void __init sh_mv_setup(void)
+ * vector (usually the only one) from .machvec.init.
+ */
+ if (machvec_size >= sizeof(struct sh_machine_vector))
+- sh_mv = *(struct sh_machine_vector *)&__machvec_start;
++ sh_mv = *(struct sh_machine_vector *)__machvec_start;
+ }
+
+ pr_notice("Booting machvec: %s\n", get_system_type());
+diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
+index d9e023c78f568..f6f126ac34804 100644
+--- a/arch/um/kernel/um_arch.c
++++ b/arch/um/kernel/um_arch.c
+@@ -96,7 +96,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/x86/Kconfig b/arch/x86/Kconfig
+index f9920f1341c8d..159c025ebb03e 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -448,6 +448,11 @@ config X86_X2APIC
+ This allows 32-bit apic IDs (so it can support very large systems),
+ and accesses the local apic via MSRs not via mmio.
+
++ Some Intel systems circa 2022 and later are locked into x2APIC mode
++ and can not fall back to the legacy APIC modes if SGX or TDX are
++ enabled in the BIOS. They will be unable to boot without enabling
++ this option.
++
+ If you don't know what to do here, say N.
+
+ config X86_MPPARSE
+@@ -1919,7 +1924,7 @@ endchoice
+
+ config X86_SGX
+ bool "Software Guard eXtensions (SGX)"
+- depends on X86_64 && CPU_SUP_INTEL
++ depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC
+ depends on CRYPTO=y
+ depends on CRYPTO_SHA256=y
+ select SRCU
+diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
+index 8cbf623f0ecfb..b472ef76826ad 100644
+--- a/arch/x86/include/asm/cpu.h
++++ b/arch/x86/include/asm/cpu.h
+@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
+ return p1 & p2;
+ }
+
++extern u64 x86_read_arch_cap_msr(void);
++
+ #endif /* _ASM_X86_CPU_H */
+diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
+index 0a9407dc08598..6f0acc45e67a7 100644
+--- a/arch/x86/include/asm/hyperv-tlfs.h
++++ b/arch/x86/include/asm/hyperv-tlfs.h
+@@ -546,7 +546,7 @@ struct hv_enlightened_vmcs {
+ u64 guest_rip;
+
+ u32 hv_clean_fields;
+- u32 hv_padding_32;
++ u32 padding32_1;
+ u32 hv_synthetic_controls;
+ struct {
+ u32 nested_flush_hypercall:1;
+@@ -554,7 +554,7 @@ struct hv_enlightened_vmcs {
+ u32 reserved:30;
+ } __packed hv_enlightenments_control;
+ u32 hv_vp_id;
+-
++ u32 padding32_2;
+ u64 hv_vm_id;
+ u64 partition_assist_page;
+ u64 padding64_4[4];
+diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
+index 0c3d3440fe278..aa675783412f8 100644
+--- a/arch/x86/include/asm/microcode.h
++++ b/arch/x86/include/asm/microcode.h
+@@ -9,6 +9,7 @@
+ struct ucode_patch {
+ struct list_head plist;
+ void *data; /* Intel uses only this one */
++ unsigned int size;
+ u32 patch_id;
+ u16 equiv_cpu;
+ };
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 6674bdb096f34..1e086b37a3071 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -155,6 +155,11 @@
+ * Return Stack Buffer Predictions.
+ */
+
++#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
++ * IA32_XAPIC_DISABLE_STATUS MSR
++ * supported
++ */
++
+ #define MSR_IA32_FLUSH_CMD 0x0000010b
+ #define L1D_FLUSH BIT(0) /*
+ * Writeback and invalidate the
+@@ -1054,4 +1059,12 @@
+ #define MSR_IA32_HW_FEEDBACK_PTR 0x17d0
+ #define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1
+
++/* x2APIC locked status */
++#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD
++#define LEGACY_XAPIC_DISABLED BIT(0) /*
++ * x2APIC mode is locked and
++ * disabling x2APIC will cause
++ * a #GP
++ */
++
+ #endif /* _ASM_X86_MSR_INDEX_H */
+diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
+index 89df6c6617f50..bc2e1b67319d3 100644
+--- a/arch/x86/include/asm/paravirt_types.h
++++ b/arch/x86/include/asm/paravirt_types.h
+@@ -414,8 +414,17 @@ int paravirt_disable_iospace(void);
+ "=c" (__ecx)
+ #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
+
+-/* void functions are still allowed [re]ax for scratch */
++/*
++ * void functions are still allowed [re]ax for scratch.
++ *
++ * The ZERO_CALL_USED REGS feature may end up zeroing out callee-saved
++ * registers. Make sure we model this with the appropriate clobbers.
++ */
++#ifdef CONFIG_ZERO_CALL_USED_REGS
++#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), PVOP_VCALL_CLOBBERS
++#else
+ #define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
++#endif
+ #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
+
+ #define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11"
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index 6d303d1d276c3..c6876d3ea4b17 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -61,6 +61,7 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/intel-family.h>
+ #include <asm/irq_regs.h>
++#include <asm/cpu.h>
+
+ unsigned int num_processors;
+
+@@ -1751,11 +1752,26 @@ EXPORT_SYMBOL_GPL(x2apic_mode);
+
+ enum {
+ X2APIC_OFF,
+- X2APIC_ON,
+ X2APIC_DISABLED,
++ /* All states below here have X2APIC enabled */
++ X2APIC_ON,
++ X2APIC_ON_LOCKED
+ };
+ static int x2apic_state;
+
++static bool x2apic_hw_locked(void)
++{
++ u64 ia32_cap;
++ u64 msr;
++
++ ia32_cap = x86_read_arch_cap_msr();
++ if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) {
++ rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr);
++ return (msr & LEGACY_XAPIC_DISABLED);
++ }
++ return false;
++}
++
+ static void __x2apic_disable(void)
+ {
+ u64 msr;
+@@ -1793,6 +1809,10 @@ static int __init setup_nox2apic(char *str)
+ apicid);
+ return 0;
+ }
++ if (x2apic_hw_locked()) {
++ pr_warn("APIC locked in x2apic mode, can't disable\n");
++ return 0;
++ }
+ pr_warn("x2apic already enabled.\n");
+ __x2apic_disable();
+ }
+@@ -1807,10 +1827,18 @@ early_param("nox2apic", setup_nox2apic);
+ void x2apic_setup(void)
+ {
+ /*
+- * If x2apic is not in ON state, disable it if already enabled
++ * Try to make the AP's APIC state match that of the BSP, but if the
++ * BSP is unlocked and the AP is locked then there is a state mismatch.
++ * Warn about the mismatch in case a GP fault occurs due to a locked AP
++ * trying to be turned off.
++ */
++ if (x2apic_state != X2APIC_ON_LOCKED && x2apic_hw_locked())
++ pr_warn("x2apic lock mismatch between BSP and AP.\n");
++ /*
++ * If x2apic is not in ON or LOCKED state, disable it if already enabled
+ * from BIOS.
+ */
+- if (x2apic_state != X2APIC_ON) {
++ if (x2apic_state < X2APIC_ON) {
+ __x2apic_disable();
+ return;
+ }
+@@ -1831,6 +1859,11 @@ static __init void x2apic_disable(void)
+ if (x2apic_id >= 255)
+ panic("Cannot disable x2apic, id: %08x\n", x2apic_id);
+
++ if (x2apic_hw_locked()) {
++ pr_warn("Cannot disable locked x2apic, id: %08x\n", x2apic_id);
++ return;
++ }
++
+ __x2apic_disable();
+ register_lapic_address(mp_lapic_addr);
+ }
+@@ -1889,7 +1922,10 @@ void __init check_x2apic(void)
+ if (x2apic_enabled()) {
+ pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n");
+ x2apic_mode = 1;
+- x2apic_state = X2APIC_ON;
++ if (x2apic_hw_locked())
++ x2apic_state = X2APIC_ON_LOCKED;
++ else
++ x2apic_state = X2APIC_ON;
+ } else if (!boot_cpu_has(X86_FEATURE_X2APIC)) {
+ x2apic_state = X2APIC_DISABLED;
+ }
+diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c
+index 993697e71854c..03851240c3e36 100644
+--- a/arch/x86/kernel/cpu/feat_ctl.c
++++ b/arch/x86/kernel/cpu/feat_ctl.c
+@@ -1,11 +1,11 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/tboot.h>
+
++#include <asm/cpu.h>
+ #include <asm/cpufeature.h>
+ #include <asm/msr-index.h>
+ #include <asm/processor.h>
+ #include <asm/vmx.h>
+-#include "cpu.h"
+
+ #undef pr_fmt
+ #define pr_fmt(fmt) "x86/cpu: " fmt
+diff --git a/arch/x86/kernel/cpu/mce/apei.c b/arch/x86/kernel/cpu/mce/apei.c
+index 717192915f28a..8ed341714686a 100644
+--- a/arch/x86/kernel/cpu/mce/apei.c
++++ b/arch/x86/kernel/cpu/mce/apei.c
+@@ -29,15 +29,26 @@
+ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
+ {
+ struct mce m;
++ int lsb;
+
+ if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
+ return;
+
++ /*
++ * Even if the ->validation_bits are set for address mask,
++ * to be extra safe, check and reject an error radius '0',
++ * and fall back to the default page size.
++ */
++ if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
++ lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT);
++ else
++ lsb = PAGE_SHIFT;
++
+ mce_setup(&m);
+ m.bank = -1;
+ /* Fake a memory read error with unknown channel */
+ m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f;
+- m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT;
++ m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb;
+
+ if (severity >= GHES_SEV_RECOVERABLE)
+ m.status |= MCI_STATUS_UC;
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 8b2fcdfa6d316..615bc6efa1dd4 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -788,6 +788,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,
+ kfree(patch);
+ return -EINVAL;
+ }
++ patch->size = *patch_size;
+
+ mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE);
+ proc_id = mc_hdr->processor_rev_id;
+@@ -869,7 +870,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
+ return ret;
+
+ memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
+- memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
++ memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
+
+ return ret;
+ }
+diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+index db813f819ad6c..4d8398986f784 100644
+--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
++++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+@@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ struct pseudo_lock_region *plr = rdtgrp->plr;
+ u32 rmid_p, closid_p;
+ unsigned long i;
++ u64 saved_msr;
+ #ifdef CONFIG_KASAN
+ /*
+ * The registers used for local register variables are also used
+@@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ * the buffer and evict pseudo-locked memory read earlier from the
+ * cache.
+ */
++ saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL);
+ __wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+ closid_p = this_cpu_read(pqr_state.cur_closid);
+ rmid_p = this_cpu_read(pqr_state.cur_rmid);
+@@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ __wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p);
+
+ /* Re-enable the hardware prefetcher(s) */
+- wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++ wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr);
+ local_irq_enable();
+
+ plr->thread_done = 1;
+@@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
+ static int measure_cycles_lat_fn(void *_plr)
+ {
+ struct pseudo_lock_region *plr = _plr;
++ u32 saved_low, saved_high;
+ unsigned long i;
+ u64 start, end;
+ void *mem_r;
+@@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr)
+ /*
+ * Disable hardware prefetchers.
+ */
++ rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+ mem_r = READ_ONCE(plr->kmem);
+ /*
+@@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr)
+ end = rdtsc_ordered();
+ trace_pseudo_lock_mem_latency((u32)(end - start));
+ }
+- wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++ wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ local_irq_enable();
+ plr->thread_done = 1;
+ wake_up_interruptible(&plr->lock_thread_wq);
+@@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0;
+ struct perf_event *miss_event, *hit_event;
+ int hit_pmcnum, miss_pmcnum;
++ u32 saved_low, saved_high;
+ unsigned int line_size;
+ unsigned int size;
+ unsigned long i;
+@@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ /*
+ * Disable hardware prefetchers.
+ */
++ rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+
+ /* Initialize rest of local variables */
+@@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ */
+ rmb();
+ /* Re-enable hardware prefetchers */
+- wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++ wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ local_irq_enable();
+ out_hit:
+ perf_event_release_kernel(hit_event);
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index aacb28c83e437..883e380e5801d 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -1953,7 +1953,7 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+- if (ctxt->modrm_reg == VCPU_SREG_SS)
++ if (seg == VCPU_SREG_SS)
+ ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS;
+ if (ctxt->op_bytes > 2)
+ rsp_increment(ctxt, ctxt->op_bytes - 2);
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index ddd4367d48265..03d348fa6485a 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -2328,9 +2328,14 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
+ * are emulated by vmx_set_efer() in prepare_vmcs02(), but speculate
+ * on the related bits (if supported by the CPU) in the hope that
+ * we can avoid VMWrites during vmx_set_efer().
++ *
++ * Similarly, take vmcs01's PERF_GLOBAL_CTRL in the hope that if KVM is
++ * loading PERF_GLOBAL_CTRL via the VMCS for L1, then KVM will want to
++ * do the same for L2.
+ */
+ exec_control = __vm_entry_controls_get(vmcs01);
+- exec_control |= vmcs12->vm_entry_controls;
++ exec_control |= (vmcs12->vm_entry_controls &
++ ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL);
+ exec_control &= ~(VM_ENTRY_IA32E_MODE | VM_ENTRY_LOAD_IA32_EFER);
+ if (cpu_has_load_ia32_efer()) {
+ if (guest_efer & EFER_LMA)
+@@ -3827,7 +3832,16 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu,
+ u32 intr_info = nr | INTR_INFO_VALID_MASK;
+
+ if (vcpu->arch.exception.has_error_code) {
+- vmcs12->vm_exit_intr_error_code = vcpu->arch.exception.error_code;
++ /*
++ * Intel CPUs do not generate error codes with bits 31:16 set,
++ * and more importantly VMX disallows setting bits 31:16 in the
++ * injected error code for VM-Entry. Drop the bits to mimic
++ * hardware and avoid inducing failure on nested VM-Entry if L1
++ * chooses to inject the exception back to L2. AMD CPUs _do_
++ * generate "full" 32-bit error codes, so KVM allows userspace
++ * to inject exception error codes with bits 31:16 set.
++ */
++ vmcs12->vm_exit_intr_error_code = (u16)vcpu->arch.exception.error_code;
+ intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ }
+
+@@ -4255,14 +4269,6 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
+ nested_vmx_abort(vcpu,
+ VMX_ABORT_SAVE_GUEST_MSR_FAIL);
+ }
+-
+- /*
+- * Drop what we picked up for L2 via vmx_complete_interrupts. It is
+- * preserved above and would only end up incorrectly in L1.
+- */
+- vcpu->arch.nmi_injected = false;
+- kvm_clear_exception_queue(vcpu);
+- kvm_clear_interrupt_queue(vcpu);
+ }
+
+ /*
+@@ -4602,6 +4608,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
+ WARN_ON_ONCE(nested_early_check);
+ }
+
++ /*
++ * Drop events/exceptions that were queued for re-injection to L2
++ * (picked up via vmx_complete_interrupts()), as well as exceptions
++ * that were pending for L2. Note, this must NOT be hoisted above
++ * prepare_vmcs12(), events/exceptions queued for re-injection need to
++ * be captured in vmcs12 (see vmcs12_save_pending_event()).
++ */
++ vcpu->arch.nmi_injected = false;
++ kvm_clear_exception_queue(vcpu);
++ kvm_clear_interrupt_queue(vcpu);
++
+ vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+
+ /* Update any VMCS fields that might have changed while L2 ran */
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index c9b49a09e6b53..7f3581960eb5d 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -1695,7 +1695,17 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu)
+ kvm_deliver_exception_payload(vcpu);
+
+ if (has_error_code) {
+- vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
++ /*
++ * Despite the error code being architecturally defined as 32
++ * bits, and the VMCS field being 32 bits, Intel CPUs and thus
++ * VMX don't actually supporting setting bits 31:16. Hardware
++ * will (should) never provide a bogus error code, but AMD CPUs
++ * do generate error codes with bits 31:16 set, and so KVM's
++ * ABI lets userspace shove in arbitrary 32-bit values. Drop
++ * the upper bits to avoid VM-Fail, losing information that
++ * does't really exist is preferable to killing the VM.
++ */
++ vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, (u16)error_code);
+ intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ }
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index b0c47b41c2649..e2435090f2258 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -528,6 +528,7 @@ static int exception_class(int vector)
+ #define EXCPT_TRAP 1
+ #define EXCPT_ABORT 2
+ #define EXCPT_INTERRUPT 3
++#define EXCPT_DB 4
+
+ static int exception_type(int vector)
+ {
+@@ -538,8 +539,14 @@ static int exception_type(int vector)
+
+ mask = 1 << vector;
+
+- /* #DB is trap, as instruction watchpoints are handled elsewhere */
+- if (mask & ((1 << DB_VECTOR) | (1 << BP_VECTOR) | (1 << OF_VECTOR)))
++ /*
++ * #DBs can be trap-like or fault-like, the caller must check other CPU
++ * state, e.g. DR6, to determine whether a #DB is a trap or fault.
++ */
++ if (mask & (1 << DB_VECTOR))
++ return EXCPT_DB;
++
++ if (mask & ((1 << BP_VECTOR) | (1 << OF_VECTOR)))
+ return EXCPT_TRAP;
+
+ if (mask & ((1 << DF_VECTOR) | (1 << MC_VECTOR)))
+@@ -8801,6 +8808,12 @@ writeback:
+ unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ toggle_interruptibility(vcpu, ctxt->interruptibility);
+ vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
++
++ /*
++ * Note, EXCPT_DB is assumed to be fault-like as the emulator
++ * only supports code breakpoints and general detect #DB, both
++ * of which are fault-like.
++ */
+ if (!ctxt->have_exception ||
+ exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
+ kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+@@ -9724,6 +9737,16 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
+
+ /* try to inject new event if pending */
+ if (vcpu->arch.exception.pending) {
++ /*
++ * Fault-class exceptions, except #DBs, set RF=1 in the RFLAGS
++ * value pushed on the stack. Trap-like exception and all #DBs
++ * leave RF as-is (KVM follows Intel's behavior in this regard;
++ * AMD states that code breakpoint #DBs excplitly clear RF=0).
++ *
++ * Note, most versions of Intel's SDM and AMD's APM incorrectly
++ * describe the behavior of General Detect #DBs, which are
++ * fault-like. They do _not_ set RF, a la code breakpoints.
++ */
+ if (exception_type(vcpu->arch.exception.nr) == EXCPT_FAULT)
+ __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) |
+ X86_EFLAGS_RF);
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index c1f6c1c51d998..362562c832e65 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -2209,7 +2209,7 @@ cleanup:
+ return ret;
+ }
+
+-static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
++static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs, u8 *image, u8 *buf)
+ {
+ u8 *jg_reloc, *prog = *pprog;
+ int pivot, err, jg_bytes = 1;
+@@ -2225,12 +2225,12 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ EMIT2_off32(0x81, add_1reg(0xF8, BPF_REG_3),
+ progs[a]);
+ err = emit_cond_near_jump(&prog, /* je func */
+- (void *)progs[a], prog,
++ (void *)progs[a], image + (prog - buf),
+ X86_JE);
+ if (err)
+ return err;
+
+- emit_indirect_jump(&prog, 2 /* rdx */, prog);
++ emit_indirect_jump(&prog, 2 /* rdx */, image + (prog - buf));
+
+ *pprog = prog;
+ return 0;
+@@ -2255,7 +2255,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ jg_reloc = prog;
+
+ err = emit_bpf_dispatcher(&prog, a, a + pivot, /* emit lower_part */
+- progs);
++ progs, image, buf);
+ if (err)
+ return err;
+
+@@ -2269,7 +2269,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ emit_code(jg_reloc - jg_bytes, jg_offset, jg_bytes);
+
+ err = emit_bpf_dispatcher(&prog, a + pivot + 1, /* emit upper_part */
+- b, progs);
++ b, progs, image, buf);
+ if (err)
+ return err;
+
+@@ -2289,12 +2289,12 @@ static int cmp_ips(const void *a, const void *b)
+ return 0;
+ }
+
+-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
++int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
+ {
+- u8 *prog = image;
++ u8 *prog = buf;
+
+ sort(funcs, num_funcs, sizeof(funcs[0]), cmp_ips, NULL);
+- return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs);
++ return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs, image, buf);
+ }
+
+ struct x64_jit_data {
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 0ed2e487a693f..9b1a58dda935b 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc)
+ {
+ static DEFINE_SPINLOCK(lock);
+ static struct trap_info traps[257];
++ static const struct trap_info zero = { };
+ unsigned out;
+
+ trace_xen_cpu_load_idt(desc);
+@@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc)
+ memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc));
+
+ out = xen_convert_trap_info(desc, traps, false);
+- memset(&traps[out], 0, sizeof(traps[0]));
++ traps[out] = zero;
+
+ xen_mc_flush();
+ if (HYPERVISOR_set_trap_table(traps))
+diff --git a/block/bio.c b/block/bio.c
+index 3d3a2678fea25..77e3b764a0784 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -760,8 +760,6 @@ EXPORT_SYMBOL(bio_put);
+ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
+ {
+ bio_set_flag(bio, BIO_CLONED);
+- if (bio_flagged(bio_src, BIO_THROTTLED))
+- bio_set_flag(bio, BIO_THROTTLED);
+ bio->bi_ioprio = bio_src->bi_ioprio;
+ bio->bi_iter = bio_src->bi_iter;
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index c96c8c4f751b3..887b8682eb690 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4473,14 +4473,14 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
+ list_add(&qe->node, head);
+
+ /*
+- * After elevator_switch_mq, the previous elevator_queue will be
++ * After elevator_switch, the previous elevator_queue will be
+ * released by elevator_release. The reference of the io scheduler
+ * module get by elevator_get will also be put. So we need to get
+ * a reference of the io scheduler module here to prevent it to be
+ * removed.
+ */
+ __module_get(qe->type->elevator_owner);
+- elevator_switch_mq(q, NULL);
++ elevator_switch(q, NULL);
+ mutex_unlock(&q->sysfs_lock);
+
+ return true;
+@@ -4512,7 +4512,7 @@ static void blk_mq_elv_switch_back(struct list_head *head,
+ kfree(qe);
+
+ mutex_lock(&q->sysfs_lock);
+- elevator_switch_mq(q, t);
++ elevator_switch(q, t);
+ mutex_unlock(&q->sysfs_lock);
+ }
+
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 9f5fe62afff92..35cf744ea9d11 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -806,12 +806,12 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
+ u64 bps_limit, unsigned long *wait)
+ {
+ bool rw = bio_data_dir(bio);
+- u64 bytes_allowed, extra_bytes, tmp;
++ u64 bytes_allowed, extra_bytes;
+ unsigned long jiffy_elapsed, jiffy_wait, jiffy_elapsed_rnd;
+ unsigned int bio_size = throtl_bio_data_size(bio);
+
+ /* no need to throttle if this bio's bytes have been accounted */
+- if (bps_limit == U64_MAX || bio_flagged(bio, BIO_THROTTLED)) {
++ if (bps_limit == U64_MAX || bio_flagged(bio, BIO_BPS_THROTTLED)) {
+ if (wait)
+ *wait = 0;
+ return true;
+@@ -824,10 +824,8 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
+ jiffy_elapsed_rnd = tg->td->throtl_slice;
+
+ jiffy_elapsed_rnd = roundup(jiffy_elapsed_rnd, tg->td->throtl_slice);
+-
+- tmp = bps_limit * jiffy_elapsed_rnd;
+- do_div(tmp, HZ);
+- bytes_allowed = tmp;
++ bytes_allowed = mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed_rnd,
++ (u64)HZ);
+
+ if (tg->bytes_disp[rw] + bio_size <= bytes_allowed) {
+ if (wait)
+@@ -921,22 +919,13 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
+ unsigned int bio_size = throtl_bio_data_size(bio);
+
+ /* Charge the bio to the group */
+- if (!bio_flagged(bio, BIO_THROTTLED)) {
++ if (!bio_flagged(bio, BIO_BPS_THROTTLED)) {
+ tg->bytes_disp[rw] += bio_size;
+ tg->last_bytes_disp[rw] += bio_size;
+ }
+
+ tg->io_disp[rw]++;
+ tg->last_io_disp[rw]++;
+-
+- /*
+- * BIO_THROTTLED is used to prevent the same bio to be throttled
+- * more than once as a throttled bio will go through blk-throtl the
+- * second time when it eventually gets issued. Set it when a bio
+- * is being charged to a tg.
+- */
+- if (!bio_flagged(bio, BIO_THROTTLED))
+- bio_set_flag(bio, BIO_THROTTLED);
+ }
+
+ /**
+@@ -1026,6 +1015,7 @@ static void tg_dispatch_one_bio(struct throtl_grp *tg, bool rw)
+ sq->nr_queued[rw]--;
+
+ throtl_charge_bio(tg, bio);
++ bio_set_flag(bio, BIO_BPS_THROTTLED);
+
+ /*
+ * If our parent is another tg, we just need to transfer @bio to
+@@ -2159,8 +2149,10 @@ again:
+ qn = &tg->qnode_on_parent[rw];
+ sq = sq->parent_sq;
+ tg = sq_to_tg(sq);
+- if (!tg)
++ if (!tg) {
++ bio_set_flag(bio, BIO_BPS_THROTTLED);
+ goto out_unlock;
++ }
+ }
+
+ /* out-of-limit, queue to @tg */
+@@ -2189,8 +2181,6 @@ again:
+ }
+
+ out_unlock:
+- bio_set_flag(bio, BIO_THROTTLED);
+-
+ #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
+ if (throttled || !td->track_bio_latency)
+ bio->bi_issue.value |= BIO_ISSUE_THROTL_SKIP_LATENCY;
+diff --git a/block/blk-throttle.h b/block/blk-throttle.h
+index c1b6029961272..ee7299e6dea91 100644
+--- a/block/blk-throttle.h
++++ b/block/blk-throttle.h
+@@ -175,7 +175,7 @@ static inline bool blk_throtl_bio(struct bio *bio)
+ struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg);
+
+ /* no need to throttle bps any more if the bio has been throttled */
+- if (bio_flagged(bio, BIO_THROTTLED) &&
++ if (bio_flagged(bio, BIO_BPS_THROTTLED) &&
+ !(tg->flags & THROTL_TG_HAS_IOPS_LIMIT))
+ return false;
+
+diff --git a/block/blk-wbt.c b/block/blk-wbt.c
+index a9982000b667e..c293e08b301ff 100644
+--- a/block/blk-wbt.c
++++ b/block/blk-wbt.c
+@@ -841,8 +841,11 @@ int wbt_init(struct request_queue *q)
+ rwb->last_comp = rwb->last_issue = jiffies;
+ rwb->win_nsec = RWB_WINDOW_NSEC;
+ rwb->enable_state = WBT_STATE_ON_DEFAULT;
+- rwb->wc = 1;
++ rwb->wc = test_bit(QUEUE_FLAG_WC, &q->queue_flags);
+ rwb->rq_depth.default_depth = RWB_DEF_DEPTH;
++ rwb->min_lat_nsec = wbt_default_latency_nsec(q);
++
++ wbt_queue_depth_changed(&rwb->rqos);
+
+ /*
+ * Assign rwb and add the stats callback.
+@@ -853,11 +856,6 @@ int wbt_init(struct request_queue *q)
+
+ blk_stat_add_callback(q, rwb->cb);
+
+- rwb->min_lat_nsec = wbt_default_latency_nsec(q);
+-
+- wbt_queue_depth_changed(&rwb->rqos);
+- wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags));
+-
+ return 0;
+
+ err_free:
+diff --git a/block/blk.h b/block/blk.h
+index d7142c4d2fefb..52432eab621e5 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -270,8 +270,7 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list,
+
+ void blk_insert_flush(struct request *rq);
+
+-int elevator_switch_mq(struct request_queue *q,
+- struct elevator_type *new_e);
++int elevator_switch(struct request_queue *q, struct elevator_type *new_e);
+ void elevator_exit(struct request_queue *q);
+ int elv_register_queue(struct request_queue *q, bool uevent);
+ void elv_unregister_queue(struct request_queue *q);
+diff --git a/block/elevator.c b/block/elevator.c
+index c319765892bb9..bd71f0fc4e4b6 100644
+--- a/block/elevator.c
++++ b/block/elevator.c
+@@ -588,7 +588,7 @@ void elv_unregister(struct elevator_type *e)
+ }
+ EXPORT_SYMBOL_GPL(elv_unregister);
+
+-int elevator_switch_mq(struct request_queue *q,
++static int elevator_switch_mq(struct request_queue *q,
+ struct elevator_type *new_e)
+ {
+ int ret;
+@@ -723,7 +723,7 @@ void elevator_init_mq(struct request_queue *q)
+ * need for the new one. this way we have a chance of going back to the old
+ * one, if the new one fails init for some reason.
+ */
+-static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
++int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
+ {
+ int err;
+
+diff --git a/crypto/akcipher.c b/crypto/akcipher.c
+index f866085c8a4a3..ab975a420e1e9 100644
+--- a/crypto/akcipher.c
++++ b/crypto/akcipher.c
+@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)
+ return -ENOSYS;
+ }
+
++static int akcipher_default_set_key(struct crypto_akcipher *tfm,
++ const void *key, unsigned int keylen)
++{
++ return -ENOSYS;
++}
++
+ int crypto_register_akcipher(struct akcipher_alg *alg)
+ {
+ struct crypto_alg *base = &alg->base;
+@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
+ alg->encrypt = akcipher_default_op;
+ if (!alg->decrypt)
+ alg->decrypt = akcipher_default_op;
++ if (!alg->set_priv_key)
++ alg->set_priv_key = akcipher_default_set_key;
+
+ akcipher_prepare_alg(alg);
+ return crypto_register_alg(base);
+diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c
+index 6922a44b3ce70..a2056c4c8cb70 100644
+--- a/drivers/acpi/acpi_fpdt.c
++++ b/drivers/acpi/acpi_fpdt.c
+@@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {
+
+ static struct kobject *fpdt_kobj;
+
++#if defined CONFIG_X86 && defined CONFIG_PHYS_ADDR_T_64BIT
++#include <linux/processor.h>
++static bool fpdt_address_valid(u64 address)
++{
++ /*
++ * On some systems the table contains invalid addresses
++ * with unsuppored high address bits set, check for this.
++ */
++ return !(address >> boot_cpu_data.x86_phys_bits);
++}
++#else
++static bool fpdt_address_valid(u64 address)
++{
++ return true;
++}
++#endif
++
+ static int fpdt_process_subtable(u64 address, u32 subtable_type)
+ {
+ struct fpdt_subtable_header *subtable_header;
+@@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
+ u32 length, offset;
+ int result;
+
++ if (!fpdt_address_valid(address)) {
++ pr_info(FW_BUG "invalid physical address: 0x%llx!\n", address);
++ return -EINVAL;
++ }
++
+ subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header));
+ if (!subtable_header)
+ return -ENOMEM;
+diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c
+index a12b55d812096..ee4ce5ba1fb24 100644
+--- a/drivers/acpi/acpi_pcc.c
++++ b/drivers/acpi/acpi_pcc.c
+@@ -23,6 +23,12 @@
+
+ #include <acpi/pcc.h>
+
++/*
++ * Arbitrary retries in case the remote processor is slow to respond
++ * to PCC commands
++ */
++#define PCC_CMD_WAIT_RETRIES_NUM 500
++
+ struct pcc_data {
+ struct pcc_mbox_chan *pcc_chan;
+ void __iomem *pcc_comm_addr;
+@@ -63,6 +69,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
+ if (IS_ERR(data->pcc_chan)) {
+ pr_err("Failed to find PCC channel for subspace %d\n",
+ ctx->subspace_id);
++ kfree(data);
+ return AE_NOT_FOUND;
+ }
+
+@@ -72,6 +79,8 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
+ if (!data->pcc_comm_addr) {
+ pr_err("Failed to ioremap PCC comm region mem for %d\n",
+ ctx->subspace_id);
++ pcc_mbox_free_channel(data->pcc_chan);
++ kfree(data);
+ return AE_NO_MEMORY;
+ }
+
+@@ -86,6 +95,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
+ {
+ int ret;
+ struct pcc_data *data = region_context;
++ u64 usecs_lat;
+
+ reinit_completion(&data->done);
+
+@@ -96,10 +106,22 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
+ if (ret < 0)
+ return AE_ERROR;
+
+- if (data->pcc_chan->mchan->mbox->txdone_irq)
+- wait_for_completion(&data->done);
++ if (data->pcc_chan->mchan->mbox->txdone_irq) {
++ /*
++ * pcc_chan->latency is just a Nominal value. In reality the remote
++ * processor could be much slower to reply. So add an arbitrary
++ * amount of wait on top of Nominal.
++ */
++ usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
++ ret = wait_for_completion_timeout(&data->done,
++ usecs_to_jiffies(usecs_lat));
++ if (ret == 0) {
++ pr_err("PCC command executed timeout!\n");
++ return AE_TIME;
++ }
++ }
+
+- mbox_client_txdone(data->pcc_chan->mchan, ret);
++ mbox_chan_txdone(data->pcc_chan->mchan, ret);
+
+ memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);
+
+diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
+index 5cbe2196176db..2a4990733cf02 100644
+--- a/drivers/acpi/acpi_video.c
++++ b/drivers/acpi/acpi_video.c
+@@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
+ },
+ },
++ {
++ .callback = video_disable_backlight_sysfs_if,
++ .ident = "Toshiba Satellite Z830",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"),
++ },
++ },
++ {
++ .callback = video_disable_backlight_sysfs_if,
++ .ident = "Toshiba Portege Z830",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"),
++ },
++ },
+ /*
+ * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
+ * but the IDs actually follow the Device ID Scheme.
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index d91ad378c00d6..80ad530583c9c 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
+ ghes_estatus_cache_add(generic, estatus);
+ }
+
+- if (task_work_pending && current->mm != &init_mm) {
++ if (task_work_pending && current->mm) {
+ estatus_node->task_work.func = ghes_kick_task_work;
+ estatus_node->task_work_cpu = smp_processor_id();
+ ret = task_work_add(current, &estatus_node->task_work,
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index 664070fc83498..d7cdd8406c84f 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = {
+ {}
+ };
+
++static const struct dmi_system_id force_storage_d3_dmi[] = {
++ {
++ /*
++ * _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME
++ * but .NVME is needed to get StorageD3Enable node
++ * https://bugzilla.kernel.org/show_bug.cgi?id=216440
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
++ }
++ },
++ {}
++};
++
+ bool force_storage_d3(void)
+ {
+- return x86_match_cpu(storage_d3_cpu_ids);
++ const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi);
++
++ return dmi_id || x86_match_cpu(storage_d3_cpu_ids);
+ }
+
+ /*
+diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
+index 32495ae96567a..986f1923a76da 100644
+--- a/drivers/ata/libahci_platform.c
++++ b/drivers/ata/libahci_platform.c
+@@ -451,14 +451,24 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
+ }
+ }
+
+- hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
++ /*
++ * Too many sub-nodes most likely means having something wrong with
++ * the firmware.
++ */
++ child_nodes = of_get_child_count(dev->of_node);
++ if (child_nodes > AHCI_MAX_PORTS) {
++ rc = -EINVAL;
++ goto err_out;
++ }
+
+ /*
+ * If no sub-node was found, we still need to set nports to
+ * one in order to be able to use the
+ * ahci_platform_[en|dis]able_[phys|regulators] functions.
+ */
+- if (!child_nodes)
++ if (child_nodes)
++ hpriv->nports = child_nodes;
++ else
+ hpriv->nports = 1;
+
+ hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
+diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
+index 46cbe4471e785..d07a7cfa389a1 100644
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -841,4 +841,23 @@ void __init init_cpu_topology(void)
+ return;
+ }
+ }
++
++void store_cpu_topology(unsigned int cpuid)
++{
++ struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
++
++ if (cpuid_topo->package_id != -1)
++ goto topology_populated;
++
++ cpuid_topo->thread_id = -1;
++ cpuid_topo->core_id = cpuid;
++ cpuid_topo->package_id = cpu_to_node(cpuid);
++
++ pr_debug("CPU%u: package %d core %d thread %d\n",
++ cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
++ cpuid_topo->thread_id);
++
++topology_populated:
++ update_siblings_masks(cpuid);
++}
+ #endif
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 2a709daefbc46..2a2a1d996a57a 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -1413,10 +1413,12 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd)
+ mutex_unlock(&nbd->config_lock);
+ ret = wait_event_interruptible(config->recv_wq,
+ atomic_read(&config->recv_threads) == 0);
+- if (ret)
++ if (ret) {
+ sock_shutdown(nbd);
+- flush_workqueue(nbd->recv_workq);
++ nbd_clear_que(nbd);
++ }
+
++ flush_workqueue(nbd->recv_workq);
+ mutex_lock(&nbd->config_lock);
+ nbd_bdev_reset(nbd);
+ /* user requested, ignore socket errors */
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index 818681c89db8b..d44a966675179 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2439,15 +2439,20 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+ &hdev->quirks);
++ if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
++ set_bit(HCI_QUIRK_VALID_LE_STATES,
++ &hdev->quirks);
+
+ err = btintel_legacy_rom_setup(hdev, &ver);
+ break;
+ case 0x0b: /* SfP */
+- case 0x0c: /* WsP */
+ case 0x11: /* JfP */
+ case 0x12: /* ThP */
+ case 0x13: /* HrP */
+ case 0x14: /* CcP */
++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
++ fallthrough;
++ case 0x0c: /* WsP */
+ /* Apply the device specific HCI quirks
+ *
+ * All Legacy bootloader devices support WBS
+@@ -2455,11 +2460,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+ &hdev->quirks);
+
+- /* Valid LE States quirk for JfP/ThP familiy */
+- if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12)
+- set_bit(HCI_QUIRK_VALID_LE_STATES,
+- &hdev->quirks);
+-
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev, ver.hw_variant);
+
+@@ -2530,9 +2530,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ */
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+
+- /* Valid LE States quirk for JfP/ThP familiy */
+- if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12)
+- set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
++ /* Set Valid LE States quirk */
++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev, ver.hw_variant);
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 15caa64695389..1bb46cbff0fac 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2477,15 +2477,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
+
+ set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
+
++ /* WMT cmd/event doesn't follow up the generic HCI cmd/event handling,
++ * it needs constantly polling control pipe until the host received the
++ * WMT event, thus, we should require to specifically acquire PM counter
++ * on the USB to prevent the interface from entering auto suspended
++ * while WMT cmd/event in progress.
++ */
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ goto err_free_wc;
++
+ err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
+
+ if (err < 0) {
+ clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
++ usb_autopm_put_interface(data->intf);
+ goto err_free_wc;
+ }
+
+ /* Submit control IN URB on demand to process the WMT event */
+ err = btusb_mtk_submit_wmt_recv_urb(hdev);
++
++ usb_autopm_put_interface(data->intf);
++
+ if (err < 0)
+ goto err_free_wc;
+
+diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
+index f537673ede174..865112e96ff9f 100644
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)
+ BT_ERR("Can't allocate control structure");
+ return -ENFILE;
+ }
++ if (percpu_init_rwsem(&hu->proto_lock)) {
++ BT_ERR("Can't allocate semaphore structure");
++ kfree(hu);
++ return -ENOMEM;
++ }
+
+ tty->disc_data = hu;
+ hu->tty = tty;
+@@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)
+ INIT_WORK(&hu->init_ready, hci_uart_init_work);
+ INIT_WORK(&hu->write_work, hci_uart_write_work);
+
+- percpu_init_rwsem(&hu->proto_lock);
+-
+ /* Flush any pending characters in the driver */
+ tty_driver_flush_buffer(tty);
+
+diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
+index c0e5f42ec6b7d..f16fd79bc02b8 100644
+--- a/drivers/bluetooth/hci_serdev.c
++++ b/drivers/bluetooth/hci_serdev.c
+@@ -310,11 +310,12 @@ int hci_uart_register_device(struct hci_uart *hu,
+
+ serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops);
+
++ if (percpu_init_rwsem(&hu->proto_lock))
++ return -ENOMEM;
++
+ err = serdev_device_open(hu->serdev);
+ if (err)
+- return err;
+-
+- percpu_init_rwsem(&hu->proto_lock);
++ goto err_rwsem;
+
+ err = p->open(hu);
+ if (err)
+@@ -389,6 +390,8 @@ err_alloc:
+ p->close(hu);
+ err_open:
+ serdev_device_close(hu->serdev);
++err_rwsem:
++ percpu_free_rwsem(&hu->proto_lock);
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(hci_uart_register_device);
+@@ -410,5 +413,6 @@ void hci_uart_unregister_device(struct hci_uart *hu)
+ clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ serdev_device_close(hu->serdev);
+ }
++ percpu_free_rwsem(&hu->proto_lock);
+ }
+ EXPORT_SYMBOL_GPL(hci_uart_unregister_device);
+diff --git a/drivers/char/hw_random/arm_smccc_trng.c b/drivers/char/hw_random/arm_smccc_trng.c
+index b24ac39a903b3..e34c3ea692b6c 100644
+--- a/drivers/char/hw_random/arm_smccc_trng.c
++++ b/drivers/char/hw_random/arm_smccc_trng.c
+@@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ MAX_BITS_PER_CALL);
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND, bits, &res);
+- if ((int)res.a0 < 0)
+- return (int)res.a0;
+
+ switch ((int)res.a0) {
+ case SMCCC_RET_SUCCESS:
+@@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ return copied;
+ cond_resched();
+ break;
++ default:
++ return -EIO;
+ }
+ }
+
+diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
+index 16f227b995e8a..d7045dfaf16cf 100644
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -507,16 +507,17 @@ static int hwrng_fillfn(void *unused)
+ rng->quality = current_quality; /* obsolete */
+ quality = rng->quality;
+ mutex_unlock(&reading_mutex);
++
++ if (rc <= 0)
++ hwrng_msleep(rng, 10000);
++
+ put_rng(rng);
+
+ if (!quality)
+ break;
+
+- if (rc <= 0) {
+- pr_warn("hwrng: no data available\n");
+- msleep_interruptible(10000);
++ if (rc <= 0)
+ continue;
+- }
+
+ /* If we cannot credit at least one bit of entropy,
+ * keep track of the remainder for the next iteration
+@@ -570,6 +571,7 @@ int hwrng_register(struct hwrng *rng)
+
+ init_completion(&rng->cleanup_done);
+ complete(&rng->cleanup_done);
++ init_completion(&rng->dying);
+
+ if (!current_rng ||
+ (!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
+@@ -617,6 +619,7 @@ void hwrng_unregister(struct hwrng *rng)
+
+ old_rng = current_rng;
+ list_del(&rng->list);
++ complete_all(&rng->dying);
+ if (current_rng == rng) {
+ err = enable_best_rng();
+ if (err) {
+@@ -685,6 +688,14 @@ void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
+ }
+ EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
+
++long hwrng_msleep(struct hwrng *rng, unsigned int msecs)
++{
++ unsigned long timeout = msecs_to_jiffies(msecs) + 1;
++
++ return wait_for_completion_interruptible_timeout(&rng->dying, timeout);
++}
++EXPORT_SYMBOL_GPL(hwrng_msleep);
++
+ static int __init hwrng_modinit(void)
+ {
+ int ret;
+diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c
+index b05d676ca814c..1d7ce7443586e 100644
+--- a/drivers/char/hw_random/imx-rngc.c
++++ b/drivers/char/hw_random/imx-rngc.c
+@@ -245,7 +245,7 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ if (IS_ERR(rngc->base))
+ return PTR_ERR(rngc->base);
+
+- rngc->clk = devm_clk_get(&pdev->dev, NULL);
++ rngc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(rngc->clk)) {
+ dev_err(&pdev->dev, "Can not get rng_clk\n");
+ return PTR_ERR(rngc->clk);
+@@ -255,27 +255,14 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ if (irq < 0)
+ return irq;
+
+- ret = clk_prepare_enable(rngc->clk);
+- if (ret)
+- return ret;
+-
+ ver_id = readl(rngc->base + RNGC_VER_ID);
+ rng_type = ver_id >> RNGC_TYPE_SHIFT;
+ /*
+ * This driver supports only RNGC and RNGB. (There's a different
+ * driver for RNGA.)
+ */
+- if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) {
+- ret = -ENODEV;
+- goto err;
+- }
+-
+- ret = devm_request_irq(&pdev->dev,
+- irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
+- if (ret) {
+- dev_err(rngc->dev, "Can't get interrupt working.\n");
+- goto err;
+- }
++ if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB)
++ return -ENODEV;
+
+ init_completion(&rngc->rng_op_done);
+
+@@ -290,18 +277,25 @@ static int imx_rngc_probe(struct platform_device *pdev)
+
+ imx_rngc_irq_mask_clear(rngc);
+
++ ret = devm_request_irq(&pdev->dev,
++ irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
++ if (ret) {
++ dev_err(rngc->dev, "Can't get interrupt working.\n");
++ return ret;
++ }
++
+ if (self_test) {
+ ret = imx_rngc_self_test(rngc);
+ if (ret) {
+ dev_err(rngc->dev, "self test failed\n");
+- goto err;
++ return ret;
+ }
+ }
+
+ ret = hwrng_register(&rngc->rng);
+ if (ret) {
+ dev_err(&pdev->dev, "hwrng registration failed\n");
+- goto err;
++ return ret;
+ }
+
+ dev_info(&pdev->dev,
+@@ -309,11 +303,6 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ rng_type == RNGC_TYPE_RNGB ? 'B' : 'C',
+ (ver_id >> RNGC_VER_MAJ_SHIFT) & 0xff, ver_id & 0xff);
+ return 0;
+-
+-err:
+- clk_disable_unprepare(rngc->clk);
+-
+- return ret;
+ }
+
+ static int __exit imx_rngc_remove(struct platform_device *pdev)
+@@ -322,8 +311,6 @@ static int __exit imx_rngc_remove(struct platform_device *pdev)
+
+ hwrng_unregister(&rngc->rng);
+
+- clk_disable_unprepare(rngc->clk);
+-
+ return 0;
+ }
+
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 060f999dcffb3..46d6100fa3a7f 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1195,7 +1195,7 @@ static void __cold entropy_timer(struct timer_list *timer)
+ */
+ static void __cold try_to_generate_entropy(void)
+ {
+- enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 30 };
++ enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 15 };
+ struct entropy_timer_state stack;
+ unsigned int i, num_different = 0;
+ unsigned long last = random_get_entropy();
+@@ -1214,7 +1214,7 @@ static void __cold try_to_generate_entropy(void)
+ timer_setup_on_stack(&stack.timer, entropy_timer, 0);
+ while (!crng_ready() && !signal_pending(current)) {
+ if (!timer_pending(&stack.timer))
+- mod_timer(&stack.timer, jiffies + 1);
++ mod_timer(&stack.timer, jiffies);
+ mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
+ schedule();
+ stack.entropy = random_get_entropy();
+diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c
+index 4062092d67f90..a6642f3d33d44 100644
+--- a/drivers/clk/baikal-t1/ccu-div.c
++++ b/drivers/clk/baikal-t1/ccu-div.c
+@@ -34,6 +34,7 @@
+ #define CCU_DIV_CTL_CLKDIV_MASK(_width) \
+ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
+ #define CCU_DIV_CTL_LOCK_SHIFTED BIT(27)
++#define CCU_DIV_CTL_GATE_REF_BUF BIT(28)
+ #define CCU_DIV_CTL_LOCK_NORMAL BIT(31)
+
+ #define CCU_DIV_RST_DELAY_US 1
+@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)
+ return !!(val & CCU_DIV_CTL_EN);
+ }
+
++static int ccu_div_buf_enable(struct clk_hw *hw)
++{
++ struct ccu_div *div = to_ccu_div(hw);
++ unsigned long flags;
++
++ spin_lock_irqsave(&div->lock, flags);
++ regmap_update_bits(div->sys_regs, div->reg_ctl,
++ CCU_DIV_CTL_GATE_REF_BUF, 0);
++ spin_unlock_irqrestore(&div->lock, flags);
++
++ return 0;
++}
++
++static void ccu_div_buf_disable(struct clk_hw *hw)
++{
++ struct ccu_div *div = to_ccu_div(hw);
++ unsigned long flags;
++
++ spin_lock_irqsave(&div->lock, flags);
++ regmap_update_bits(div->sys_regs, div->reg_ctl,
++ CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF);
++ spin_unlock_irqrestore(&div->lock, flags);
++}
++
++static int ccu_div_buf_is_enabled(struct clk_hw *hw)
++{
++ struct ccu_div *div = to_ccu_div(hw);
++ u32 val = 0;
++
++ regmap_read(div->sys_regs, div->reg_ctl, &val);
++
++ return !(val & CCU_DIV_CTL_GATE_REF_BUF);
++}
++
+ static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
+ CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
+ CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
+ CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
++ CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF),
+ CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
+ };
+
+@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ continue;
+ }
+
++ if (!strcmp("div_buf", name))
++ continue;
++
+ bits[didx] = ccu_div_bits[bidx];
+ bits[didx].div = div;
+
+@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ &ccu_div_dbgfs_fixed_clkdiv_fops);
+ }
+
++static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry)
++{
++ struct ccu_div *div = to_ccu_div(hw);
++ struct ccu_div_dbgfs_bit *bit;
++
++ bit = kmalloc(sizeof(*bit), GFP_KERNEL);
++ if (!bit)
++ return;
++
++ *bit = ccu_div_bits[3];
++ bit->div = div;
++ debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
++ &ccu_div_dbgfs_bit_fops);
++}
++
+ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ {
+ struct ccu_div *div = to_ccu_div(hw);
+@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
+
+ #define ccu_div_var_debug_init NULL
+ #define ccu_div_gate_debug_init NULL
++#define ccu_div_buf_debug_init NULL
+ #define ccu_div_fixed_debug_init NULL
+
+ #endif /* !CONFIG_DEBUG_FS */
+@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = {
+ .debug_init = ccu_div_gate_debug_init
+ };
+
++static const struct clk_ops ccu_div_buf_ops = {
++ .enable = ccu_div_buf_enable,
++ .disable = ccu_div_buf_disable,
++ .is_enabled = ccu_div_buf_is_enabled,
++ .debug_init = ccu_div_buf_debug_init
++};
++
+ static const struct clk_ops ccu_div_fixed_ops = {
+ .recalc_rate = ccu_div_fixed_recalc_rate,
+ .round_rate = ccu_div_fixed_round_rate,
+@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
+ } else if (div_init->type == CCU_DIV_GATE) {
+ hw_init.ops = &ccu_div_gate_ops;
+ div->divider = div_init->divider;
++ } else if (div_init->type == CCU_DIV_BUF) {
++ hw_init.ops = &ccu_div_buf_ops;
+ } else if (div_init->type == CCU_DIV_FIXED) {
+ hw_init.ops = &ccu_div_fixed_ops;
+ div->divider = div_init->divider;
+@@ -579,6 +643,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
+ goto err_free_div;
+ }
+ parent_data.fw_name = div_init->parent_name;
++ parent_data.name = div_init->parent_name;
+ hw_init.parent_data = &parent_data;
+ hw_init.num_parents = 1;
+
+diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h
+index 795665caefbdc..4eb49ff4803c6 100644
+--- a/drivers/clk/baikal-t1/ccu-div.h
++++ b/drivers/clk/baikal-t1/ccu-div.h
+@@ -13,6 +13,14 @@
+ #include <linux/bits.h>
+ #include <linux/of.h>
+
++/*
++ * CCU Divider private clock IDs
++ * @CCU_SYS_SATA_CLK: CCU SATA internal clock
++ * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
++ */
++#define CCU_SYS_SATA_CLK -1
++#define CCU_SYS_XGMAC_CLK -2
++
+ /*
+ * CCU Divider private flags
+ * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
+@@ -31,11 +39,13 @@
+ * enum ccu_div_type - CCU Divider types
+ * @CCU_DIV_VAR: Clocks gate with variable divider.
+ * @CCU_DIV_GATE: Clocks gate with fixed divider.
++ * @CCU_DIV_BUF: Clock gate with no divider.
+ * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
+ */
+ enum ccu_div_type {
+ CCU_DIV_VAR,
+ CCU_DIV_GATE,
++ CCU_DIV_BUF,
+ CCU_DIV_FIXED
+ };
+
+diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c
+index f141fda12b09a..90f4fda406ee6 100644
+--- a/drivers/clk/baikal-t1/clk-ccu-div.c
++++ b/drivers/clk/baikal-t1/clk-ccu-div.c
+@@ -76,6 +76,16 @@
+ .divider = _divider \
+ }
+
++#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags) \
++ { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _pname, \
++ .base = _base, \
++ .type = CCU_DIV_BUF, \
++ .flags = _flags \
++ }
++
+ #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \
+ { \
+ .id = _id, \
+@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = {
+ * for the SoC devices registers IO-operations.
+ */
+ static const struct ccu_div_info sys_info[] = {
+- CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
++ CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk",
+ "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
+ CLK_SET_RATE_GATE,
+ CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
+ CCU_DIV_RESET_DOMAIN),
++ CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
++ "sys_sata_clk", CCU_SYS_SATA_REF_BASE,
++ CLK_SET_RATE_PARENT),
+ CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
+ "pcie_clk", CCU_SYS_APB_BASE, 5,
+ CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
+@@ -204,10 +217,12 @@ static const struct ccu_div_info sys_info[] = {
+ "eth_clk", CCU_SYS_GMAC1_BASE, 5),
+ CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
+ "eth_clk", 10),
+- CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
+- "eth_clk", CCU_SYS_XGMAC_BASE, 8),
++ CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk",
++ "eth_clk", CCU_SYS_XGMAC_BASE, 1),
++ CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
++ "sys_xgmac_clk", 8),
+ CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
+- "eth_clk", 10),
++ "sys_xgmac_clk", 8),
+ CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
+ "eth_clk", CCU_SYS_USB_BASE, 10),
+ CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
+@@ -396,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data)
+ init.base = info->base;
+ init.sys_regs = data->sys_regs;
+ init.divider = info->divider;
++ } else if (init.type == CCU_DIV_BUF) {
++ init.base = info->base;
++ init.sys_regs = data->sys_regs;
+ } else {
+ init.divider = info->divider;
+ }
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 48a1eb9f2d551..e74fe6219d14e 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -30,6 +30,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
++#include <linux/math.h>
+ #include <linux/module.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+@@ -502,6 +503,8 @@ struct bcm2835_clock_data {
+ bool low_jitter;
+
+ u32 tcnt_mux;
++
++ bool round_up;
+ };
+
+ struct bcm2835_gate_data {
+@@ -966,9 +969,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+ return div;
+ }
+
+-static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
+- unsigned long parent_rate,
+- u32 div)
++static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
++ unsigned long parent_rate,
++ u32 div)
+ {
+ const struct bcm2835_clock_data *data = clock->data;
+ u64 temp;
+@@ -993,12 +996,34 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
+ return temp;
+ }
+
++static unsigned long bcm2835_round_rate(unsigned long rate)
++{
++ unsigned long scaler;
++ unsigned long limit;
++
++ limit = rate / 100000;
++
++ scaler = 1;
++ while (scaler < limit)
++ scaler *= 10;
++
++ /*
++ * If increasing a clock by less than 0.1% changes it
++ * from ..999.. to ..000.., round up.
++ */
++ if ((rate + scaler - 1) / scaler % 1000 == 0)
++ rate = roundup(rate, scaler);
++
++ return rate;
++}
++
+ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct bcm2835_cprman *cprman = clock->cprman;
+ const struct bcm2835_clock_data *data = clock->data;
++ unsigned long rate;
+ u32 div;
+
+ if (data->int_bits == 0 && data->frac_bits == 0)
+@@ -1006,7 +1031,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+
+ div = cprman_read(cprman, data->div_reg);
+
+- return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
++ rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
++
++ if (data->round_up)
++ rate = bcm2835_round_rate(rate);
++
++ return rate;
+ }
+
+ static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
+@@ -1784,7 +1814,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
+ .load_mask = CM_PLLC_LOADPER,
+ .hold_mask = CM_PLLC_HOLDPER,
+ .fixed_divider = 1,
+- .flags = CLK_SET_RATE_PARENT),
++ .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+
+ /*
+ * PLLD is the display PLL, used to drive DSI display panels.
+@@ -2143,7 +2173,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
+ .div_reg = CM_UARTDIV,
+ .int_bits = 10,
+ .frac_bits = 12,
+- .tcnt_mux = 28),
++ .tcnt_mux = 28,
++ .round_up = true),
+
+ /* TV encoder clock. Only operating frequency is 108Mhz. */
+ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
+diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
+index bccdfa00fd373..67a9edbba29c4 100644
+--- a/drivers/clk/berlin/bg2.c
++++ b/drivers/clk/berlin/bg2.c
+@@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np)
+ int n, ret;
+
+ clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
+- if (!clk_data)
++ if (!clk_data) {
++ of_node_put(parent_np);
+ return;
++ }
+ clk_data->num = MAX_CLKS;
+ hws = clk_data->hws;
+
+ gbase = of_iomap(parent_np, 0);
++ of_node_put(parent_np);
+ if (!gbase)
+ return;
+
+diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
+index e9518d35f262e..dd2784bb75b64 100644
+--- a/drivers/clk/berlin/bg2q.c
++++ b/drivers/clk/berlin/bg2q.c
+@@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np)
+ int n, ret;
+
+ clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
+- if (!clk_data)
++ if (!clk_data) {
++ of_node_put(parent_np);
+ return;
++ }
+ clk_data->num = MAX_CLKS;
+ hws = clk_data->hws;
+
+ gbase = of_iomap(parent_np, 0);
+ if (!gbase) {
++ of_node_put(parent_np);
+ pr_err("%pOF: Unable to map global base\n", np);
+ return;
+ }
+
+ /* BG2Q CPU PLL is not part of global registers */
+ cpupll_base = of_iomap(parent_np, 1);
++ of_node_put(parent_np);
+ if (!cpupll_base) {
+ pr_err("%pOF: Unable to map cpupll base\n", np);
+ iounmap(gbase);
+diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
+index 24dab2312bc6f..9c3305bcb27ae 100644
+--- a/drivers/clk/clk-ast2600.c
++++ b/drivers/clk/clk-ast2600.c
+@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
+ regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */
+
+ /* P-Bus (BCLK) clock divider */
+- hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
++ hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0,
+ scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,
+ ast2600_div_table,
+ &aspeed_g6_clk_lock);
+diff --git a/drivers/clk/clk-oxnas.c b/drivers/clk/clk-oxnas.c
+index cda5e258355bc..584e293156ad6 100644
+--- a/drivers/clk/clk-oxnas.c
++++ b/drivers/clk/clk-oxnas.c
+@@ -207,7 +207,7 @@ static const struct of_device_id oxnas_stdclk_dt_ids[] = {
+
+ static int oxnas_stdclk_probe(struct platform_device *pdev)
+ {
+- struct device_node *np = pdev->dev.of_node;
++ struct device_node *np = pdev->dev.of_node, *parent_np;
+ const struct oxnas_stdclk_data *data;
+ struct regmap *regmap;
+ int ret;
+@@ -215,7 +215,9 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)
+
+ data = of_device_get_match_data(&pdev->dev);
+
+- regmap = syscon_node_to_regmap(of_get_parent(np));
++ parent_np = of_get_parent(np);
++ regmap = syscon_node_to_regmap(parent_np);
++ of_node_put(parent_np);
+ if (IS_ERR(regmap)) {
+ dev_err(&pdev->dev, "failed to have parent regmap\n");
+ return PTR_ERR(regmap);
+diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
+index 88898b97a4431..5eddb9f0d6bdb 100644
+--- a/drivers/clk/clk-qoriq.c
++++ b/drivers/clk/clk-qoriq.c
+@@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy);
+ */
+ static void __init legacy_init_clockgen(struct device_node *np)
+ {
+- if (!clockgen.node)
+- _clockgen_init(of_get_parent(np), true);
++ if (!clockgen.node) {
++ struct device_node *parent_np;
++
++ parent_np = of_get_parent(np);
++ _clockgen_init(parent_np, true);
++ of_node_put(parent_np);
++ }
+ }
+
+ /* Legacy node */
+@@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name)
+ sysclk = of_get_child_by_name(clockgen.node, "sysclk");
+ if (sysclk) {
+ clk = sysclk_from_fixed(sysclk, name);
++ of_node_put(sysclk);
+ if (!IS_ERR(clk))
+ return clk;
+ }
+diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
+index e7be3e54b9be4..03cfef494b49b 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = {
+ .model = IDT_VC6_5P49V6901,
+ .clk_fod_cnt = 4,
+ .clk_out_cnt = 5,
+- .flags = VC5_HAS_PFD_FREQ_DBL,
++ .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
+ };
+
+ static const struct vc5_chip_info idt_5p49v6965_info = {
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index e89db568f5a89..652ae58c2735f 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -665,8 +665,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
+ hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
+ hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
+- hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
+ hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
++ hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
+ hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
+ hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
+ hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
+diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
+index c56e406138dbe..1e6870f3671f6 100644
+--- a/drivers/clk/imx/clk-scu.c
++++ b/drivers/clk/imx/clk-scu.c
+@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
+ pr_warn("%s: failed to attached the power domain %d\n",
+ name, ret);
+
+- platform_device_add(pdev);
++ ret = platform_device_add(pdev);
++ if (ret) {
++ platform_device_put(pdev);
++ return ERR_PTR(ret);
++ }
+
+ /* For API backwards compatiblilty, simply return NULL for success */
+ return NULL;
+diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
+index d774edaf760be..230299728859c 100644
+--- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
++++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
+@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_MFG(_id, _name, _parent, _shift) \
+- GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \
+- &mtk_clk_gate_ops_setclr)
++#define GATE_MFG(_id, _name, _parent, _shift) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)
+
+ static const struct mtk_gate mfg_clks[] = {
+ GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0)
+diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
+index 97657f255618c..832160c929961 100644
+--- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c
++++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
+@@ -55,8 +55,12 @@ static const struct mtk_gate_regs infra_ao4_cg_regs = {
+ #define GATE_INFRA_AO1(_id, _name, _parent, _shift) \
+ GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
+
++#define GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, _flag) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao2_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, _flag)
++
+ #define GATE_INFRA_AO2(_id, _name, _parent, _shift) \
+- GATE_MTK(_id, _name, _parent, &infra_ao2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++ GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, 0)
+
+ #define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag) \
+ GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift, \
+@@ -136,8 +140,11 @@ static const struct mtk_gate infra_ao_clks[] = {
+ GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_SYS, "infra_ao_unipro_sys", "top_ufs", 11),
+ GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_TICK, "infra_ao_unipro_tick", "top_ufs_tick1us", 12),
+ GATE_INFRA_AO2(CLK_INFRA_AO_UFS_MP_SAP_B, "infra_ao_ufs_mp_sap_b", "top_ufs_mp_sap_cfg", 13),
+- GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15),
+- GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17),
++ /* pwrmcu is used by ATF for platform PM: clocks must never be disabled by the kernel */
++ GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15,
++ CLK_IS_CRITICAL),
++ GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17,
++ CLK_IS_CRITICAL),
+ GATE_INFRA_AO2(CLK_INFRA_AO_APDMA_B, "infra_ao_apdma_b", "top_axi", 18),
+ GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
+ GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
+diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
+index 9411c556a5a97..c94cb71bd9b94 100644
+--- a/drivers/clk/mediatek/clk-mt8195-mfg.c
++++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
+@@ -17,10 +17,12 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ };
+
+ #define GATE_MFG(_id, _name, _parent, _shift) \
+- GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++ GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, \
++ _shift, &mtk_clk_gate_ops_setclr, \
++ CLK_SET_RATE_PARENT)
+
+ static const struct mtk_gate mfg_clks[] = {
+- GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg_core_tmp", 0),
++ GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_ck_fast_ref", 0),
+ };
+
+ static const struct mtk_clk_desc mfg_desc = {
+diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
+index 261a7f76dd3cc..07b46bfd50406 100644
+--- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
++++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
+@@ -37,6 +37,10 @@ static const struct mtk_gate_regs vdo0_2_cg_regs = {
+ #define GATE_VDO0_2(_id, _name, _parent, _shift) \
+ GATE_MTK(_id, _name, _parent, &vdo0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
++#define GATE_VDO0_2_FLAGS(_id, _name, _parent, _shift, _flags) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &vdo0_2_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, _flags)
++
+ static const struct mtk_gate vdo0_clks[] = {
+ /* VDO0_0 */
+ GATE_VDO0_0(CLK_VDO0_DISP_OVL0, "vdo0_disp_ovl0", "top_vpp", 0),
+@@ -85,7 +89,8 @@ static const struct mtk_gate vdo0_clks[] = {
+ /* VDO0_2 */
+ GATE_VDO0_2(CLK_VDO0_DSI0_DSI, "vdo0_dsi0_dsi", "top_dsi_occ", 0),
+ GATE_VDO0_2(CLK_VDO0_DSI1_DSI, "vdo0_dsi1_dsi", "top_dsi_occ", 8),
+- GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf", "top_edp", 16),
++ GATE_VDO0_2_FLAGS(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf",
++ "top_edp", 16, CLK_SET_RATE_PARENT),
+ };
+
+ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
+diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
+index 3378487d2c904..d54d7726d1866 100644
+--- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
++++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
+@@ -43,6 +43,10 @@ static const struct mtk_gate_regs vdo1_3_cg_regs = {
+ #define GATE_VDO1_2(_id, _name, _parent, _shift) \
+ GATE_MTK(_id, _name, _parent, &vdo1_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
++#define GATE_VDO1_2_FLAGS(_id, _name, _parent, _shift, _flags) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &vdo1_2_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, _flags)
++
+ #define GATE_VDO1_3(_id, _name, _parent, _shift) \
+ GATE_MTK(_id, _name, _parent, &vdo1_3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+@@ -99,7 +103,7 @@ static const struct mtk_gate vdo1_clks[] = {
+ GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI0, "vdo1_disp_monitor_dpi0", "top_vpp", 1),
+ GATE_VDO1_2(CLK_VDO1_DPI1, "vdo1_dpi1", "top_vpp", 8),
+ GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI1, "vdo1_disp_monitor_dpi1", "top_vpp", 9),
+- GATE_VDO1_2(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_vpp", 16),
++ GATE_VDO1_2_FLAGS(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_dp", 16, CLK_SET_RATE_PARENT),
+ GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf", "top_vpp", 17),
+ /* VDO1_3 */
+ GATE_VDO1_3(CLK_VDO1_26M_SLOW, "vdo1_26m_slow", "clk26m", 8),
+diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
+index 05a188c621191..e1b445f2c5c54 100644
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -80,7 +80,7 @@ err:
+ if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
+ continue;
+
+- clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
++ clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
+ clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
+ }
+
+@@ -102,7 +102,7 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+ if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
+ continue;
+
+- clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
++ clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
+ clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
+ }
+ }
+@@ -146,7 +146,7 @@ err:
+ if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
+ continue;
+
+- clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
++ clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
+ clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
+ }
+
+@@ -168,7 +168,7 @@ void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
+ if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
+ continue;
+
+- clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
++ clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
+ clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
+ }
+ }
+@@ -393,7 +393,7 @@ err:
+ if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
+ continue;
+
+- mtk_clk_unregister_composite(clk_data->hws[mcd->id]);
++ clk_hw_unregister_divider(clk_data->hws[mcd->id]);
+ clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
+ }
+
+@@ -414,7 +414,7 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
+ if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
+ continue;
+
+- clk_unregister_divider(clk_data->hws[mcd->id]->clk);
++ clk_hw_unregister_divider(clk_data->hws[mcd->id]);
+ clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
+ }
+ }
+diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c
+index 27cd2c1f3f612..434cd8f9de826 100644
+--- a/drivers/clk/meson/meson-aoclk.c
++++ b/drivers/clk/meson/meson-aoclk.c
+@@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)
+ struct meson_aoclk_reset_controller *rstc;
+ struct meson_aoclk_data *data;
+ struct device *dev = &pdev->dev;
++ struct device_node *np;
+ struct regmap *regmap;
+ int ret, clkid;
+
+@@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev)
+ if (!rstc)
+ return -ENOMEM;
+
+- regmap = syscon_node_to_regmap(of_get_parent(dev->of_node));
++ np = of_get_parent(dev->of_node);
++ regmap = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "failed to get regmap\n");
+ return PTR_ERR(regmap);
+diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
+index 8d5a5dab955a8..0e5e6b57eb20e 100644
+--- a/drivers/clk/meson/meson-eeclk.c
++++ b/drivers/clk/meson/meson-eeclk.c
+@@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev)
+ {
+ const struct meson_eeclkc_data *data;
+ struct device *dev = &pdev->dev;
++ struct device_node *np;
+ struct regmap *map;
+ int ret, i;
+
+@@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev)
+ return -EINVAL;
+
+ /* Get the hhi system controller node */
+- map = syscon_node_to_regmap(of_get_parent(dev->of_node));
++ np = of_get_parent(dev->of_node);
++ map = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(map)) {
+ dev_err(dev,
+ "failed to get HHI regmap\n");
+diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
+index 8f3b7a94a6677..827e78fb16a84 100644
+--- a/drivers/clk/meson/meson8b.c
++++ b/drivers/clk/meson/meson8b.c
+@@ -3792,12 +3792,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
+ struct clk_hw_onecell_data *clk_hw_onecell_data)
+ {
+ struct meson8b_clk_reset *rstc;
++ struct device_node *parent_np;
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ struct regmap *map;
+ int i, ret;
+
+- map = syscon_node_to_regmap(of_get_parent(np));
++ parent_np = of_get_parent(np);
++ map = syscon_node_to_regmap(parent_np);
++ of_node_put(parent_np);
+ if (IS_ERR(map)) {
+ pr_err("failed to get HHI regmap - Trying obsolete regs\n");
+ return;
+diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
+index 1cf1ef70e3478..d566fbdebdf93 100644
+--- a/drivers/clk/qcom/Kconfig
++++ b/drivers/clk/qcom/Kconfig
+@@ -645,6 +645,7 @@ config SM_DISPCC_6350
+
+ config SM_GCC_6115
+ tristate "SM6115 and SM4250 Global Clock Controller"
++ select QCOM_GDSC
+ help
+ Support for the global clock controller on SM6115 and SM4250 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c
+index d78ff2f310bfa..b5d93657e1ee3 100644
+--- a/drivers/clk/qcom/apss-ipq6018.c
++++ b/drivers/clk/qcom/apss-ipq6018.c
+@@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_core_clk = {
+ .parent_hws = (const struct clk_hw *[]){
+ &apcs_alias0_clk_src.clkr.hw },
+ .num_parents = 1,
+- .flags = CLK_SET_RATE_PARENT,
++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ .ops = &clk_branch2_ops,
+ },
+ },
+diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
+index 9b97425008ce1..db918c92a522c 100644
+--- a/drivers/clk/qcom/gcc-sdm660.c
++++ b/drivers/clk/qcom/gcc-sdm660.c
+@@ -757,7 +757,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
+ .name = "sdcc1_apps_clk_src",
+ .parent_data = gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+
+diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c
+index 68fe9f6f0d2f3..e24a977c25806 100644
+--- a/drivers/clk/qcom/gcc-sm6115.c
++++ b/drivers/clk/qcom/gcc-sm6115.c
+@@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = {
+ { 750000000, 1500000000, 1 },
+ };
+
++static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = {
++ [CLK_ALPHA_PLL_TYPE_DEFAULT] = {
++ [PLL_OFF_L_VAL] = 0x04,
++ [PLL_OFF_ALPHA_VAL] = 0x08,
++ [PLL_OFF_ALPHA_VAL_U] = 0x0c,
++ [PLL_OFF_TEST_CTL] = 0x10,
++ [PLL_OFF_TEST_CTL_U] = 0x14,
++ [PLL_OFF_USER_CTL] = 0x18,
++ [PLL_OFF_USER_CTL_U] = 0x1c,
++ [PLL_OFF_CONFIG_CTL] = 0x20,
++ [PLL_OFF_STATUS] = 0x24,
++ },
++};
++
+ static struct clk_alpha_pll gpll0 = {
+ .offset = 0x0,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(0),
+@@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
+ .post_div_table = post_div_table_gpll0_out_aux2,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll0_out_aux2",
+ .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+@@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = {
+ .post_div_table = post_div_table_gpll0_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll0_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+@@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = {
+ .offset = 0xa000,
+ .vco_table = gpll10_vco,
+ .num_vco = ARRAY_SIZE(gpll10_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(10),
+@@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = {
+ .post_div_table = post_div_table_gpll10_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll10_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
+@@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = {
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+ .flags = SUPPORTS_DYNAMIC_UPDATE,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(11),
+@@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = {
+ .post_div_table = post_div_table_gpll11_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll11_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
+@@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = {
+ .offset = 0x3000,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(3),
+@@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = {
+ .offset = 0x4000,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(4),
+@@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = {
+ .post_div_table = post_div_table_gpll4_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll4_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
+@@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = {
+ .offset = 0x6000,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(6),
+@@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = {
+ .post_div_table = post_div_table_gpll6_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll6_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
+@@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = {
+ .offset = 0x7000,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x79000,
+ .enable_mask = BIT(7),
+@@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = {
+ .post_div_table = post_div_table_gpll7_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll7_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
+@@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = {
+ .offset = 0x8000,
+ .vco_table = default_vco,
+ .num_vco = ARRAY_SIZE(default_vco),
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .flags = SUPPORTS_DYNAMIC_UPDATE,
+ .clkr = {
+ .enable_reg = 0x79000,
+@@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = {
+ .post_div_table = post_div_table_gpll8_out_main,
+ .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
+ .width = 4,
+- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++ .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll8_out_main",
+ .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
+diff --git a/drivers/clk/samsung/clk-exynosautov9.c b/drivers/clk/samsung/clk-exynosautov9.c
+index d9e1f8e4a7b45..487a71b32a009 100644
+--- a/drivers/clk/samsung/clk-exynosautov9.c
++++ b/drivers/clk/samsung/clk-exynosautov9.c
+@@ -1170,9 +1170,9 @@ static const struct samsung_cmu_info fsys2_cmu_info __initconst = {
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_2 0x2058
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_3 0x205c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4 0x2060
+-#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7 0x206c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5 0x2064
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6 0x2068
++#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7 0x206c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8 0x2070
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9 0x2074
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10 0x204c
+@@ -1418,14 +1418,14 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = {
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11 0x2020
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_0 0x2044
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1 0x2048
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2 0x2058
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3 0x205c
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4 0x2060
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7 0x206c
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5 0x2064
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6 0x2068
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8 0x2070
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9 0x2074
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2 0x2054
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3 0x2058
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4 0x205c
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5 0x2060
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6 0x2064
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7 0x2068
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8 0x206c
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9 0x2070
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10 0x204c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11 0x2050
+
+@@ -1463,9 +1463,9 @@ static const unsigned long peric1_clk_regs[] __initconst = {
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4,
+- CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6,
++ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9,
+ CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10,
+diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c
+index d620bbbcdfc88..ce81e4087a8fc 100644
+--- a/drivers/clk/sprd/common.c
++++ b/drivers/clk/sprd/common.c
+@@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
+ {
+ void __iomem *base;
+ struct device *dev = &pdev->dev;
+- struct device_node *node = dev->of_node;
++ struct device_node *node = dev->of_node, *np;
+ struct regmap *regmap;
+
+ if (of_find_property(node, "sprd,syscon", NULL)) {
+@@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
+ pr_err("%s: failed to get syscon regmap\n", __func__);
+ return PTR_ERR(regmap);
+ }
+- } else if (of_device_is_compatible(of_get_parent(dev->of_node),
+- "syscon")) {
+- regmap = device_node_to_regmap(of_get_parent(dev->of_node));
++ } else if (of_device_is_compatible(np = of_get_parent(node), "syscon") ||
++ (of_node_put(np), 0)) {
++ regmap = device_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "failed to get regmap from its parent.\n");
+ return PTR_ERR(regmap);
+diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
+index 582a22c049194..d820292a381d0 100644
+--- a/drivers/clk/st/clkgen-fsyn.c
++++ b/drivers/clk/st/clkgen-fsyn.c
+@@ -987,6 +987,7 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+ const char *pll_name, *clk_parent_name;
+ void __iomem *reg;
+ spinlock_t *lock;
++ struct device_node *parent_np;
+
+ /*
+ * First check for reg property within the node to keep backward
+@@ -994,7 +995,9 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+ */
+ reg = of_iomap(np, 0);
+ if (!reg) {
+- reg = of_iomap(of_get_parent(np), 0);
++ parent_np = of_get_parent(np);
++ reg = of_iomap(parent_np, 0);
++ of_node_put(parent_np);
+ if (!reg) {
+ pr_err("%s: Failed to get base address\n", __func__);
+ return;
+diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
+index ee39af7a0b721..596e939ad905e 100644
+--- a/drivers/clk/st/clkgen-mux.c
++++ b/drivers/clk/st/clkgen-mux.c
+@@ -56,6 +56,7 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
+ void __iomem *reg;
+ const char **parents;
+ int num_parents = 0;
++ struct device_node *parent_np;
+
+ /*
+ * First check for reg property within the node to keep backward
+@@ -63,7 +64,9 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
+ */
+ reg = of_iomap(np, 0);
+ if (!reg) {
+- reg = of_iomap(of_get_parent(np), 0);
++ parent_np = of_get_parent(np);
++ reg = of_iomap(parent_np, 0);
++ of_node_put(parent_np);
+ if (!reg) {
+ pr_err("%s: Failed to get base address\n", __func__);
+ return;
+diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
+index ef718c4b38267..f7405a58877e2 100644
+--- a/drivers/clk/tegra/clk-tegra114.c
++++ b/drivers/clk/tegra/clk-tegra114.c
+@@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np)
+ }
+
+ pmc_base = of_iomap(node, 0);
++ of_node_put(node);
+ if (!pmc_base) {
+ pr_err("Can't map pmc registers\n");
+ WARN_ON(1);
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index be3c33441cfc4..8a4514f6d5033 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -1131,6 +1131,7 @@ static void __init tegra20_clock_init(struct device_node *np)
+ }
+
+ pmc_base = of_iomap(node, 0);
++ of_node_put(node);
+ if (!pmc_base) {
+ pr_err("Can't map pmc registers\n");
+ BUG();
+diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
+index b9099012dc7b1..499f999e91e13 100644
+--- a/drivers/clk/tegra/clk-tegra210.c
++++ b/drivers/clk/tegra/clk-tegra210.c
+@@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np)
+ }
+
+ pmc_base = of_iomap(node, 0);
++ of_node_put(node);
+ if (!pmc_base) {
+ pr_err("Can't map pmc registers\n");
+ WARN_ON(1);
+diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
+index f0f5bf68b6d23..ff4d6a9516813 100644
+--- a/drivers/clk/ti/clk-dra7-atl.c
++++ b/drivers/clk/ti/clk-dra7-atl.c
+@@ -245,14 +245,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
+ if (rc) {
+ pr_err("%s: failed to lookup atl clock %d\n", __func__,
+ i);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto pm_put;
+ }
+
+ clk = of_clk_get_from_provider(&clkspec);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to get atl clock %d from provider\n",
+ __func__, i);
+- return PTR_ERR(clk);
++ ret = PTR_ERR(clk);
++ goto pm_put;
+ }
+
+ cdesc = to_atl_desc(__clk_get_hw(clk));
+@@ -285,8 +287,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
+ if (cdesc->enabled)
+ atl_clk_enable(__clk_get_hw(clk));
+ }
+- pm_runtime_put_sync(cinfo->dev);
+
++pm_put:
++ pm_runtime_put_sync(cinfo->dev);
+ return ret;
+ }
+
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index 373e9438b57a3..1dc2f15fb75b2 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -140,11 +140,12 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,
+ break;
+ }
+ }
+- of_node_put(from);
+ kfree(tmp);
+
+- if (found)
++ if (found) {
++ of_node_put(from);
+ return np;
++ }
+
+ /* Fall back to using old node name base provider name */
+ return of_find_node_by_name(from, name);
+diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
+index eb25303eefed4..2c9da6623b84e 100644
+--- a/drivers/clk/zynqmp/clkc.c
++++ b/drivers/clk/zynqmp/clkc.c
+@@ -710,6 +710,13 @@ static void zynqmp_get_clock_info(void)
+ FIELD_PREP(CLK_ATTR_NODE_INDEX, i);
+
+ zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
++
++ /*
++ * Terminate with NULL character in case name provided by firmware
++ * is longer and truncated due to size limit.
++ */
++ name.name[sizeof(name.name) - 1] = '\0';
++
+ if (!strcmp(name.name, RESERVED_CLK_NAME))
+ continue;
+ strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
+diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
+index 91a6b4cc910eb..0d3e1377b092c 100644
+--- a/drivers/clk/zynqmp/pll.c
++++ b/drivers/clk/zynqmp/pll.c
+@@ -102,26 +102,25 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+ {
+ u32 fbdiv;
+- long rate_div, f;
++ u32 mult, div;
+
+- /* Enable the fractional mode if needed */
+- rate_div = (rate * FRAC_DIV) / *prate;
+- f = rate_div % FRAC_DIV;
+- if (f) {
+- if (rate > PS_PLL_VCO_MAX) {
+- fbdiv = rate / PS_PLL_VCO_MAX;
+- rate = rate / (fbdiv + 1);
+- }
+- if (rate < PS_PLL_VCO_MIN) {
+- fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
+- rate = rate * fbdiv;
+- }
+- return rate;
++ /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */
++ if (rate > PS_PLL_VCO_MAX) {
++ div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX);
++ rate = rate / div;
++ }
++ if (rate < PS_PLL_VCO_MIN) {
++ mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
++ rate = rate * mult;
+ }
+
+ fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+- fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+- return *prate * fbdiv;
++ if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) {
++ fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
++ rate = *prate * fbdiv;
++ }
++
++ return rate;
+ }
+
+ /**
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index 9ab8221ee3c65..a7ff77550e173 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -44,8 +44,8 @@
+ #define CNTACR_RWVT BIT(4)
+ #define CNTACR_RWPT BIT(5)
+
+-#define CNTVCT_LO 0x00
+-#define CNTPCT_LO 0x08
++#define CNTPCT_LO 0x00
++#define CNTVCT_LO 0x08
+ #define CNTFRQ 0x10
+ #define CNTP_CVAL_LO 0x20
+ #define CNTP_CTL 0x2c
+@@ -473,6 +473,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
+ .desc = "ARM erratum 858921",
+ .read_cntpct_el0 = arm64_858921_read_cntpct_el0,
+ .read_cntvct_el0 = arm64_858921_read_cntvct_el0,
++ .set_next_event_phys = erratum_set_next_event_phys,
++ .set_next_event_virt = erratum_set_next_event_virt,
+ },
+ #endif
+ #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
+diff --git a/drivers/clocksource/timer-gxp.c b/drivers/clocksource/timer-gxp.c
+index 8b38b32123880..fe4fa8d7b3f13 100644
+--- a/drivers/clocksource/timer-gxp.c
++++ b/drivers/clocksource/timer-gxp.c
+@@ -171,6 +171,7 @@ static int gxp_timer_probe(struct platform_device *pdev)
+ {
+ struct platform_device *gxp_watchdog_device;
+ struct device *dev = &pdev->dev;
++ int ret;
+
+ if (!gxp_timer) {
+ pr_err("Gxp Timer not initialized, cannot create watchdog");
+@@ -187,7 +188,11 @@ static int gxp_timer_probe(struct platform_device *pdev)
+ gxp_watchdog_device->dev.platform_data = gxp_timer->counter;
+ gxp_watchdog_device->dev.parent = dev;
+
+- return platform_device_add(gxp_watchdog_device);
++ ret = platform_device_add(gxp_watchdog_device);
++ if (ret)
++ platform_device_put(gxp_watchdog_device);
++
++ return ret;
+ }
+
+ static const struct of_device_id gxp_timer_of_match[] = {
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 9ac75c1cde9c2..d63a28c5f95a9 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -152,6 +152,7 @@ static inline int amd_pstate_enable(bool enable)
+ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ {
+ u64 cap1;
++ u32 highest_perf;
+
+ int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
+ &cap1);
+@@ -163,7 +164,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ *
+ * CPPC entry doesn't indicate the highest performance in some ASICs.
+ */
+- WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
++ highest_perf = amd_get_highest_perf();
++ if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
++ highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
++
++ WRITE_ONCE(cpudata->highest_perf, highest_perf);
+
+ WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
+ WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
+@@ -175,12 +180,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ static int cppc_init_perf(struct amd_cpudata *cpudata)
+ {
+ struct cppc_perf_caps cppc_perf;
++ u32 highest_perf;
+
+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+ if (ret)
+ return ret;
+
+- WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
++ highest_perf = amd_get_highest_perf();
++ if (highest_perf > cppc_perf.highest_perf)
++ highest_perf = cppc_perf.highest_perf;
++
++ WRITE_ONCE(cpudata->highest_perf, highest_perf);
+
+ WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
+ WRITE_ONCE(cpudata->lowest_nonlinear_perf,
+@@ -312,7 +322,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
+ return -ENODEV;
+
+ cap_perf = READ_ONCE(cpudata->highest_perf);
+- min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
++ min_perf = READ_ONCE(cpudata->lowest_perf);
+ max_perf = cap_perf;
+
+ freqs.old = policy->cur;
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 57cdb36798854..fc3ebeb0bbe59 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -2416,6 +2416,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
+ X86_MATCH(SKYLAKE_X, core_funcs),
+ X86_MATCH(COMETLAKE, core_funcs),
+ X86_MATCH(ICELAKE_X, core_funcs),
++ X86_MATCH(TIGERLAKE, core_funcs),
+ {}
+ };
+ MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index d5ef3c66c7625..bb32659820ceb 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -316,14 +316,14 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ if (IS_ERR(opp)) {
+ dev_warn(dev, "Can't find the OPP for throttling: %pe!\n", opp);
+ } else {
+- throttled_freq = freq_hz / HZ_PER_KHZ;
+-
+- /* Update thermal pressure (the boost frequencies are accepted) */
+- arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
+-
+ dev_pm_opp_put(opp);
+ }
+
++ throttled_freq = freq_hz / HZ_PER_KHZ;
++
++ /* Update thermal pressure (the boost frequencies are accepted) */
++ arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
++
+ /*
+ * In the unlikely case policy is unregistered do not enable
+ * polling or h/w interrupt
+diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
+index 862a2876f1c9d..05fe2902df9a7 100644
+--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
++++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
+@@ -97,8 +97,13 @@ static int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int idx)
+ {
+ u32 *states = __this_cpu_read(sbi_cpuidle_data.states);
++ u32 state = states[idx];
+
+- return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, states[idx]);
++ if (state & SBI_HSM_SUSP_NON_RET_BIT)
++ return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, state);
++ else
++ return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(sbi_suspend,
++ idx, state);
+ }
+
+ static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
+diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
+index 8c32d0eb8fcf2..6872ac3440010 100644
+--- a/drivers/crypto/cavium/cpt/cptpf_main.c
++++ b/drivers/crypto/cavium/cpt/cptpf_main.c
+@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+ const struct firmware *fw_entry;
+ struct device *dev = &cpt->pdev->dev;
+ struct ucode_header *ucode;
++ unsigned int code_length;
+ struct microcode *mcode;
+ int j, ret = 0;
+
+@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+ ucode = (struct ucode_header *)fw_entry->data;
+ mcode = &cpt->mcode[cpt->next_mc_idx];
+ memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ);
+- mcode->code_size = ntohl(ucode->code_length) * 2;
+- if (!mcode->code_size) {
++ code_length = ntohl(ucode->code_length);
++ if (code_length == 0 || code_length >= INT_MAX / 2) {
+ ret = -EINVAL;
+ goto fw_release;
+ }
++ mcode->code_size = code_length * 2;
+
+ mcode->is_ae = is_ae;
+ mcode->core_mask = 0ULL;
+diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c
+index 7d4b4ad1db1f3..9f753cb4f5f18 100644
+--- a/drivers/crypto/ccp/ccp-dmaengine.c
++++ b/drivers/crypto/ccp/ccp-dmaengine.c
+@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp)
+ for (i = 0; i < ccp->cmd_q_count; i++) {
+ chan = ccp->ccp_dma_chan + i;
+ dma_chan = &chan->dma_chan;
++
++ if (dma_chan->client_count)
++ dma_release_channel(dma_chan);
++
+ tasklet_kill(&chan->cleanup_tasklet);
+ list_del_rcu(&dma_chan->device_node);
+ }
+@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)
+ if (!dmaengine)
+ return;
+
+- dma_async_device_unregister(dma_dev);
+ ccp_dma_release(ccp);
++ dma_async_device_unregister(dma_dev);
+
+ kmem_cache_destroy(ccp->dma_desc_cache);
+ kmem_cache_destroy(ccp->dma_cmd_cache);
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 9f588c9728f8b..6c49e6d06114f 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -231,7 +231,7 @@ static int sev_read_init_ex_file(void)
+ return 0;
+ }
+
+-static void sev_write_init_ex_file(void)
++static int sev_write_init_ex_file(void)
+ {
+ struct sev_device *sev = psp_master->sev_data;
+ struct file *fp;
+@@ -241,14 +241,16 @@ static void sev_write_init_ex_file(void)
+ lockdep_assert_held(&sev_cmd_mutex);
+
+ if (!sev_init_ex_buffer)
+- return;
++ return 0;
+
+ fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600);
+ if (IS_ERR(fp)) {
++ int ret = PTR_ERR(fp);
++
+ dev_err(sev->dev,
+- "SEV: could not open file for write, error %ld\n",
+- PTR_ERR(fp));
+- return;
++ "SEV: could not open file for write, error %d\n",
++ ret);
++ return ret;
+ }
+
+ nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset);
+@@ -259,18 +261,20 @@ static void sev_write_init_ex_file(void)
+ dev_err(sev->dev,
+ "SEV: failed to write %u bytes to non volatile memory area, ret %ld\n",
+ NV_LENGTH, nwrite);
+- return;
++ return -EIO;
+ }
+
+ dev_dbg(sev->dev, "SEV: write successful to NV file\n");
++
++ return 0;
+ }
+
+-static void sev_write_init_ex_file_if_required(int cmd_id)
++static int sev_write_init_ex_file_if_required(int cmd_id)
+ {
+ lockdep_assert_held(&sev_cmd_mutex);
+
+ if (!sev_init_ex_buffer)
+- return;
++ return 0;
+
+ /*
+ * Only a few platform commands modify the SPI/NV area, but none of the
+@@ -285,10 +289,10 @@ static void sev_write_init_ex_file_if_required(int cmd_id)
+ case SEV_CMD_PEK_GEN:
+ break;
+ default:
+- return;
++ return 0;
+ }
+
+- sev_write_init_ex_file();
++ return sev_write_init_ex_file();
+ }
+
+ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
+@@ -361,7 +365,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
+ cmd, reg & PSP_CMDRESP_ERR_MASK);
+ ret = -EIO;
+ } else {
+- sev_write_init_ex_file_if_required(cmd);
++ ret = sev_write_init_ex_file_if_required(cmd);
+ }
+
+ print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index ad83c194d6648..9fa2efe601537 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -2245,8 +2245,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer,
+ return ret;
+
+ /* Judge if the instance is being reset. */
+- if (unlikely(atomic_read(&qm->status.flags) == QM_STOP))
+- return 0;
++ if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) {
++ ret = 0;
++ goto put_dfx_access;
++ }
+
+ if (count > QM_DBG_WRITE_LEN) {
+ ret = -ENOSPC;
+diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
+index ad35434a3fdb7..06a2d6e81ae93 100644
+--- a/drivers/crypto/hisilicon/zip/zip_crypto.c
++++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
+@@ -123,12 +123,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
+ if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX)
+ return -EINVAL;
+
+- return param_set_int(val, kp);
++ return param_set_ushort(val, kp);
+ }
+
+ static const struct kernel_param_ops sgl_sge_nr_ops = {
+ .set = sgl_sge_nr_set,
+- .get = param_get_int,
++ .get = param_get_ushort,
+ };
+
+ static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index bc60b58022564..2124416742f84 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ u32 x;
+
+ x = ipad[i] ^ ipad[i + 4];
+- cache[i] ^= swab(x);
++ cache[i] ^= swab32(x);
+ }
+ }
+ cache_len = AES_BLOCK_SIZE;
+@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq)
+ u32 *result = (void *)areq->result;
+
+ /* K3 */
+- result[i] = swab(ctx->base.ipad.word[i + 4]);
++ result[i] = swab32(ctx->base.ipad.word[i + 4]);
+ }
+ areq->result[0] ^= 0x80; // 10- padding
+ crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result);
+@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE,
+ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3");
+ for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++)
+- ctx->base.ipad.word[i] = swab(key_tmp[i]);
++ ctx->base.ipad.word[i] = swab32(key_tmp[i]);
+
+ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
+@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+ return ret;
+
+ for (i = 0; i < len / sizeof(u32); i++)
+- ctx->base.ipad.word[i + 8] = swab(aes.key_enc[i]);
++ ctx->base.ipad.word[i + 8] = swab32(aes.key_enc[i]);
+
+ /* precompute the CMAC key material */
+ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
+diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+index 40b482198ebc5..a765eefb18c2f 100644
+--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
++++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,
+ struct tar_ucode_info_t *tar_info;
+ struct otx_cpt_ucode_hdr *ucode_hdr;
+ int ucode_type, ucode_size;
++ unsigned int code_length;
+
+ /*
+ * If size is less than microcode header size then don't report
+@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,
+ if (get_ucode_type(ucode_hdr, &ucode_type))
+ return 0;
+
+- ucode_size = ntohl(ucode_hdr->code_length) * 2;
++ code_length = ntohl(ucode_hdr->code_length);
++ if (code_length >= INT_MAX / 2) {
++ dev_err(dev, "Invalid code_length %u\n", code_length);
++ return -EINVAL;
++ }
++
++ ucode_size = code_length * 2;
+ if (!ucode_size || (size < round_up(ucode_size, 16) +
+ sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
+ dev_err(dev, "Ucode %s invalid size\n", filename);
+@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
+ {
+ struct otx_cpt_ucode_hdr *ucode_hdr;
+ const struct firmware *fw;
++ unsigned int code_length;
+ int ret;
+
+ set_ucode_filename(ucode, ucode_filename);
+@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
+ ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;
+ memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
+ ucode->ver_num = ucode_hdr->ver_num;
+- ucode->size = ntohl(ucode_hdr->code_length) * 2;
++ code_length = ntohl(ucode_hdr->code_length);
++ if (code_length >= INT_MAX / 2) {
++ dev_err(dev, "Ucode invalid code_length %u\n", code_length);
++ ret = -EINVAL;
++ goto release_fw;
++ }
++ ucode->size = code_length * 2;
+ if (!ucode->size || (fw->size < round_up(ucode->size, 16)
+ + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
+ dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
+diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+index 43b8f864806bd..4fb4b3df5a188 100644
+--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
++++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+@@ -107,7 +107,7 @@ do { \
+ * Timeout is in cycles. Clock speed may vary across products but this
+ * value should be a few milli-seconds.
+ */
+-#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000
++#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL
+ #define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000
+ #define ADF_SSMWDTL_OFFSET 0x54
+ #define ADF_SSMWDTH_OFFSET 0x5C
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index fb45fa83841c5..cad9c58caab13 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ dma_addr_t blpout = qat_req->buf.bloutp;
+ size_t sz = qat_req->buf.sz;
+ size_t sz_out = qat_req->buf.sz_out;
++ int bl_dma_dir;
+ int i;
+
++ bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
++
+ for (i = 0; i < bl->num_bufs; i++)
+ dma_unmap_single(dev, bl->bufers[i].addr,
+- bl->bufers[i].len, DMA_BIDIRECTIONAL);
++ bl->bufers[i].len, bl_dma_dir);
+
+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
+
+@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ for (i = bufless; i < blout->num_bufs; i++) {
+ dma_unmap_single(dev, blout->bufers[i].addr,
+ blout->bufers[i].len,
+- DMA_BIDIRECTIONAL);
++ DMA_FROM_DEVICE);
+ }
+ dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE);
+
+@@ -716,6 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ struct scatterlist *sg;
+ size_t sz_out, sz = struct_size(bufl, bufers, n);
+ int node = dev_to_node(&GET_DEV(inst->accel_dev));
++ int bufl_dma_dir;
+
+ if (unlikely(!n))
+ return -EINVAL;
+@@ -733,6 +737,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ qat_req->buf.sgl_src_valid = true;
+ }
+
++ bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
++
+ for_each_sg(sgl, sg, n, i)
+ bufl->bufers[i].addr = DMA_MAPPING_ERROR;
+
+@@ -744,7 +750,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+
+ bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ sg->length,
+- DMA_BIDIRECTIONAL);
++ bufl_dma_dir);
+ bufl->bufers[y].len = sg->length;
+ if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr)))
+ goto err_in;
+@@ -787,7 +793,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+
+ bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ sg->length,
+- DMA_BIDIRECTIONAL);
++ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(dev, bufers[y].addr)))
+ goto err_out;
+ bufers[y].len = sg->length;
+@@ -817,7 +823,7 @@ err_out:
+ if (!dma_mapping_error(dev, buflout->bufers[i].addr))
+ dma_unmap_single(dev, buflout->bufers[i].addr,
+ buflout->bufers[i].len,
+- DMA_BIDIRECTIONAL);
++ DMA_FROM_DEVICE);
+
+ if (!qat_req->buf.sgl_dst_valid)
+ kfree(buflout);
+@@ -831,7 +837,7 @@ err_in:
+ if (!dma_mapping_error(dev, bufl->bufers[i].addr))
+ dma_unmap_single(dev, bufl->bufers[i].addr,
+ bufl->bufers[i].len,
+- DMA_BIDIRECTIONAL);
++ bufl_dma_dir);
+
+ if (!qat_req->buf.sgl_src_valid)
+ kfree(bufl);
+diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c
+index 457084b344c17..b07ae4ba165e7 100644
+--- a/drivers/crypto/sahara.c
++++ b/drivers/crypto/sahara.c
+@@ -26,10 +26,10 @@
+ #include <linux/kernel.h>
+ #include <linux/kthread.h>
+ #include <linux/module.h>
+-#include <linux/mutex.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
++#include <linux/spinlock.h>
+
+ #define SHA_BUFFER_LEN PAGE_SIZE
+ #define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
+@@ -196,7 +196,7 @@ struct sahara_dev {
+ void __iomem *regs_base;
+ struct clk *clk_ipg;
+ struct clk *clk_ahb;
+- struct mutex queue_mutex;
++ spinlock_t queue_spinlock;
+ struct task_struct *kthread;
+ struct completion dma_completion;
+
+@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode)
+
+ rctx->mode = mode;
+
+- mutex_lock(&dev->queue_mutex);
++ spin_lock_bh(&dev->queue_spinlock);
+ err = crypto_enqueue_request(&dev->queue, &req->base);
+- mutex_unlock(&dev->queue_mutex);
++ spin_unlock_bh(&dev->queue_spinlock);
+
+ wake_up_process(dev->kthread);
+
+@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data)
+ do {
+ __set_current_state(TASK_INTERRUPTIBLE);
+
+- mutex_lock(&dev->queue_mutex);
++ spin_lock_bh(&dev->queue_spinlock);
+ backlog = crypto_get_backlog(&dev->queue);
+ async_req = crypto_dequeue_request(&dev->queue);
+- mutex_unlock(&dev->queue_mutex);
++ spin_unlock_bh(&dev->queue_spinlock);
+
+ if (backlog)
+ backlog->complete(backlog, -EINPROGRESS);
+@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last)
+ rctx->first = 1;
+ }
+
+- mutex_lock(&dev->queue_mutex);
++ spin_lock_bh(&dev->queue_spinlock);
+ ret = crypto_enqueue_request(&dev->queue, &req->base);
+- mutex_unlock(&dev->queue_mutex);
++ spin_unlock_bh(&dev->queue_spinlock);
+
+ wake_up_process(dev->kthread);
+
+@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev)
+
+ crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
+
+- mutex_init(&dev->queue_mutex);
++ spin_lock_init(&dev->queue_spinlock);
+
+ dev_ptr = dev;
+
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index 38e8767ec3715..bf11d32205f38 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -124,17 +124,20 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
+ {
+ struct udmabuf *ubuf = buf->priv;
+ struct device *dev = ubuf->device->this_device;
++ int ret = 0;
+
+ if (!ubuf->sg) {
+ ubuf->sg = get_sg_table(dev, buf, direction);
+- if (IS_ERR(ubuf->sg))
+- return PTR_ERR(ubuf->sg);
++ if (IS_ERR(ubuf->sg)) {
++ ret = PTR_ERR(ubuf->sg);
++ ubuf->sg = NULL;
++ }
+ } else {
+ dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
+ direction);
+ }
+
+- return 0;
++ return ret;
+ }
+
+ static int end_cpu_udmabuf(struct dma_buf *buf,
+diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
+index 07f7564796637..c54b24ff5206a 100644
+--- a/drivers/dma/dw-edma/dw-edma-core.c
++++ b/drivers/dma/dw-edma/dw-edma-core.c
+@@ -9,7 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/kernel.h>
+-#include <linux/pm_runtime.h>
+ #include <linux/dmaengine.h>
+ #include <linux/err.h>
+ #include <linux/interrupt.h>
+@@ -682,15 +681,12 @@ static int dw_edma_alloc_chan_resources(struct dma_chan *dchan)
+ if (chan->status != EDMA_ST_IDLE)
+ return -EBUSY;
+
+- pm_runtime_get(chan->dw->chip->dev);
+-
+ return 0;
+ }
+
+ static void dw_edma_free_chan_resources(struct dma_chan *dchan)
+ {
+ unsigned long timeout = jiffies + msecs_to_jiffies(5000);
+- struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
+ int ret;
+
+ while (time_before(jiffies, timeout)) {
+@@ -703,8 +699,6 @@ static void dw_edma_free_chan_resources(struct dma_chan *dchan)
+
+ cpu_relax();
+ }
+-
+- pm_runtime_put(chan->dw->chip->dev);
+ }
+
+ static int dw_edma_channel_setup(struct dw_edma *dw, bool write,
+@@ -977,9 +971,6 @@ int dw_edma_probe(struct dw_edma_chip *chip)
+ if (err)
+ goto err_irq_free;
+
+- /* Power management */
+- pm_runtime_enable(dev);
+-
+ /* Turn debugfs on */
+ dw_edma_v0_core_debugfs_on(dw);
+
+@@ -1009,9 +1000,6 @@ int dw_edma_remove(struct dw_edma_chip *chip)
+ for (i = (dw->nr_irqs - 1); i >= 0; i--)
+ free_irq(chip->ops->irq_vector(dev, i), &dw->irq[i]);
+
+- /* Power management */
+- pm_runtime_disable(dev);
+-
+ /* Deregister eDMA device */
+ dma_async_device_unregister(&dw->wr_edma);
+ list_for_each_entry_safe(chan, _chan, &dw->wr_edma.channels,
+diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c
+index 43817ced3a3e1..0233b42143c77 100644
+--- a/drivers/dma/hisi_dma.c
++++ b/drivers/dma/hisi_dma.c
+@@ -180,7 +180,8 @@ static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index)
+ hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, index, 0);
+ }
+
+-static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan)
++static void hisi_dma_reset_or_disable_hw_chan(struct hisi_dma_chan *chan,
++ bool disable)
+ {
+ struct hisi_dma_dev *hdma_dev = chan->hdma_dev;
+ u32 index = chan->qp_num, tmp;
+@@ -201,8 +202,11 @@ static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan)
+ hisi_dma_do_reset(hdma_dev, index);
+ hisi_dma_reset_qp_point(hdma_dev, index);
+ hisi_dma_pause_dma(hdma_dev, index, false);
+- hisi_dma_enable_dma(hdma_dev, index, true);
+- hisi_dma_unmask_irq(hdma_dev, index);
++
++ if (!disable) {
++ hisi_dma_enable_dma(hdma_dev, index, true);
++ hisi_dma_unmask_irq(hdma_dev, index);
++ }
+
+ ret = readl_relaxed_poll_timeout(hdma_dev->base +
+ HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp,
+@@ -218,7 +222,7 @@ static void hisi_dma_free_chan_resources(struct dma_chan *c)
+ struct hisi_dma_chan *chan = to_hisi_dma_chan(c);
+ struct hisi_dma_dev *hdma_dev = chan->hdma_dev;
+
+- hisi_dma_reset_hw_chan(chan);
++ hisi_dma_reset_or_disable_hw_chan(chan, false);
+ vchan_free_chan_resources(&chan->vc);
+
+ memset(chan->sq, 0, sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth);
+@@ -267,7 +271,6 @@ static void hisi_dma_start_transfer(struct hisi_dma_chan *chan)
+
+ vd = vchan_next_desc(&chan->vc);
+ if (!vd) {
+- dev_err(&hdma_dev->pdev->dev, "no issued task!\n");
+ chan->desc = NULL;
+ return;
+ }
+@@ -299,7 +302,7 @@ static void hisi_dma_issue_pending(struct dma_chan *c)
+
+ spin_lock_irqsave(&chan->vc.lock, flags);
+
+- if (vchan_issue_pending(&chan->vc))
++ if (vchan_issue_pending(&chan->vc) && !chan->desc)
+ hisi_dma_start_transfer(chan);
+
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+@@ -394,7 +397,7 @@ static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index)
+
+ static void hisi_dma_disable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index)
+ {
+- hisi_dma_reset_hw_chan(&hdma_dev->chan[qp_index]);
++ hisi_dma_reset_or_disable_hw_chan(&hdma_dev->chan[qp_index], true);
+ }
+
+ static void hisi_dma_enable_qps(struct hisi_dma_dev *hdma_dev)
+@@ -432,18 +435,15 @@ static irqreturn_t hisi_dma_irq(int irq, void *data)
+ desc = chan->desc;
+ cqe = chan->cq + chan->cq_head;
+ if (desc) {
++ chan->cq_head = (chan->cq_head + 1) % hdma_dev->chan_depth;
++ hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR,
++ chan->qp_num, chan->cq_head);
+ if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) {
+- chan->cq_head = (chan->cq_head + 1) %
+- hdma_dev->chan_depth;
+- hisi_dma_chan_write(hdma_dev->base,
+- HISI_DMA_CQ_HEAD_PTR, chan->qp_num,
+- chan->cq_head);
+ vchan_cookie_complete(&desc->vd);
++ hisi_dma_start_transfer(chan);
+ } else {
+ dev_err(&hdma_dev->pdev->dev, "task error!\n");
+ }
+-
+- chan->desc = NULL;
+ }
+
+ spin_unlock(&chan->vc.lock);
+diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
+index 743ead5ebc579..5b9921475be6c 100644
+--- a/drivers/dma/idxd/irq.c
++++ b/drivers/dma/idxd/irq.c
+@@ -324,13 +324,11 @@ halt:
+ idxd->state = IDXD_DEV_HALTED;
+ idxd_wqs_quiesce(idxd);
+ idxd_wqs_unmap_portal(idxd);
+- spin_lock(&idxd->dev_lock);
+ idxd_device_clear_state(idxd);
+ dev_err(&idxd->pdev->dev,
+ "idxd halted, need %s.\n",
+ gensts.reset_type == IDXD_DEVICE_RESET_FLR ?
+ "FLR" : "system reset");
+- spin_unlock(&idxd->dev_lock);
+ return -ENXIO;
+ }
+ }
+diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
+index 37ff4ec7db76f..e2070df6cad28 100644
+--- a/drivers/dma/ioat/dma.c
++++ b/drivers/dma/ioat/dma.c
+@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)
+ if (active - i == 0) {
+ dev_dbg(to_dev(ioat_chan), "%s: cancel completion timeout\n",
+ __func__);
+- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ }
+
+ /* microsecond delay by sysfs variable per pending descriptor */
+@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)
+
+ if (chanerr &
+ (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) {
+- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ ioat_eh(ioat_chan);
+ }
+ }
+@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan)
+ }
+
+ if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state))
+- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ }
+
+ static void ioat_reboot_chan(struct ioatdma_chan *ioat_chan)
+diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
+index 994fc4d2aca42..dc147cc2436e9 100644
+--- a/drivers/dma/mxs-dma.c
++++ b/drivers/dma/mxs-dma.c
+@@ -670,7 +670,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
+ return mxs_chan->status;
+ }
+
+-static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
++static int mxs_dma_init(struct mxs_dma_engine *mxs_dma)
+ {
+ int ret;
+
+@@ -741,7 +741,7 @@ static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
+ ofdma->of_node);
+ }
+
+-static int __init mxs_dma_probe(struct platform_device *pdev)
++static int mxs_dma_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+ const struct mxs_dma_type *dma_type;
+@@ -839,10 +839,7 @@ static struct platform_driver mxs_dma_driver = {
+ .name = "mxs-dma",
+ .of_match_table = mxs_dma_dt_ids,
+ },
++ .probe = mxs_dma_probe,
+ };
+
+-static int __init mxs_dma_module_init(void)
+-{
+- return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe);
+-}
+-subsys_initcall(mxs_dma_module_init);
++builtin_platform_driver(mxs_dma_driver);
+diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
+index facdacf8aede6..d56caf1681ffb 100644
+--- a/drivers/dma/qcom/qcom_adm.c
++++ b/drivers/dma/qcom/qcom_adm.c
+@@ -379,13 +379,13 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ if (blk_size < 0) {
+ dev_err(adev->dev, "invalid burst value: %d\n",
+ burst);
+- return ERR_PTR(-EINVAL);
++ return NULL;
+ }
+
+ crci = achan->crci & 0xf;
+ if (!crci || achan->crci > 0x1f) {
+ dev_err(adev->dev, "invalid crci value\n");
+- return ERR_PTR(-EINVAL);
++ return NULL;
+ }
+ }
+
+@@ -403,8 +403,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ }
+
+ async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
+- if (!async_desc)
+- return ERR_PTR(-ENOMEM);
++ if (!async_desc) {
++ dev_err(adev->dev, "not enough memory for async_desc struct\n");
++ return NULL;
++ }
+
+ async_desc->mux = achan->mux ? ADM_CRCI_CTL_MUX_SEL : 0;
+ async_desc->crci = crci;
+@@ -414,8 +416,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ sizeof(*cple) + 2 * ADM_DESC_ALIGN;
+
+ async_desc->cpl = kzalloc(async_desc->dma_len, GFP_NOWAIT);
+- if (!async_desc->cpl)
++ if (!async_desc->cpl) {
++ dev_err(adev->dev, "not enough memory for cpl struct\n");
+ goto free;
++ }
+
+ async_desc->adev = adev;
+
+@@ -437,8 +441,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl,
+ async_desc->dma_len,
+ DMA_TO_DEVICE);
+- if (dma_mapping_error(adev->dev, async_desc->dma_addr))
++ if (dma_mapping_error(adev->dev, async_desc->dma_addr)) {
++ dev_err(adev->dev, "dma mapping error for cpl\n");
+ goto free;
++ }
+
+ cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl);
+
+@@ -454,7 +460,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+
+ free:
+ kfree(async_desc);
+- return ERR_PTR(-ENOMEM);
++ return NULL;
+ }
+
+ /**
+@@ -494,7 +500,7 @@ static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
+
+ spin_lock_irqsave(&achan->vc.lock, flag);
+ memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config));
+- if (cfg->peripheral_size == sizeof(config))
++ if (cfg->peripheral_size == sizeof(*config))
+ achan->crci = config->crci;
+ spin_unlock_irqrestore(&achan->vc.lock, flag);
+
+diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
+index 2f0d2c68c93c6..fcfcde947b307 100644
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -300,8 +300,6 @@ struct udma_chan {
+
+ struct udma_tx_drain tx_drain;
+
+- u32 bcnt; /* number of bytes completed since the start of the channel */
+-
+ /* Channel configuration parameters */
+ struct udma_chan_config config;
+
+@@ -757,6 +755,20 @@ static void udma_reset_rings(struct udma_chan *uc)
+ }
+ }
+
++static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val)
++{
++ if (uc->desc->dir == DMA_DEV_TO_MEM) {
++ udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
++ udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
++ udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
++ } else {
++ udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
++ udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
++ if (!uc->bchan)
++ udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
++ }
++}
++
+ static void udma_reset_counters(struct udma_chan *uc)
+ {
+ u32 val;
+@@ -790,8 +802,6 @@ static void udma_reset_counters(struct udma_chan *uc)
+ val = udma_rchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG);
+ udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
+ }
+-
+- uc->bcnt = 0;
+ }
+
+ static int udma_reset_chan(struct udma_chan *uc, bool hard)
+@@ -1115,7 +1125,7 @@ static void udma_check_tx_completion(struct work_struct *work)
+ if (uc->desc) {
+ struct udma_desc *d = uc->desc;
+
+- uc->bcnt += d->residue;
++ udma_decrement_byte_counters(uc, d->residue);
+ udma_start(uc);
+ vchan_cookie_complete(&d->vd);
+ break;
+@@ -1168,7 +1178,7 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
+ vchan_cyclic_callback(&d->vd);
+ } else {
+ if (udma_is_desc_really_done(uc, d)) {
+- uc->bcnt += d->residue;
++ udma_decrement_byte_counters(uc, d->residue);
+ udma_start(uc);
+ vchan_cookie_complete(&d->vd);
+ } else {
+@@ -1204,7 +1214,7 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data)
+ vchan_cyclic_callback(&d->vd);
+ } else {
+ /* TODO: figure out the real amount of data */
+- uc->bcnt += d->residue;
++ udma_decrement_byte_counters(uc, d->residue);
+ udma_start(uc);
+ vchan_cookie_complete(&d->vd);
+ }
+@@ -3809,7 +3819,6 @@ static enum dma_status udma_tx_status(struct dma_chan *chan,
+ bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+ }
+
+- bcnt -= uc->bcnt;
+ if (bcnt && !(bcnt % uc->desc->residue))
+ residue = 0;
+ else
+diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
+index fe567be0f118b..804f542be3f28 100644
+--- a/drivers/firmware/efi/libstub/fdt.c
++++ b/drivers/firmware/efi/libstub/fdt.c
+@@ -280,14 +280,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
+ goto fail;
+ }
+
+- /*
+- * Now that we have done our final memory allocation (and free)
+- * we can get the memory map key needed for exit_boot_services().
+- */
+- status = efi_get_memory_map(&map);
+- if (status != EFI_SUCCESS)
+- goto fail_free_new_fdt;
+-
+ status = update_fdt((void *)fdt_addr, fdt_size,
+ (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr,
+ initrd_addr, initrd_size);
+diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
+index adaa492c3d2df..4e2575dfeb908 100644
+--- a/drivers/firmware/google/gsmi.c
++++ b/drivers/firmware/google/gsmi.c
+@@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = {
+ static int gsmi_panic_callback(struct notifier_block *nb,
+ unsigned long reason, void *arg)
+ {
++
++ /*
++ * Panic callbacks are executed with all other CPUs stopped,
++ * so we must not attempt to spin waiting for gsmi_dev.lock
++ * to be released.
++ */
++ if (spin_is_locked(&gsmi_dev.lock))
++ return NOTIFY_DONE;
++
+ gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
+ return NOTIFY_DONE;
+ }
+diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
+index fd1fa55c91130..0914e7328b1a5 100644
+--- a/drivers/fpga/dfl-pci.c
++++ b/drivers/fpga/dfl-pci.c
+@@ -77,12 +77,18 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
+ #define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
+ #define PCIE_DEVICE_ID_SILICOM_PAC_N5010 0x1000
+ #define PCIE_DEVICE_ID_SILICOM_PAC_N5011 0x1001
++#define PCIE_DEVICE_ID_INTEL_DFL 0xbcce
++/* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
++#define PCIE_SUBDEVICE_ID_INTEL_N6000 0x1770
++#define PCIE_SUBDEVICE_ID_INTEL_N6001 0x1771
++#define PCIE_SUBDEVICE_ID_INTEL_C6100 0x17d4
+
+ /* VF Device */
+ #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
+ #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
+ #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
+ #define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
++#define PCIE_DEVICE_ID_INTEL_DFL_VF 0xbccf
+
+ static struct pci_device_id cci_pcie_id_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
+@@ -96,6 +102,18 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
+ {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
+ {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
++ {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++ PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
+ {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
+diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
+index 5498bc337f8b2..b9aae85ba9308 100644
+--- a/drivers/fpga/dfl.c
++++ b/drivers/fpga/dfl.c
+@@ -1866,7 +1866,7 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
+ return -EINVAL;
+
+ fds = memdup_user((void __user *)(arg + sizeof(hdr)),
+- hdr.count * sizeof(s32));
++ array_size(hdr.count, sizeof(s32)));
+ if (IS_ERR(fds))
+ return PTR_ERR(fds);
+
+diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
+index 3a7b78e367011..5858e6339a10b 100644
+--- a/drivers/fsi/fsi-core.c
++++ b/drivers/fsi/fsi-core.c
+@@ -1314,6 +1314,9 @@ int fsi_master_register(struct fsi_master *master)
+
+ mutex_init(&master->scan_lock);
+ master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL);
++ if (master->idx < 0)
++ return master->idx;
++
+ dev_set_name(&master->dev, "fsi%d", master->idx);
+ master->dev.class = &fsi_master_class;
+
+diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c
+index 24292acdbaf84..5f608ef8b53ca 100644
+--- a/drivers/fsi/fsi-master-ast-cf.c
++++ b/drivers/fsi/fsi-master-ast-cf.c
+@@ -1324,12 +1324,14 @@ static int fsi_master_acf_probe(struct platform_device *pdev)
+ }
+ master->cvic = devm_of_iomap(&pdev->dev, np, 0, NULL);
+ if (IS_ERR(master->cvic)) {
++ of_node_put(np);
+ rc = PTR_ERR(master->cvic);
+ dev_err(&pdev->dev, "Error %d mapping CVIC\n", rc);
+ goto err_free;
+ }
+ rc = of_property_read_u32(np, "copro-sw-interrupts",
+ &master->cvic_sw_irq);
++ of_node_put(np);
+ if (rc) {
+ dev_err(&pdev->dev, "Can't find coprocessor SW interrupt\n");
+ goto err_free;
+diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
+index c9cc75fbdfb9d..28c176d038a26 100644
+--- a/drivers/fsi/fsi-occ.c
++++ b/drivers/fsi/fsi-occ.c
+@@ -94,6 +94,7 @@ static int occ_open(struct inode *inode, struct file *file)
+ client->occ = occ;
+ mutex_init(&client->lock);
+ file->private_data = client;
++ get_device(occ->dev);
+
+ /* We allocate a 1-page buffer, make sure it all fits */
+ BUILD_BUG_ON((OCC_CMD_DATA_BYTES + 3) > PAGE_SIZE);
+@@ -197,6 +198,7 @@ static int occ_release(struct inode *inode, struct file *file)
+ {
+ struct occ_client *client = file->private_data;
+
++ put_device(client->occ->dev);
+ free_page((unsigned long)client->buffer);
+ kfree(client);
+
+@@ -493,12 +495,19 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
+ for (i = 1; i < req_len - 2; ++i)
+ checksum += byte_request[i];
+
+- mutex_lock(&occ->occ_lock);
++ rc = mutex_lock_interruptible(&occ->occ_lock);
++ if (rc)
++ return rc;
+
+ occ->client_buffer = response;
+ occ->client_buffer_size = user_resp_len;
+ occ->client_response_size = 0;
+
++ if (!occ->buffer) {
++ rc = -ENOENT;
++ goto done;
++ }
++
+ /*
+ * Get a sequence number and update the counter. Avoid a sequence
+ * number of 0 which would pass the response check below even if the
+@@ -671,10 +680,13 @@ static int occ_remove(struct platform_device *pdev)
+ {
+ struct occ *occ = platform_get_drvdata(pdev);
+
+- kvfree(occ->buffer);
+-
+ misc_deregister(&occ->mdev);
+
++ mutex_lock(&occ->occ_lock);
++ kvfree(occ->buffer);
++ occ->buffer = NULL;
++ mutex_unlock(&occ->occ_lock);
++
+ device_for_each_child(&pdev->dev, NULL, occ_unregister_child);
+
+ ida_simple_remove(&occ_ida, occ->idx);
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index bb50335239ac8..9c976ad7208ef 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -19,6 +19,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_device.h>
+ #include <linux/of_irq.h>
++#include <linux/pinctrl/consumer.h>
+ #include <linux/pinctrl/pinconf-generic.h>
+ #include <linux/regmap.h>
+
+@@ -156,6 +157,12 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
+ unsigned long flags;
+ u32 data = input ? 0 : 1;
+
++
++ if (input)
++ pinctrl_gpio_direction_input(bank->pin_base + offset);
++ else
++ pinctrl_gpio_direction_output(bank->pin_base + offset);
++
+ raw_spin_lock_irqsave(&bank->slock, flags);
+ rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
+diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
+index 6c2256e8474be..679ad054ea4b0 100644
+--- a/drivers/gpu/drm/Kconfig
++++ b/drivers/gpu/drm/Kconfig
+@@ -31,6 +31,7 @@ menuconfig DRM
+ config DRM_MIPI_DBI
+ tristate
+ depends on DRM
++ select DRM_KMS_HELPER
+
+ config DRM_MIPI_DSI
+ bool
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index b7933c2ce765c..491d4846fc02c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -1674,10 +1674,12 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ adev->mode_info.dither_property,
+ AMDGPU_FMT_DITHER_DISABLE);
+
+- if (amdgpu_audio != 0)
++ if (amdgpu_audio != 0) {
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.audio_property,
+ AMDGPU_AUDIO_AUTO);
++ amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
++ }
+
+ subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = true;
+@@ -1799,6 +1801,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.audio_property,
+ AMDGPU_AUDIO_AUTO);
++ amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ }
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.dither_property,
+@@ -1852,6 +1855,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.audio_property,
+ AMDGPU_AUDIO_AUTO);
++ amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ }
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.dither_property,
+@@ -1902,6 +1906,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.audio_property,
+ AMDGPU_AUDIO_AUTO);
++ amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ }
+ drm_object_attach_property(&amdgpu_connector->base.base,
+ adev->mode_info.dither_property,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+index 23998f727c7f9..1a06b8d724f39 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+@@ -38,8 +38,6 @@
+ #include <linux/pci.h>
+ #include <linux/pm_runtime.h>
+ #include <drm/drm_crtc_helper.h>
+-#include <drm/drm_damage_helper.h>
+-#include <drm/drm_drv.h>
+ #include <drm/drm_edid.h>
+ #include <drm/drm_gem_framebuffer_helper.h>
+ #include <drm/drm_fb_helper.h>
+@@ -500,12 +498,6 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
+ .create_handle = drm_gem_fb_create_handle,
+ };
+
+-static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = {
+- .destroy = drm_gem_fb_destroy,
+- .create_handle = drm_gem_fb_create_handle,
+- .dirty = drm_atomic_helper_dirtyfb,
+-};
+-
+ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
+ uint64_t bo_flags)
+ {
+@@ -1108,10 +1100,8 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev,
+ if (ret)
+ goto err;
+
+- if (drm_drv_uses_atomic_modeset(dev))
+- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic);
+- else
+- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
++ ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
++
+ if (ret)
+ goto err;
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 429fcdf28836e..de7144b06e933 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
+ amdgpu_device_baco_exit(drm_dev);
+ }
+ ret = amdgpu_device_resume(drm_dev, false);
+- if (ret)
++ if (ret) {
++ if (amdgpu_device_supports_px(drm_dev))
++ pci_disable_device(pdev);
+ return ret;
++ }
+
+ if (amdgpu_device_supports_px(drm_dev))
+ drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+index 1fd3cbca20a29..718db7d98e5a3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+@@ -211,12 +211,15 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
+ int r;
+
+ /* Wait for PD/PT moves to be completed */
+- dma_resv_for_each_fence(&cursor, bo->tbo.base.resv,
+- DMA_RESV_USAGE_KERNEL, fence) {
++ dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL);
++ dma_resv_for_each_fence_unlocked(&cursor, fence) {
+ r = amdgpu_sync_fence(&p->job->sync, fence);
+- if (r)
++ if (r) {
++ dma_resv_iter_end(&cursor);
+ return r;
++ }
+ }
++ dma_resv_iter_end(&cursor);
+
+ do {
+ ndw = p->num_dw_left;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+index bc11b2de37aeb..a1d26c4d80b8c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+@@ -169,17 +169,17 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
+ uint64_t value;
+ uint32_t tmp;
+
+- /* Disable AGP. */
+- WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
+- WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
+- WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
+-
+ if (!amdgpu_sriov_vf(adev)) {
+ /*
+ * the new L1 policy will block SRIOV guest from writing
+ * these regs, and they will be programed at host.
+ * so skip programing these regs.
+ */
++ /* Disable AGP. */
++ WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
++ WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
++ WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
++
+ /* Program the system aperture low logical page number. */
+ WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ adev->gmc.vram_start >> 18);
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+index 0200cb3a31a49..6a4f3ba14b1d2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+@@ -910,7 +910,8 @@ static int sdma_v6_0_mqd_init(struct amdgpu_device *adev, void *mqd,
+ m->sdmax_rlcx_rb_cntl =
+ order_base_2(prop->queue_size / 4) << SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
+ 1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
+- 4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
++ 4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
++ 1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
+
+ m->sdmax_rlcx_rb_base = lower_32_bits(prop->hqd_base_gpu_addr >> 8);
+ m->sdmax_rlcx_rb_base_hi = upper_32_bits(prop->hqd_base_gpu_addr >> 8);
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
+index 6e564b549b9ff..9c3463b481396 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
+@@ -583,6 +583,10 @@ static int soc21_common_early_init(void *handle)
+ AMD_PG_SUPPORT_JPEG |
+ AMD_PG_SUPPORT_ATHUB |
+ AMD_PG_SUPPORT_MMHUB;
++ if (amdgpu_sriov_vf(adev)) {
++ adev->cg_flags = 0;
++ adev->pg_flags = 0;
++ }
+ adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
+ break;
+ case IP_VERSION(11, 0, 2):
+@@ -625,6 +629,7 @@ static int soc21_common_early_init(void *handle)
+ AMD_CG_SUPPORT_JPEG_MGCG;
+ adev->pg_flags =
+ AMD_PG_SUPPORT_GFX_PG |
++ AMD_PG_SUPPORT_VCN |
+ AMD_PG_SUPPORT_VCN_DPG |
+ AMD_PG_SUPPORT_JPEG;
+ adev->external_rev_id = adev->rev_id + 0x1;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 007a3db69df13..ecb4c3abc6297 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -1242,6 +1242,24 @@ static void init_interrupts(struct device_queue_manager *dqm)
+ dqm->dev->kfd2kgd->init_interrupts(dqm->dev->adev, i);
+ }
+
++static void init_sdma_bitmaps(struct device_queue_manager *dqm)
++{
++ unsigned int num_sdma_queues =
++ min_t(unsigned int, sizeof(dqm->sdma_bitmap)*8,
++ get_num_sdma_queues(dqm));
++ unsigned int num_xgmi_sdma_queues =
++ min_t(unsigned int, sizeof(dqm->xgmi_sdma_bitmap)*8,
++ get_num_xgmi_sdma_queues(dqm));
++
++ if (num_sdma_queues)
++ dqm->sdma_bitmap = GENMASK_ULL(num_sdma_queues-1, 0);
++ if (num_xgmi_sdma_queues)
++ dqm->xgmi_sdma_bitmap = GENMASK_ULL(num_xgmi_sdma_queues-1, 0);
++
++ dqm->sdma_bitmap &= ~get_reserved_sdma_queues_bitmap(dqm);
++ pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
++}
++
+ static int initialize_nocpsch(struct device_queue_manager *dqm)
+ {
+ int pipe, queue;
+@@ -1270,11 +1288,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
+
+ memset(dqm->vmid_pasid, 0, sizeof(dqm->vmid_pasid));
+
+- dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
+- dqm->sdma_bitmap &= ~(get_reserved_sdma_queues_bitmap(dqm));
+- pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
+-
+- dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm));
++ init_sdma_bitmaps(dqm);
+
+ return 0;
+ }
+@@ -1452,9 +1466,6 @@ static int set_sched_resources(struct device_queue_manager *dqm)
+
+ static int initialize_cpsch(struct device_queue_manager *dqm)
+ {
+- uint64_t num_sdma_queues;
+- uint64_t num_xgmi_sdma_queues;
+-
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
+
+ mutex_init(&dqm->lock_hidden);
+@@ -1463,24 +1474,10 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
+ dqm->active_cp_queue_count = 0;
+ dqm->gws_queue_count = 0;
+ dqm->active_runlist = false;
+-
+- num_sdma_queues = get_num_sdma_queues(dqm);
+- if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap))
+- dqm->sdma_bitmap = ULLONG_MAX;
+- else
+- dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1);
+-
+- dqm->sdma_bitmap &= ~(get_reserved_sdma_queues_bitmap(dqm));
+- pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
+-
+- num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm);
+- if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap))
+- dqm->xgmi_sdma_bitmap = ULLONG_MAX;
+- else
+- dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
+-
+ INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
+
++ init_sdma_bitmaps(dqm);
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+index 3ae350220d42e..5c3d216a26633 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -375,7 +375,8 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ << SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
+ q->vmid << SDMA0_QUEUE0_RB_CNTL__RB_VMID__SHIFT |
+ 1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
+- 6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
++ 6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
++ 1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
+
+ m->sdmax_rlcx_rb_base = lower_32_bits(q->queue_address >> 8);
+ m->sdmax_rlcx_rb_base_hi = upper_32_bits(q->queue_address >> 8);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 1efe7fa5bc589..3be70848b2020 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1109,7 +1109,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
+ hw_params.fb[i] = &fb_info->fb[i];
+
+ switch (adev->ip_versions[DCE_HWIP][0]) {
+- case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */
++ case IP_VERSION(3, 1, 3):
++ case IP_VERSION(3, 1, 4):
+ hw_params.dpia_supported = true;
+ hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
+ break;
+@@ -1295,13 +1296,21 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(struct
+
+ if (hpd_rx_offload_wq[i].wq == NULL) {
+ DRM_ERROR("create amdgpu_dm_hpd_rx_offload_wq fail!");
+- return NULL;
++ goto out_err;
+ }
+
+ spin_lock_init(&hpd_rx_offload_wq[i].offload_lock);
+ }
+
+ return hpd_rx_offload_wq;
++
++out_err:
++ for (i = 0; i < max_caps; i++) {
++ if (hpd_rx_offload_wq[i].wq)
++ destroy_workqueue(hpd_rx_offload_wq[i].wq);
++ }
++ kfree(hpd_rx_offload_wq);
++ return NULL;
+ }
+
+ struct amdgpu_stutter_quirk {
+@@ -7490,15 +7499,15 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
+ * We also need vupdate irq for the actual core vblank handling
+ * at end of vblank.
+ */
+- dm_set_vupdate_irq(new_state->base.crtc, true);
+- drm_crtc_vblank_get(new_state->base.crtc);
++ WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0);
++ WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0);
+ DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n",
+ __func__, new_state->base.crtc->base.id);
+ } else if (old_vrr_active && !new_vrr_active) {
+ /* Transition VRR active -> inactive:
+ * Allow vblank irq disable again for fixed refresh rate.
+ */
+- dm_set_vupdate_irq(new_state->base.crtc, false);
++ WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0);
+ drm_crtc_vblank_put(new_state->base.crtc);
+ DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n",
+ __func__, new_state->base.crtc->base.id);
+@@ -8253,23 +8262,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ mutex_unlock(&dm->dc_lock);
+ }
+
+- /* Count number of newly disabled CRTCs for dropping PM refs later. */
+- for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+- new_crtc_state, i) {
+- if (old_crtc_state->active && !new_crtc_state->active)
+- crtc_disable_count++;
+-
+- dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+- dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+-
+- /* For freesync config update on crtc state and params for irq */
+- update_stream_irq_parameters(dm, dm_new_crtc_state);
+-
+- /* Handle vrr on->off / off->on transitions */
+- amdgpu_dm_handle_vrr_transition(dm_old_crtc_state,
+- dm_new_crtc_state);
+- }
+-
+ /**
+ * Enable interrupts for CRTCs that are newly enabled or went through
+ * a modeset. It was intentionally deferred until after the front end
+@@ -8279,16 +8271,29 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+ #ifdef CONFIG_DEBUG_FS
+- bool configure_crc = false;
+ enum amdgpu_dm_pipe_crc_source cur_crc_src;
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+- struct crc_rd_work *crc_rd_wrk = dm->crc_rd_wrk;
++ struct crc_rd_work *crc_rd_wrk;
++#endif
++#endif
++ /* Count number of newly disabled CRTCs for dropping PM refs later. */
++ if (old_crtc_state->active && !new_crtc_state->active)
++ crtc_disable_count++;
++
++ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
++ dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
++
++ /* For freesync config update on crtc state and params for irq */
++ update_stream_irq_parameters(dm, dm_new_crtc_state);
++
++#ifdef CONFIG_DEBUG_FS
++#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
++ crc_rd_wrk = dm->crc_rd_wrk;
+ #endif
+ spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+ cur_crc_src = acrtc->dm_irq_params.crc_src;
+ spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+ #endif
+- dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+
+ if (new_crtc_state->active &&
+ (!old_crtc_state->active ||
+@@ -8296,16 +8301,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ dc_stream_retain(dm_new_crtc_state->stream);
+ acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
+ manage_dm_interrupts(adev, acrtc, true);
++ }
++ /* Handle vrr on->off / off->on transitions */
++ amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state);
+
+ #ifdef CONFIG_DEBUG_FS
++ if (new_crtc_state->active &&
++ (!old_crtc_state->active ||
++ drm_atomic_crtc_needs_modeset(new_crtc_state))) {
+ /**
+ * Frontend may have changed so reapply the CRC capture
+ * settings for the stream.
+ */
+- dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+-
+ if (amdgpu_dm_is_valid_crc_source(cur_crc_src)) {
+- configure_crc = true;
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ if (amdgpu_dm_crc_window_is_activated(crtc)) {
+ spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+@@ -8317,14 +8325,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+ }
+ #endif
+- }
+-
+- if (configure_crc)
+ if (amdgpu_dm_crtc_configure_crc_source(
+ crtc, dm_new_crtc_state, cur_crc_src))
+ DRM_DEBUG_DRIVER("Failed to configure crc source");
+-#endif
++ }
+ }
++#endif
+ }
+
+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, j)
+@@ -9408,10 +9414,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ }
+ }
+ }
+- if (!pre_validate_dsc(state, &dm_state, vars)) {
+- ret = -EINVAL;
+- goto fail;
+- }
+ }
+ #endif
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+@@ -9545,6 +9547,15 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ }
+ }
+
++#if defined(CONFIG_DRM_AMD_DC_DCN)
++ if (dc_resource_is_dsc_encoding_supported(dc)) {
++ if (!pre_validate_dsc(state, &dm_state, vars)) {
++ ret = -EINVAL;
++ goto fail;
++ }
++ }
++#endif
++
+ /* Run this here since we want to validate the streams we created */
+ ret = drm_atomic_helper_check_planes(dev, state);
+ if (ret) {
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+index 8ca10ab3dfc12..26291db0a3cf6 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+@@ -60,11 +60,15 @@ static bool link_supports_psrsu(struct dc_link *link)
+ */
+ void amdgpu_dm_set_psr_caps(struct dc_link *link)
+ {
+- if (!(link->connector_signal & SIGNAL_TYPE_EDP))
++ if (!(link->connector_signal & SIGNAL_TYPE_EDP)) {
++ link->psr_settings.psr_feature_enabled = false;
+ return;
++ }
+
+- if (link->type == dc_connection_none)
++ if (link->type == dc_connection_none) {
++ link->psr_settings.psr_feature_enabled = false;
+ return;
++ }
+
+ if (link->dpcd_caps.psr_info.psr_version == 0) {
+ link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
+index 897105d1c111e..ef0795b14a1fd 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
+@@ -339,29 +339,24 @@ void dcn314_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zs
+ if (!clk_mgr->smu_present)
+ return;
+
+- if (!clk_mgr->base.ctx->dc->debug.enable_z9_disable_interface &&
+- (support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY))
+- support = DCN_ZSTATE_SUPPORT_DISALLOW;
+-
+-
+ // Arg[15:0] = 8/9/0 for Z8/Z9/disallow -> existing bits
+ // Arg[16] = Disallow Z9 -> new bit
+ switch (support) {
+
+ case DCN_ZSTATE_SUPPORT_ALLOW:
+ msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+- param = 9;
++ param = (1 << 10) | (1 << 9) | (1 << 8);
+ break;
+
+ case DCN_ZSTATE_SUPPORT_DISALLOW:
+ msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+- param = 8;
++ param = 0;
+ break;
+
+
+ case DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY:
+ msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+- param = 0x00010008;
++ param = (1 << 10);
+ break;
+
+ default: //DCN_ZSTATE_SUPPORT_UNKNOWN
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index fb22c3d70528e..18d6ee666297b 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2753,11 +2753,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
+ if (update->abm_level)
+ stream->abm_level = *update->abm_level;
+
+- if (update->periodic_interrupt0)
+- stream->periodic_interrupt0 = *update->periodic_interrupt0;
+-
+- if (update->periodic_interrupt1)
+- stream->periodic_interrupt1 = *update->periodic_interrupt1;
++ if (update->periodic_interrupt)
++ stream->periodic_interrupt = *update->periodic_interrupt;
+
+ if (update->gamut_remap)
+ stream->gamut_remap_matrix = *update->gamut_remap;
+@@ -2987,13 +2984,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
+
+ if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
+
+- if (stream_update->periodic_interrupt0 &&
+- dc->hwss.setup_periodic_interrupt)
+- dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE0);
+-
+- if (stream_update->periodic_interrupt1 &&
+- dc->hwss.setup_periodic_interrupt)
+- dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE1);
++ if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt)
++ dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+
+ if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->vrr_infopacket ||
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 52a61b3e5a8b0..755c4f9de6da0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -323,11 +323,13 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
+ struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
+ int i = 0;
+ int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
+- uint8_t visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
++ uint8_t visual_confirm_enabled;
+
+ if (dc == NULL)
+ return false;
+
++ visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
++
+ // Format command.
+ cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
+ cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL;
+@@ -719,7 +721,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
+ // Store the original watermark value for this SubVP config so we can lower it when the
+ // MCLK switch starts
+ wm_val_refclk = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns *
+- dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 / 1000;
++ (dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000) / 1000;
+
+ cmd.fw_assisted_mclk_switch_v2.config_data.watermark_a_cache = wm_val_refclk < 0xFFFF ? wm_val_refclk : 0xFFFF;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+index f87f852d48298..ae0922e98ef77 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+@@ -212,8 +212,7 @@ struct dc_stream_state {
+ /* DMCU info */
+ unsigned int abm_level;
+
+- struct periodic_interrupt_config periodic_interrupt0;
+- struct periodic_interrupt_config periodic_interrupt1;
++ struct periodic_interrupt_config periodic_interrupt;
+
+ /* from core_stream struct */
+ struct dc_context *ctx;
+@@ -283,8 +282,7 @@ struct dc_stream_update {
+ struct dc_info_packet *hdr_static_metadata;
+ unsigned int *abm_level;
+
+- struct periodic_interrupt_config *periodic_interrupt0;
+- struct periodic_interrupt_config *periodic_interrupt1;
++ struct periodic_interrupt_config *periodic_interrupt;
+
+ struct dc_info_packet *vrr_infopacket;
+ struct dc_info_packet *vsc_infopacket;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 5b5d952b2b8cd..bc9b92838ea9f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -3768,7 +3768,7 @@ void dcn10_calc_vupdate_position(
+ {
+ const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
+ int vline_int_offset_from_vupdate =
+- pipe_ctx->stream->periodic_interrupt0.lines_offset;
++ pipe_ctx->stream->periodic_interrupt.lines_offset;
+ int vupdate_offset_from_vsync = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+ int start_position;
+
+@@ -3793,18 +3793,10 @@ void dcn10_calc_vupdate_position(
+ static void dcn10_cal_vline_position(
+ struct dc *dc,
+ struct pipe_ctx *pipe_ctx,
+- enum vline_select vline,
+ uint32_t *start_line,
+ uint32_t *end_line)
+ {
+- enum vertical_interrupt_ref_point ref_point = INVALID_POINT;
+-
+- if (vline == VLINE0)
+- ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point;
+- else if (vline == VLINE1)
+- ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point;
+-
+- switch (ref_point) {
++ switch (pipe_ctx->stream->periodic_interrupt.ref_point) {
+ case START_V_UPDATE:
+ dcn10_calc_vupdate_position(
+ dc,
+@@ -3813,7 +3805,9 @@ static void dcn10_cal_vline_position(
+ end_line);
+ break;
+ case START_V_SYNC:
+- // Suppose to do nothing because vsync is 0;
++ // vsync is line 0 so start_line is just the requested line offset
++ *start_line = pipe_ctx->stream->periodic_interrupt.lines_offset;
++ *end_line = *start_line + 2;
+ break;
+ default:
+ ASSERT(0);
+@@ -3823,24 +3817,15 @@ static void dcn10_cal_vline_position(
+
+ void dcn10_setup_periodic_interrupt(
+ struct dc *dc,
+- struct pipe_ctx *pipe_ctx,
+- enum vline_select vline)
++ struct pipe_ctx *pipe_ctx)
+ {
+ struct timing_generator *tg = pipe_ctx->stream_res.tg;
++ uint32_t start_line = 0;
++ uint32_t end_line = 0;
+
+- if (vline == VLINE0) {
+- uint32_t start_line = 0;
+- uint32_t end_line = 0;
++ dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
+
+- dcn10_cal_vline_position(dc, pipe_ctx, vline, &start_line, &end_line);
+-
+- tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
+-
+- } else if (vline == VLINE1) {
+- pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1(
+- tg,
+- pipe_ctx->stream->periodic_interrupt1.lines_offset);
+- }
++ tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
+ }
+
+ void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+index 9ae07c77fdc01..0ef7bf7ddb75e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+@@ -175,8 +175,7 @@ void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
+ void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
+ void dcn10_setup_periodic_interrupt(
+ struct dc *dc,
+- struct pipe_ctx *pipe_ctx,
+- enum vline_select vline);
++ struct pipe_ctx *pipe_ctx);
+ enum dc_status dcn10_set_clock(struct dc *dc,
+ enum dc_clock_type clock_type,
+ uint32_t clk_khz,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+index 23621ff08c905..52fb2bf3d5781 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+@@ -150,9 +150,9 @@ static void dcn31_hpo_dp_stream_enc_dp_blank(
+ * 10us*5000=50ms. This covers 41.7ms of minimum 24 Hz mode +
+ * a little more because we may not trust delay accuracy.
+ */
+- //REG_WAIT(DP_SYM32_ENC_VID_STREAM_CONTROL,
+- // VID_STREAM_STATUS, 0,
+- // 10, 5000);
++ REG_WAIT(DP_SYM32_ENC_VID_STREAM_CONTROL,
++ VID_STREAM_STATUS, 0,
++ 10, 5000);
+
+ /* Disable SDP tranmission */
+ REG_UPDATE(DP_SYM32_ENC_SDP_CONTROL,
+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 44ac1c2aabf5e..6d721fadcbee6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -881,7 +881,8 @@ static const struct dc_plane_cap plane_cap = {
+ };
+
+ static const struct dc_debug_options debug_defaults_drv = {
+- .disable_z10 = true, /*hw not support it*/
++ .disable_z10 = false,
++ .enable_z9_disable_interface = true,
+ .disable_dmcu = true,
+ .force_abm_enable = false,
+ .timing_trace = false,
+@@ -1719,6 +1720,7 @@ static struct clock_source *dcn30_clock_source_create(
+ }
+
+ BREAK_TO_DEBUGGER();
++ kfree(clk_src);
+ return NULL;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
+index 2038cbda33f74..1fbb9fbf84549 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
+@@ -179,6 +179,7 @@ static struct hubp_funcs dcn32_hubp_funcs = {
+ .hubp_init = hubp3_init,
+ .set_unbounded_requesting = hubp31_set_unbounded_requesting,
+ .hubp_soft_reset = hubp31_soft_reset,
++ .hubp_set_flip_int = hubp1_set_flip_int,
+ .hubp_in_blank = hubp1_in_blank,
+ .hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
+ .phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
+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 344fe7535df5b..c72166e096bad 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -1001,6 +1001,10 @@ void dcn32_init_hw(struct dc *dc)
+ dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
+ dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+ }
++
++ /* Enable support for ODM and windowed MPO if policy flag is set */
++ if (dc->debug.enable_single_display_2to1_odm_policy)
++ dc->config.enable_windowed_mpo_odm = true;
+ }
+
+ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+index 6ca288fb5fb9e..2d46bc527b218 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+@@ -26,12 +26,12 @@
+ #include "bw_fixed.h"
+
+
+-#define MIN_I64 \
+- (int64_t)(-(1LL << 63))
+-
+ #define MAX_I64 \
+ (int64_t)((1ULL << 63) - 1)
+
++#define MIN_I64 \
++ (-MAX_I64 - 1)
++
+ #define FRACTIONAL_PART_MASK \
+ ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1)
+
+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 e573e706430df..b9d3a4000c3d4 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
+@@ -2199,6 +2199,7 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
+ if ((int)(dcn3_2_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
+ && dc->bb_overrides.urgent_latency_ns) {
+ dcn3_2_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
++ dcn3_2_soc.urgent_latency_pixel_data_only_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ }
+
+ if ((int)(dcn3_2_soc.dram_clock_change_latency_us * 1000)
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 6980f698eb23a..52525833a99b9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -733,6 +733,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ mode_lib->vba.FCLKChangeLatency, v->UrgentLatency,
+ mode_lib->vba.SREnterPlusExitTime);
+
++ memset(&v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe, 0, sizeof(DmlPipe));
++
+ v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dppclk = mode_lib->vba.DPPCLK[k];
+ v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dispclk = mode_lib->vba.DISPCLK;
+ v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index c87091683b5dc..b6369758b4912 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -489,6 +489,7 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
+ if ((int)(dcn3_21_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
+ && dc->bb_overrides.urgent_latency_ns) {
+ dcn3_21_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
++ dcn3_21_soc.urgent_latency_pixel_data_only_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ }
+
+ if ((int)(dcn3_21_soc.dram_clock_change_latency_us * 1000)
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index ccb3c719fc4de..ac94dba72c18b 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -32,11 +32,6 @@
+ #include "inc/hw/link_encoder.h"
+ #include "core_status.h"
+
+-enum vline_select {
+- VLINE0,
+- VLINE1
+-};
+-
+ struct pipe_ctx;
+ struct dc_state;
+ struct dc_stream_status;
+@@ -116,8 +111,7 @@ struct hw_sequencer_funcs {
+ int group_index, int group_size,
+ struct pipe_ctx *grouped_pipes[]);
+ void (*setup_periodic_interrupt)(struct dc *dc,
+- struct pipe_ctx *pipe_ctx,
+- enum vline_select vline);
++ struct pipe_ctx *pipe_ctx);
+ void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
+ struct dc_crtc_timing_adjust adjust);
+ void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+index 59172acb97380..292f533d8cf0d 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+@@ -235,7 +235,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
+ crtc->state->event = NULL;
+ drm_crtc_send_vblank_event(crtc, event);
+ } else {
+- DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
++ DRM_WARN("CRTC[%d]: FLIP happened but no pending commit.\n",
+ drm_crtc_index(&kcrtc->base));
+ }
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+@@ -286,7 +286,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,
+ komeda_crtc_do_flush(crtc, old);
+ }
+
+-static void
++void
+ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
+ struct completion *input_flip_done)
+ {
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+index 93b7f09b96ca9..327051bba5b68 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+@@ -69,6 +69,25 @@ static const struct drm_driver komeda_kms_driver = {
+ .minor = 1,
+ };
+
++static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state)
++{
++ struct drm_device *dev = state->dev;
++ struct komeda_kms_dev *kms = to_kdev(dev);
++ int i;
++
++ for (i = 0; i < kms->n_crtcs; i++) {
++ struct komeda_crtc *kcrtc = &kms->crtcs[i];
++
++ if (kcrtc->base.state->active) {
++ struct completion *flip_done = NULL;
++ if (kcrtc->base.state->event)
++ flip_done = kcrtc->base.state->event->base.completion;
++ komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done);
++ }
++ }
++ drm_atomic_helper_commit_hw_done(state);
++}
++
+ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
+ {
+ struct drm_device *dev = old_state->dev;
+@@ -81,7 +100,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+- drm_atomic_helper_commit_hw_done(old_state);
++ komeda_kms_atomic_commit_hw_done(old_state);
+
+ drm_atomic_helper_wait_for_flip_done(dev, old_state);
+
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+index 7889e380ab23c..7339339ef6b87 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+@@ -183,6 +183,8 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);
+
+ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
+ struct komeda_events *evts);
++void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
++ struct completion *input_flip_done);
+
+ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
+ void komeda_kms_detach(struct komeda_kms_dev *kms);
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index a031a0cd1f181..94de73cbeb2dd 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -394,10 +394,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
+ #else
+ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ {
+- unsigned int offset = adv7511->type == ADV7533 ?
+- ADV7533_REG_CEC_OFFSET : 0;
+-
+- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
+ ADV7511_CEC_CTRL_POWER_DOWN);
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+index 0b266f28f150f..99964f5a5457b 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+@@ -359,7 +359,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ goto err_cec_alloc;
+ }
+
+- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0);
+ /* cec soft reset */
+ regmap_write(adv7511->regmap_cec,
+ ADV7511_REG_CEC_SOFT_RESET + offset, 0x01);
+@@ -386,7 +386,7 @@ err_cec_alloc:
+ dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
+ ret);
+ err_cec_parse_dt:
+- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
+ ADV7511_CEC_CTRL_POWER_DOWN);
+ return ret == -EPROBE_DEFER ? ret : 0;
+ }
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 38bf28720f3a2..6031bdd923420 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1340,9 +1340,6 @@ static int adv7511_remove(struct i2c_client *i2c)
+ {
+ struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+
+- i2c_unregister_device(adv7511->i2c_cec);
+- clk_disable_unprepare(adv7511->cec_clk);
+-
+ adv7511_uninit_regulators(adv7511);
+
+ drm_bridge_remove(&adv7511->bridge);
+@@ -1350,6 +1347,8 @@ static int adv7511_remove(struct i2c_client *i2c)
+ adv7511_audio_exit(adv7511);
+
+ cec_unregister_adapter(adv7511->cec_adap);
++ i2c_unregister_device(adv7511->i2c_cec);
++ clk_disable_unprepare(adv7511->cec_clk);
+
+ i2c_unregister_device(adv7511->i2c_packet);
+ i2c_unregister_device(adv7511->i2c_edid);
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index d1f1d525aeb6d..79fc7a50b4976 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -1642,6 +1642,7 @@ static int anx7625_parse_dt(struct device *dev,
+ anx7625_get_swing_setting(dev, pdata);
+
+ pdata->is_dpi = 0; /* default dsi mode */
++ of_node_put(pdata->mipi_host_node);
+ pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0);
+ if (!pdata->mipi_host_node) {
+ DRM_DEV_ERROR(dev, "fail to get internal panel.\n");
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index 4b673c4792d77..a09d1a39ab0ae 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -2954,6 +2954,9 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,
+
+ it6505_int_mask_enable(it6505);
+ it6505_video_reset(it6505);
++
++ it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
++ DP_SET_POWER_D0);
+ }
+
+ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
+@@ -2965,9 +2968,9 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
+ DRM_DEV_DEBUG_DRIVER(dev, "start");
+
+ if (it6505->powered) {
+- it6505_video_disable(it6505);
+ it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
+ DP_SET_POWER_D3);
++ it6505_video_disable(it6505);
+ }
+ }
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 8a60e83482a04..5fccacc159f00 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -813,13 +813,14 @@ static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt961
+
+ drm_connector_helper_add(<9611->connector,
+ <9611_bridge_connector_helper_funcs);
+- drm_connector_attach_encoder(<9611->connector, bridge->encoder);
+
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found");
+ return -ENODEV;
+ }
+
++ drm_connector_attach_encoder(<9611->connector, bridge->encoder);
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+index cce98bf2a4e73..72248a565579e 100644
+--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+@@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void)
+ * This check is to avoid both the drivers
+ * removing the bridge in their remove() function
+ */
+- if (!ge_b850v3_lvds_ptr)
++ if (!ge_b850v3_lvds_ptr ||
++ !ge_b850v3_lvds_ptr->stdp2690_i2c ||
++ !ge_b850v3_lvds_ptr->stdp4028_i2c)
+ goto out;
+
+ drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
+diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
+index 31e88cb39f8a0..49107a6cdac18 100644
+--- a/drivers/gpu/drm/bridge/parade-ps8640.c
++++ b/drivers/gpu/drm/bridge/parade-ps8640.c
+@@ -631,8 +631,8 @@ static int ps8640_probe(struct i2c_client *client)
+ if (!ps_bridge)
+ return -ENOMEM;
+
+- ps_bridge->supplies[0].supply = "vdd33";
+- ps_bridge->supplies[1].supply = "vdd12";
++ ps_bridge->supplies[0].supply = "vdd12";
++ ps_bridge->supplies[1].supply = "vdd33";
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
+ ps_bridge->supplies);
+ if (ret)
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 25a60eb4d67c7..40d8ca37f5bc8 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -3096,6 +3096,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
+ {
+ struct dw_hdmi *hdmi = dev_id;
+ u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
++ enum drm_connector_status status = connector_status_unknown;
+
+ intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
+ phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
+@@ -3134,13 +3135,15 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
+ cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+ mutex_unlock(&hdmi->cec_notifier_mutex);
+ }
+- }
+
+- if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+- enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
+- ? connector_status_connected
+- : connector_status_disconnected;
++ if (phy_stat & HDMI_PHY_HPD)
++ status = connector_status_connected;
++
++ if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE)))
++ status = connector_status_disconnected;
++ }
+
++ if (status != connector_status_unknown) {
+ dev_dbg(hdmi->dev, "EVENT=%s\n",
+ status == connector_status_connected ?
+ "plugin" : "plugout");
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 02bd757a89874..1dc107f13645b 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -2010,9 +2010,10 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
+
+ for_each_endpoint_of_node(dev->of_node, node) {
+ of_graph_parse_endpoint(node, &endpoint);
+- if (endpoint.port > 2)
++ if (endpoint.port > 2) {
++ of_node_put(node);
+ return -EINVAL;
+-
++ }
+ mode |= BIT(endpoint.port);
+ }
+
+diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
+index e5bab236b3ae5..4c0c4e3d1e206 100644
+--- a/drivers/gpu/drm/display/drm_dp_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_helper.c
+@@ -2638,17 +2638,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
+ struct drm_dp_phy_test_params *data, u8 dp_rev)
+ {
+ int err, i;
+- u8 link_config[2];
+ u8 test_pattern;
+
+- link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate);
+- link_config[1] = data->num_lanes;
+- if (data->enhanced_frame_cap)
+- link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+- err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2);
+- if (err < 0)
+- return err;
+-
+ test_pattern = data->phy_pattern;
+ if (dp_rev < 0x12) {
+ test_pattern = (test_pattern << 2) &
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 57e65423e50d2..7a94a5288e8d7 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -4907,14 +4907,14 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
+ seq_printf(m, "dpcd: %*ph\n", DP_RECEIVER_CAP_SIZE, buf);
+
+ ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);
+- if (ret) {
++ if (ret != 2) {
+ seq_printf(m, "faux/mst read failed\n");
+ goto out;
+ }
+ seq_printf(m, "faux/mst: %*ph\n", 2, buf);
+
+ ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);
+- if (ret) {
++ if (ret != 1) {
+ seq_printf(m, "mst ctrl read failed\n");
+ goto out;
+ }
+@@ -4922,7 +4922,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
+
+ /* dump the standard OUI branch header */
+ ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);
+- if (ret) {
++ if (ret != DP_BRANCH_OUI_HEADER_SIZE) {
+ seq_printf(m, "branch oui read failed\n");
+ goto out;
+ }
+diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
+index 6abf7a2407e93..1545c50fd1c8f 100644
+--- a/drivers/gpu/drm/drm_bridge.c
++++ b/drivers/gpu/drm/drm_bridge.c
+@@ -847,8 +847,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
+ struct drm_connector_state *conn_state,
+ u32 out_bus_fmt)
+ {
++ unsigned int i, num_in_bus_fmts = 0;
+ struct drm_bridge_state *cur_state;
+- unsigned int num_in_bus_fmts, i;
+ struct drm_bridge *prev_bridge;
+ u32 *in_bus_fmts;
+ int ret;
+@@ -969,7 +969,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
+ struct drm_connector *conn = conn_state->connector;
+ struct drm_encoder *encoder = bridge->encoder;
+ struct drm_bridge_state *last_bridge_state;
+- unsigned int i, num_out_bus_fmts;
++ unsigned int i, num_out_bus_fmts = 0;
+ struct drm_bridge *last_bridge;
+ u32 *out_bus_fmts;
+ int ret = 0;
+diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
+index 8faad23dc1d81..ca2a6e6101dc8 100644
+--- a/drivers/gpu/drm/drm_ioctl.c
++++ b/drivers/gpu/drm/drm_ioctl.c
+@@ -472,7 +472,13 @@ EXPORT_SYMBOL(drm_invalid_op);
+ */
+ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
+ {
+- int len;
++ size_t len;
++
++ /* don't attempt to copy a NULL pointer */
++ if (WARN_ONCE(!value, "BUG: the value to copy was not set!")) {
++ *buf_len = 0;
++ return 0;
++ }
+
+ /* don't overflow userbuf */
+ len = strlen(value);
+diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
+index c40bde96cfdf0..c317ee9fa4458 100644
+--- a/drivers/gpu/drm/drm_mipi_dsi.c
++++ b/drivers/gpu/drm/drm_mipi_dsi.c
+@@ -346,6 +346,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
+ {
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
++ mipi_dsi_detach(dsi);
+ mipi_dsi_device_unregister(dsi);
+
+ return 0;
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index fc1728d46ac2a..8a0c0e0bb5bd2 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -103,6 +103,12 @@ static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = {
+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+ };
+
++static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = {
++ .width = 1080,
++ .height = 1920,
++ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
++};
++
+ static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
+ .width = 1200,
+ .height = 1920,
+@@ -128,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ },
+ .driver_data = (void *)&lcd800x1280_rightside_up,
++ }, { /* Anbernic Win600 */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"),
++ },
++ .driver_data = (void *)&lcd720x1280_rightside_up,
+ }, { /* Asus T100HA */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+@@ -152,6 +164,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"),
+ },
+ .driver_data = (void *)&lcd800x1280_rightside_up,
++ }, { /* AYA NEO AIR */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
++ DMI_MATCH(DMI_BOARD_NAME, "AIR"),
++ },
++ .driver_data = (void *)&lcd1080x1920_leftside_up,
+ }, { /* AYA NEO NEXT */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
+index 6e80162632ddf..86a22c3766e52 100644
+--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
++++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
+@@ -2300,7 +2300,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
+ min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
+ /*
+- * HACK. Currently for TGL platforms we calculate
++ * HACK. Currently for TGL/DG2 platforms we calculate
+ * min_cdclk initially based on pixel_rate divided
+ * by 2, accounting for also plane requirements,
+ * however in some cases the lowest possible CDCLK
+@@ -2308,7 +2308,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
+ * Explicitly stating here that this seems to be currently
+ * rather a Hack, than final solution.
+ */
+- if (IS_TIGERLAKE(dev_priv)) {
++ if (IS_TIGERLAKE(dev_priv) || IS_DG2(dev_priv)) {
+ /*
+ * Clamp to max_cdclk_freq in case pixel rate is higher,
+ * in order not to break an 8K, but still leave W/A at place.
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
+index 0bcde53c50c61..1e29b1e6d1868 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
+@@ -1387,14 +1387,8 @@ kill_engines(struct i915_gem_engines *engines, bool exit, bool persistent)
+ */
+ for_each_gem_engine(ce, engines, it) {
+ struct intel_engine_cs *engine;
+- bool skip = false;
+
+- if (exit)
+- skip = intel_context_set_exiting(ce);
+- else if (!persistent)
+- skip = intel_context_exit_nonpersistent(ce, NULL);
+-
+- if (skip)
++ if ((exit || !persistent) && intel_context_revoke(ce))
+ continue; /* Already marked. */
+
+ /*
+diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+index 1bb766c79dcbe..5aaacc53fa4ca 100644
+--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
++++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+@@ -247,6 +247,7 @@ err_scratch1:
+ i915_gem_object_put(vm->scratch[1]);
+ err_scratch0:
+ i915_gem_object_put(vm->scratch[0]);
++ vm->scratch[0] = NULL;
+ return ret;
+ }
+
+@@ -268,9 +269,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
+ gen6_ppgtt_free_pd(ppgtt);
+ free_scratch(vm);
+
+- mutex_destroy(&ppgtt->flush);
++ if (ppgtt->base.pd)
++ free_pd(&ppgtt->base.vm, ppgtt->base.pd);
+
+- free_pd(&ppgtt->base.vm, ppgtt->base.pd);
++ mutex_destroy(&ppgtt->flush);
+ }
+
+ static void pd_vma_bind(struct i915_address_space *vm,
+@@ -449,19 +451,17 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
+
+ err = gen6_ppgtt_init_scratch(ppgtt);
+ if (err)
+- goto err_free;
++ goto err_put;
+
+ ppgtt->base.pd = gen6_alloc_top_pd(ppgtt);
+ if (IS_ERR(ppgtt->base.pd)) {
+ err = PTR_ERR(ppgtt->base.pd);
+- goto err_scratch;
++ goto err_put;
+ }
+
+ return &ppgtt->base;
+
+-err_scratch:
+- free_scratch(&ppgtt->base.vm);
+-err_free:
+- kfree(ppgtt);
++err_put:
++ i915_vm_put(&ppgtt->base.vm);
+ return ERR_PTR(err);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+index c7bd5d71b03e5..2128b7a72a257 100644
+--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
++++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+@@ -196,7 +196,10 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
+ if (intel_vgpu_active(vm->i915))
+ gen8_ppgtt_notify_vgt(ppgtt, false);
+
+- __gen8_ppgtt_cleanup(vm, ppgtt->pd, gen8_pd_top_count(vm), vm->top);
++ if (ppgtt->pd)
++ __gen8_ppgtt_cleanup(vm, ppgtt->pd,
++ gen8_pd_top_count(vm), vm->top);
++
+ free_scratch(vm);
+ }
+
+@@ -803,8 +806,10 @@ static int gen8_init_scratch(struct i915_address_space *vm)
+ struct drm_i915_gem_object *obj;
+
+ obj = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K);
+- if (IS_ERR(obj))
++ if (IS_ERR(obj)) {
++ ret = PTR_ERR(obj);
+ goto free_scratch;
++ }
+
+ ret = map_pt_dma(vm, obj);
+ if (ret) {
+@@ -823,7 +828,8 @@ static int gen8_init_scratch(struct i915_address_space *vm)
+ free_scratch:
+ while (i--)
+ i915_gem_object_put(vm->scratch[i]);
+- return -ENOMEM;
++ vm->scratch[0] = NULL;
++ return ret;
+ }
+
+ static int gen8_preallocate_top_level_pdp(struct i915_ppgtt *ppgtt)
+@@ -901,6 +907,7 @@ err_pd:
+ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ unsigned long lmem_pt_obj_flags)
+ {
++ struct i915_page_directory *pd;
+ struct i915_ppgtt *ppgtt;
+ int err;
+
+@@ -946,21 +953,7 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ ppgtt->vm.alloc_scratch_dma = alloc_pt_dma;
+ }
+
+- err = gen8_init_scratch(&ppgtt->vm);
+- if (err)
+- goto err_free;
+-
+- ppgtt->pd = gen8_alloc_top_pd(&ppgtt->vm);
+- if (IS_ERR(ppgtt->pd)) {
+- err = PTR_ERR(ppgtt->pd);
+- goto err_free_scratch;
+- }
+-
+- if (!i915_vm_is_4lvl(&ppgtt->vm)) {
+- err = gen8_preallocate_top_level_pdp(ppgtt);
+- if (err)
+- goto err_free_pd;
+- }
++ ppgtt->vm.pte_encode = gen8_pte_encode;
+
+ ppgtt->vm.bind_async_flags = I915_VMA_LOCAL_BIND;
+ ppgtt->vm.insert_entries = gen8_ppgtt_insert;
+@@ -971,22 +964,31 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc;
+ ppgtt->vm.clear_range = gen8_ppgtt_clear;
+ ppgtt->vm.foreach = gen8_ppgtt_foreach;
++ ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
+
+- ppgtt->vm.pte_encode = gen8_pte_encode;
++ err = gen8_init_scratch(&ppgtt->vm);
++ if (err)
++ goto err_put;
++
++ pd = gen8_alloc_top_pd(&ppgtt->vm);
++ if (IS_ERR(pd)) {
++ err = PTR_ERR(pd);
++ goto err_put;
++ }
++ ppgtt->pd = pd;
++
++ if (!i915_vm_is_4lvl(&ppgtt->vm)) {
++ err = gen8_preallocate_top_level_pdp(ppgtt);
++ if (err)
++ goto err_put;
++ }
+
+ if (intel_vgpu_active(gt->i915))
+ gen8_ppgtt_notify_vgt(ppgtt, true);
+
+- ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
+-
+ return ppgtt;
+
+-err_free_pd:
+- __gen8_ppgtt_cleanup(&ppgtt->vm, ppgtt->pd,
+- gen8_pd_top_count(&ppgtt->vm), ppgtt->vm.top);
+-err_free_scratch:
+- free_scratch(&ppgtt->vm);
+-err_free:
+- kfree(ppgtt);
++err_put:
++ i915_vm_put(&ppgtt->vm);
+ return ERR_PTR(err);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
+index 654a092ed3d69..e94365b08f1ef 100644
+--- a/drivers/gpu/drm/i915/gt/intel_context.c
++++ b/drivers/gpu/drm/i915/gt/intel_context.c
+@@ -614,13 +614,12 @@ bool intel_context_ban(struct intel_context *ce, struct i915_request *rq)
+ return ret;
+ }
+
+-bool intel_context_exit_nonpersistent(struct intel_context *ce,
+- struct i915_request *rq)
++bool intel_context_revoke(struct intel_context *ce)
+ {
+ bool ret = intel_context_set_exiting(ce);
+
+ if (ce->ops->revoke)
+- ce->ops->revoke(ce, rq, ce->engine->props.preempt_timeout_ms);
++ ce->ops->revoke(ce, NULL, ce->engine->props.preempt_timeout_ms);
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
+index 8e2d70630c49e..be09fb2e883a5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_context.h
++++ b/drivers/gpu/drm/i915/gt/intel_context.h
+@@ -329,8 +329,7 @@ static inline bool intel_context_set_exiting(struct intel_context *ce)
+ return test_and_set_bit(CONTEXT_EXITING, &ce->flags);
+ }
+
+-bool intel_context_exit_nonpersistent(struct intel_context *ce,
+- struct i915_request *rq);
++bool intel_context_revoke(struct intel_context *ce);
+
+ static inline bool
+ intel_context_force_single_submission(const struct intel_context *ce)
+diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
+index 15a915bb4088e..e717160135d7d 100644
+--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
++++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
+@@ -1267,10 +1267,16 @@ bool i915_ggtt_resume_vm(struct i915_address_space *vm)
+ atomic_read(&vma->flags) & I915_VMA_BIND_MASK;
+
+ GEM_BUG_ON(!was_bound);
+- if (!retained_ptes)
++ if (!retained_ptes) {
++ /*
++ * Clear the bound flags of the vma resource to allow
++ * ptes to be repopulated.
++ */
++ vma->resource->bound_flags = 0;
+ vma->ops->bind_vma(vm, NULL, vma->resource,
+ obj ? obj->cache_level : 0,
+ was_bound);
++ }
+ if (obj) { /* only used during resume => exclusive access */
+ write_domain_objs |= fetch_and_zero(&obj->write_domain);
+ obj->read_domains |= I915_GEM_DOMAIN_GTT;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
+index b67831833c9a3..2eaeba14319e9 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
+@@ -405,6 +405,9 @@ void free_scratch(struct i915_address_space *vm)
+ {
+ int i;
+
++ if (!vm->scratch[0])
++ return;
++
+ for (i = 0; i <= vm->top; i++)
+ i915_gem_object_put(vm->scratch[i]);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index 3e91f44829e92..fe179146d51b9 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -684,7 +684,7 @@ static int __guc_add_request(struct intel_guc *guc, struct i915_request *rq)
+ * Corner case where requests were sitting in the priority list or a
+ * request resubmitted after the context was banned.
+ */
+- if (unlikely(intel_context_is_banned(ce))) {
++ if (unlikely(!intel_context_is_schedulable(ce))) {
+ i915_request_put(i915_request_mark_eio(rq));
+ intel_engine_signal_breadcrumbs(ce->engine);
+ return 0;
+@@ -870,15 +870,15 @@ static int guc_wq_item_append(struct intel_guc *guc,
+ struct i915_request *rq)
+ {
+ struct intel_context *ce = request_to_scheduling_context(rq);
+- int ret = 0;
++ int ret;
+
+- if (likely(!intel_context_is_banned(ce))) {
+- ret = __guc_wq_item_append(rq);
++ if (unlikely(!intel_context_is_schedulable(ce)))
++ return 0;
+
+- if (unlikely(ret == -EBUSY)) {
+- guc->stalled_request = rq;
+- guc->submission_stall_reason = STALL_MOVE_LRC_TAIL;
+- }
++ ret = __guc_wq_item_append(rq);
++ if (unlikely(ret == -EBUSY)) {
++ guc->stalled_request = rq;
++ guc->submission_stall_reason = STALL_MOVE_LRC_TAIL;
+ }
+
+ return ret;
+@@ -897,7 +897,7 @@ static bool multi_lrc_submit(struct i915_request *rq)
+ * submitting all the requests generated in parallel.
+ */
+ return test_bit(I915_FENCE_FLAG_SUBMIT_PARALLEL, &rq->fence.flags) ||
+- intel_context_is_banned(ce);
++ !intel_context_is_schedulable(ce);
+ }
+
+ static int guc_dequeue_one_context(struct intel_guc *guc)
+@@ -966,7 +966,7 @@ register_context:
+ struct intel_context *ce = request_to_scheduling_context(last);
+
+ if (unlikely(!ctx_id_mapped(guc, ce->guc_id.id) &&
+- !intel_context_is_banned(ce))) {
++ intel_context_is_schedulable(ce))) {
+ ret = try_context_registration(ce, false);
+ if (unlikely(ret == -EPIPE)) {
+ goto deadlk;
+@@ -1576,7 +1576,7 @@ static void guc_reset_state(struct intel_context *ce, u32 head, bool scrub)
+ {
+ struct intel_engine_cs *engine = __context_to_physical_engine(ce);
+
+- if (intel_context_is_banned(ce))
++ if (!intel_context_is_schedulable(ce))
+ return;
+
+ GEM_BUG_ON(!intel_context_is_pinned(ce));
+@@ -4434,12 +4434,12 @@ static void guc_handle_context_reset(struct intel_guc *guc,
+ {
+ trace_intel_context_reset(ce);
+
+- if (likely(!intel_context_is_banned(ce))) {
++ if (likely(intel_context_is_schedulable(ce))) {
+ capture_error_state(guc, ce);
+ guc_context_replay(ce);
+ } else {
+ drm_info(&guc_to_gt(guc)->i915->drm,
+- "Ignoring context reset notification of banned context 0x%04X on %s",
++ "Ignoring context reset notification of exiting context 0x%04X on %s",
+ ce->guc_id.id, ce->engine->name);
+ }
+ }
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 9fe4b583cc28a..bf01e0191e542 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -5308,10 +5308,22 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
+ modifier == I915_FORMAT_MOD_4_TILED ||
+ modifier == I915_FORMAT_MOD_Yf_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+- modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
++ modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
+ wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
+ wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+- modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
++ modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
++ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
++ modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
+ wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
+
+ wp->width = width;
+diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
+index bd4ca11d3ff53..86b90d0f5780a 100644
+--- a/drivers/gpu/drm/meson/meson_drv.c
++++ b/drivers/gpu/drm/meson/meson_drv.c
+@@ -388,10 +388,14 @@ static void meson_drv_unbind(struct device *dev)
+ drm_dev_unregister(drm);
+ drm_kms_helper_poll_fini(drm);
+ drm_atomic_helper_shutdown(drm);
+- component_unbind_all(dev, drm);
+ free_irq(priv->vsync_irq, drm);
+ drm_dev_put(drm);
+
++ meson_encoder_hdmi_remove(priv);
++ meson_encoder_cvbs_remove(priv);
++
++ component_unbind_all(dev, drm);
++
+ if (priv->afbcd.ops)
+ priv->afbcd.ops->exit(priv);
+ }
+@@ -493,6 +497,13 @@ static int meson_drv_probe(struct platform_device *pdev)
+ return 0;
+ };
+
++static int meson_drv_remove(struct platform_device *pdev)
++{
++ component_master_del(&pdev->dev, &meson_drv_master_ops);
++
++ return 0;
++}
++
+ static struct meson_drm_match_data meson_drm_gxbb_data = {
+ .compat = VPU_COMPATIBLE_GXBB,
+ };
+@@ -530,6 +541,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
+
+ static struct platform_driver meson_drm_platform_driver = {
+ .probe = meson_drv_probe,
++ .remove = meson_drv_remove,
+ .shutdown = meson_drv_shutdown,
+ .driver = {
+ .name = "meson-drm",
+diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
+index 177dac3ca3bea..c62ee358456fa 100644
+--- a/drivers/gpu/drm/meson/meson_drv.h
++++ b/drivers/gpu/drm/meson/meson_drv.h
+@@ -25,6 +25,12 @@ enum vpu_compatible {
+ VPU_COMPATIBLE_G12A = 3,
+ };
+
++enum {
++ MESON_ENC_CVBS = 0,
++ MESON_ENC_HDMI,
++ MESON_ENC_LAST,
++};
++
+ struct meson_drm_match_data {
+ enum vpu_compatible compat;
+ struct meson_afbcd_ops *afbcd_ops;
+@@ -51,6 +57,7 @@ struct meson_drm {
+ struct drm_crtc *crtc;
+ struct drm_plane *primary_plane;
+ struct drm_plane *overlay_plane;
++ void *encoders[MESON_ENC_LAST];
+
+ const struct meson_drm_soc_limits *limits;
+
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+index 8110a6e39320f..5675bc2a92cf8 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+@@ -281,5 +281,18 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
+ }
+ drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
+
++ priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
++
+ return 0;
+ }
++
++void meson_encoder_cvbs_remove(struct meson_drm *priv)
++{
++ struct meson_encoder_cvbs *meson_encoder_cvbs;
++
++ if (priv->encoders[MESON_ENC_CVBS]) {
++ meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
++ drm_bridge_remove(&meson_encoder_cvbs->bridge);
++ drm_bridge_remove(meson_encoder_cvbs->next_bridge);
++ }
++}
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+index 61d9d183ce7fb..09710fec3c660 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+@@ -25,5 +25,6 @@ struct meson_cvbs_mode {
+ extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
+
+ int meson_encoder_cvbs_init(struct meson_drm *priv);
++void meson_encoder_cvbs_remove(struct meson_drm *priv);
+
+ #endif /* __MESON_VENC_CVBS_H */
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index 2f616c55c2718..53231bfdf7e24 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -452,6 +452,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ meson_encoder_hdmi->cec_notifier = notifier;
+ }
+
++ priv->encoders[MESON_ENC_HDMI] = meson_encoder_hdmi;
++
+ dev_dbg(priv->dev, "HDMI encoder initialized\n");
+
+ return 0;
+@@ -460,3 +462,14 @@ err_put_node:
+ of_node_put(remote);
+ return ret;
+ }
++
++void meson_encoder_hdmi_remove(struct meson_drm *priv)
++{
++ struct meson_encoder_hdmi *meson_encoder_hdmi;
++
++ if (priv->encoders[MESON_ENC_HDMI]) {
++ meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
++ drm_bridge_remove(&meson_encoder_hdmi->bridge);
++ drm_bridge_remove(meson_encoder_hdmi->next_bridge);
++ }
++}
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.h b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
+index ed19494f09563..a6cd38eb5f71c 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.h
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
+@@ -8,5 +8,6 @@
+ #define __MESON_ENCODER_HDMI_H
+
+ int meson_encoder_hdmi_init(struct meson_drm *priv);
++void meson_encoder_hdmi_remove(struct meson_drm *priv);
+
+ #endif /* __MESON_ENCODER_HDMI_H */
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+index 008e1420e6e55..c99c7a218ddb3 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+@@ -384,12 +384,9 @@ static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms)
+ struct icc_path *path1;
+ struct drm_device *dev = dpu_kms->dev;
+ struct device *dpu_dev = dev->dev;
+- struct device *mdss_dev = dpu_dev->parent;
+
+- /* Interconnects are a part of MDSS device tree binding, not the
+- * MDP/DPU device. */
+- path0 = of_icc_get(mdss_dev, "mdp0-mem");
+- path1 = of_icc_get(mdss_dev, "mdp1-mem");
++ path0 = msm_icc_get(dpu_dev, "mdp0-mem");
++ path1 = msm_icc_get(dpu_dev, "mdp1-mem");
+
+ if (IS_ERR_OR_NULL(path0))
+ return PTR_ERR_OR_ZERO(path0);
+@@ -826,12 +823,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
+ _dpu_kms_mmu_destroy(dpu_kms);
+
+ if (dpu_kms->catalog) {
+- for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+- u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
+-
+- if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) {
+- dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]);
+- dpu_kms->hw_vbif[vbif_idx] = NULL;
++ for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
++ if (dpu_kms->hw_vbif[i]) {
++ dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]);
++ dpu_kms->hw_vbif[i] = NULL;
+ }
+ }
+ }
+@@ -1113,7 +1108,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
+ for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+ u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
+
+- dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx,
++ dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx,
+ dpu_kms->vbif[vbif_idx], dpu_kms->catalog);
+ if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) {
+ rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]);
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+index 21d20373eb8b3..a18fb649301c9 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+@@ -11,6 +11,14 @@
+ #include "dpu_hw_vbif.h"
+ #include "dpu_trace.h"
+
++static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx)
++{
++ if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif))
++ return dpu_kms->hw_vbif[vbif_idx];
++
++ return NULL;
++}
++
+ /**
+ * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
+ * @vbif: Pointer to hardware vbif driver
+@@ -148,20 +156,15 @@ exit:
+ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+ struct dpu_vbif_set_ot_params *params)
+ {
+- struct dpu_hw_vbif *vbif = NULL;
++ struct dpu_hw_vbif *vbif;
+ struct dpu_hw_mdp *mdp;
+ bool forced_on = false;
+ u32 ot_lim;
+- int ret, i;
++ int ret;
+
+ mdp = dpu_kms->hw_mdp;
+
+- for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+- if (dpu_kms->hw_vbif[i] &&
+- dpu_kms->hw_vbif[i]->idx == params->vbif_idx)
+- vbif = dpu_kms->hw_vbif[i];
+- }
+-
++ vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+ if (!vbif || !mdp) {
+ DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
+ vbif != NULL, mdp != NULL);
+@@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+ struct dpu_vbif_set_qos_params *params)
+ {
+- struct dpu_hw_vbif *vbif = NULL;
++ struct dpu_hw_vbif *vbif;
+ struct dpu_hw_mdp *mdp;
+ bool forced_on = false;
+ const struct dpu_vbif_qos_tbl *qos_tbl;
+@@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+ }
+ mdp = dpu_kms->hw_mdp;
+
+- for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+- if (dpu_kms->hw_vbif[i] &&
+- dpu_kms->hw_vbif[i]->idx == params->vbif_idx) {
+- vbif = dpu_kms->hw_vbif[i];
+- break;
+- }
+- }
++ vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+
+ if (!vbif || !vbif->cap) {
+ DPU_ERROR("invalid vbif %d\n", params->vbif_idx);
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+index d2a48caf9d27e..b0d21838a1343 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+@@ -902,12 +902,9 @@ fail:
+
+ static int mdp5_setup_interconnect(struct platform_device *pdev)
+ {
+- /* Interconnects are a part of MDSS device tree binding, not the
+- * MDP5 device. */
+- struct device *mdss_dev = pdev->dev.parent;
+- struct icc_path *path0 = of_icc_get(mdss_dev, "mdp0-mem");
+- struct icc_path *path1 = of_icc_get(mdss_dev, "mdp1-mem");
+- struct icc_path *path_rot = of_icc_get(mdss_dev, "rotator-mem");
++ struct icc_path *path0 = msm_icc_get(&pdev->dev, "mdp0-mem");
++ struct icc_path *path1 = msm_icc_get(&pdev->dev, "mdp1-mem");
++ struct icc_path *path_rot = msm_icc_get(&pdev->dev, "rotator-mem");
+
+ if (IS_ERR(path0))
+ return PTR_ERR(path0);
+diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
+index 7257515871a9f..676279d0ca8d9 100644
+--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
+@@ -431,7 +431,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog,
+
+ if (rate == link_rate_hbr3)
+ pixel_div = 6;
+- else if (rate == 1620000 || rate == 270000)
++ else if (rate == 162000 || rate == 270000)
+ pixel_div = 2;
+ else if (rate == link_rate_hbr2)
+ pixel_div = 4;
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index 16884db272deb..0759e2d99f59c 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -1244,10 +1244,15 @@ void msm_drv_shutdown(struct platform_device *pdev)
+ struct msm_drm_private *priv = platform_get_drvdata(pdev);
+ struct drm_device *drm = priv ? priv->dev : NULL;
+
+- if (!priv || !priv->kms)
+- return;
+-
+- drm_atomic_helper_shutdown(drm);
++ /*
++ * Shutdown the hw if we're far enough along where things might be on.
++ * If we run this too early, we'll end up panicking in any variety of
++ * places. Since we don't register the drm device until late in
++ * msm_drm_init, drm_dev->registered is used as an indicator that the
++ * shutdown will be successful.
++ */
++ if (drm && drm->registered)
++ drm_atomic_helper_shutdown(drm);
+ }
+
+ static struct platform_driver msm_platform_driver = {
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index b3689a2d27d72..80da0d3cfdc13 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -433,6 +433,8 @@ void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
+ phys_addr_t *size);
+ void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name);
+
++struct icc_path *msm_icc_get(struct device *dev, const char *name);
++
+ #define msm_writel(data, addr) writel((data), (addr))
+ #define msm_readl(addr) readl((addr))
+
+diff --git a/drivers/gpu/drm/msm/msm_io_utils.c b/drivers/gpu/drm/msm/msm_io_utils.c
+index 7b504617833ad..d02cd29ce8299 100644
+--- a/drivers/gpu/drm/msm/msm_io_utils.c
++++ b/drivers/gpu/drm/msm/msm_io_utils.c
+@@ -5,6 +5,8 @@
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
++#include <linux/interconnect.h>
++
+ #include "msm_drv.h"
+
+ /*
+@@ -124,3 +126,23 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
+ work->worker = worker;
+ kthread_init_work(&work->work, fn);
+ }
++
++struct icc_path *msm_icc_get(struct device *dev, const char *name)
++{
++ struct device *mdss_dev = dev->parent;
++ struct icc_path *path;
++
++ path = of_icc_get(dev, name);
++ if (path)
++ return path;
++
++ /*
++ * If there are no interconnects attached to the corresponding device
++ * node, of_icc_get() will return NULL.
++ *
++ * If the MDP5/DPU device node doesn't have interconnects, lookup the
++ * path in the parent (MDSS) device.
++ */
++ return of_icc_get(mdss_dev, name);
++
++}
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
+index e29175e4b44ce..07a327ad5e2a8 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -281,8 +281,10 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain,
+ break;
+ }
+
+- if (WARN_ON(pi < 0))
++ if (WARN_ON(pi < 0)) {
++ kfree(nvbo);
+ return ERR_PTR(-EINVAL);
++ }
+
+ /* Disable compression if suitable settings couldn't be found. */
+ if (nvbo->comp && !vmm->page[pi].comp) {
+diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
+index 43a9d1e1cf719..8100c75ee7319 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -504,7 +504,8 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
+ connector->interlace_allowed =
+ nv_encoder->caps.dp_interlace;
+ else
+- connector->interlace_allowed = true;
++ connector->interlace_allowed =
++ drm->client.device.info.family < NV_DEVICE_INFO_V0_VOLTA;
+ connector->doublescan_allowed = true;
+ } else
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS ||
+diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
+index 347488685f745..9608121e49b7e 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
++++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
+@@ -71,7 +71,6 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev,
+ ret = nouveau_bo_init(nvbo, size, align, NOUVEAU_GEM_DOMAIN_GART,
+ sg, robj);
+ if (ret) {
+- nouveau_bo_ref(NULL, &nvbo);
+ obj = ERR_PTR(ret);
+ goto unlock;
+ }
+diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
+index 0399f3390a0ad..c4febb8619103 100644
+--- a/drivers/gpu/drm/omapdrm/dss/dss.c
++++ b/drivers/gpu/drm/omapdrm/dss/dss.c
+@@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
+ default:
+ break;
+ }
++ of_node_put(port);
+ }
+ }
+
+@@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss)
+ default:
+ break;
+ }
++ of_node_put(port);
+ }
+
+ return 0;
+
+ error:
++ of_node_put(port);
+ __dss_uninit_ports(dss, i);
+ return r;
+ }
+diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
+index a9043eacce97c..a582ddd583c24 100644
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -165,8 +165,8 @@ config DRM_PANEL_ILITEK_IL9322
+ config DRM_PANEL_ILITEK_ILI9341
+ tristate "Ilitek ILI9341 240x320 QVGA panels"
+ depends on OF && SPI
+- depends on DRM_KMS_HELPER
+- depends on DRM_GEM_CMA_HELPER
++ select DRM_KMS_HELPER
++ select DRM_GEM_DMA_HELPER
+ depends on BACKLIGHT_CLASS_DEVICE
+ select DRM_MIPI_DBI
+ help
+diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c
+index efb01a5545740..1b436b75fd396 100644
+--- a/drivers/gpu/drm/pl111/pl111_versatile.c
++++ b/drivers/gpu/drm/pl111/pl111_versatile.c
+@@ -404,6 +404,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np,
+ if (of_device_is_compatible(child, "arm,pl111")) {
+ has_coretile_clcd = true;
+ ct_clcd = child;
++ of_node_put(child);
+ break;
+ }
+ if (of_device_is_compatible(child, "arm,hdlcd")) {
+diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c
+index 98583bf56044b..eefaba3aaea20 100644
+--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
++++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
+@@ -111,6 +111,21 @@ static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
+ return dst_pitch * drm_rect_height(clip);
+ }
+
++static u32 *le32buf_to_cpu(struct kunit *test, const u32 *buf, size_t buf_size)
++{
++ u32 *dst = NULL;
++ int n;
++
++ dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
++ if (!dst)
++ return NULL;
++
++ for (n = 0; n < buf_size; n++)
++ dst[n] = le32_to_cpu((__force __le32)buf[n]);
++
++ return dst;
++}
++
+ static void xrgb8888_to_rgb332_case_desc(struct xrgb8888_to_rgb332_case *t,
+ char *desc)
+ {
+@@ -125,6 +140,7 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
+ const struct xrgb8888_to_rgb332_case *params = test->param_value;
+ size_t dst_size;
+ __u8 *dst = NULL;
++ __u32 *src = NULL;
+
+ struct drm_framebuffer fb = {
+ .format = drm_format_info(DRM_FORMAT_XRGB8888),
+@@ -138,8 +154,11 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
+ dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
+
+- drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, params->xrgb8888,
+- &fb, ¶ms->clip);
++ src = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE);
++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, src);
++
++ drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, src, &fb,
++ ¶ms->clip);
+ KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0);
+ }
+
+diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
+index 82364a0a7b180..490fa92a4dce3 100644
+--- a/drivers/gpu/drm/tiny/bochs.c
++++ b/drivers/gpu/drm/tiny/bochs.c
+@@ -309,6 +309,8 @@ static void bochs_hw_fini(struct drm_device *dev)
+ static void bochs_hw_blank(struct bochs_device *bochs, bool blank)
+ {
+ DRM_DEBUG_DRIVER("hw_blank %d\n", blank);
++ /* enable color bit (so VGA_IS1_RC access works) */
++ bochs_vga_writeb(bochs, VGA_MIS_W, VGA_MIS_COLOR);
+ /* discard ar_flip_flop */
+ (void)bochs_vga_readb(bochs, VGA_IS1_RC);
+ /* blank or unblank; we need only update index and set 0x20 */
+diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
+index e67c40a48fb46..b43e6ff06310f 100644
+--- a/drivers/gpu/drm/udl/udl_modeset.c
++++ b/drivers/gpu/drm/udl/udl_modeset.c
+@@ -382,9 +382,6 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
+
+ udl_handle_damage(fb, &shadow_plane_state->data[0], 0, 0, fb->width, fb->height);
+
+- if (!crtc_state->mode_changed)
+- return;
+-
+ /* enable display */
+ udl_crtc_write_mode_to_hw(crtc);
+ }
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index 292d1b6a01b6f..6b8dfa1e7650d 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -267,6 +267,13 @@ static void vc4_match_add_drivers(struct device *dev,
+ }
+ }
+
++static void vc4_component_unbind_all(void *ptr)
++{
++ struct vc4_dev *vc4 = ptr;
++
++ component_unbind_all(vc4->dev, &vc4->base);
++}
++
+ static const struct of_device_id vc4_dma_range_matches[] = {
+ { .compatible = "brcm,bcm2711-hvs" },
+ { .compatible = "brcm,bcm2835-hvs" },
+@@ -310,6 +317,7 @@ static int vc4_drm_bind(struct device *dev)
+ if (IS_ERR(vc4))
+ return PTR_ERR(vc4);
+ vc4->is_vc5 = is_vc5;
++ vc4->dev = dev;
+
+ drm = &vc4->base;
+ platform_set_drvdata(pdev, drm);
+@@ -360,6 +368,10 @@ static int vc4_drm_bind(struct device *dev)
+ if (ret)
+ return ret;
+
++ ret = devm_add_action_or_reset(dev, vc4_component_unbind_all, vc4);
++ if (ret)
++ return ret;
++
+ ret = vc4_plane_create_additional_planes(drm);
+ if (ret)
+ goto unbind_all;
+@@ -380,8 +392,6 @@ static int vc4_drm_bind(struct device *dev)
+ return 0;
+
+ unbind_all:
+- component_unbind_all(dev, drm);
+-
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index 1beb96b77b8c6..950056b83843b 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -76,6 +76,7 @@ struct vc4_perfmon {
+
+ struct vc4_dev {
+ struct drm_device base;
++ struct device *dev;
+
+ bool is_vc5;
+
+diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
+index 11fc3d6f66b1e..4e2250b8fa23e 100644
+--- a/drivers/gpu/drm/vc4/vc4_vec.c
++++ b/drivers/gpu/drm/vc4/vc4_vec.c
+@@ -256,7 +256,7 @@ static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec)
+ static const struct drm_display_mode ntsc_mode = {
+ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
+ 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
+- 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0,
++ 480, 480 + 7, 480 + 7 + 6, 525, 0,
+ DRM_MODE_FLAG_INTERLACE)
+ };
+
+@@ -278,7 +278,7 @@ static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec)
+ static const struct drm_display_mode pal_mode = {
+ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
+ 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
+- 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0,
++ 576, 576 + 4, 576 + 4 + 6, 625, 0,
+ DRM_MODE_FLAG_INTERLACE)
+ };
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
+index 5c7f198c07120..9ea7611a9e0fc 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_display.c
++++ b/drivers/gpu/drm/virtio/virtgpu_display.c
+@@ -349,6 +349,8 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
+ vgdev->ddev->mode_config.max_width = XRES_MAX;
+ vgdev->ddev->mode_config.max_height = YRES_MAX;
+
++ vgdev->ddev->mode_config.fb_modifiers_not_supported = true;
++
+ for (i = 0 ; i < vgdev->num_scanouts; ++i)
+ vgdev_output_init(vgdev, i);
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
+index 580a788098361..7db48d17ee3a8 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
+@@ -228,8 +228,10 @@ int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs)
+
+ for (i = 0; i < objs->nents; ++i) {
+ ret = dma_resv_reserve_fences(objs->objs[i]->resv, 1);
+- if (ret)
++ if (ret) {
++ virtio_gpu_array_unlock_resv(objs);
+ return ret;
++ }
+ }
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index 9b2702116f93e..5d05093014ac3 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -47,7 +47,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev,
+ struct virtio_gpu_fence_event *e = NULL;
+ int ret;
+
+- if (!(vfpriv->ring_idx_mask & (1 << ring_idx)))
++ if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx)))
+ return 0;
+
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
+@@ -168,7 +168,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
+ * array contains any fence from a foreign context.
+ */
+ ret = 0;
+- if (!dma_fence_match_context(in_fence, vgdev->fence_drv.context))
++ if (!dma_fence_match_context(in_fence, fence_ctx + ring_idx))
+ ret = dma_fence_wait(in_fence, true);
+
+ dma_fence_put(in_fence);
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 1cc8f3fc8e4ba..75a159df0af66 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -170,6 +170,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+ shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
+ if (IS_ERR(shmem->pages)) {
+ drm_gem_shmem_unpin(&bo->base);
++ shmem->pages = NULL;
+ return PTR_ERR(shmem->pages);
+ }
+
+@@ -248,6 +249,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+
+ ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
+ if (ret != 0) {
++ if (fence)
++ virtio_gpu_array_unlock_resv(objs);
+ virtio_gpu_array_put_free(objs);
+ virtio_gpu_free_object(&shmem_obj->base);
+ return ret;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
+index 6d3cc9e238a4a..7148f3813d8bd 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
+@@ -266,14 +266,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
+ }
+
+ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
+- struct drm_plane_state *old_state)
++ struct drm_plane_state *state)
+ {
+ struct virtio_gpu_framebuffer *vgfb;
+
+- if (!plane->state->fb)
++ if (!state->fb)
+ return;
+
+- vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
++ vgfb = to_virtio_gpu_framebuffer(state->fb);
+ if (vgfb->fence) {
+ dma_fence_put(&vgfb->fence->f);
+ vgfb->fence = NULL;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index b7529b2b98832..1262fd0b3bef3 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -597,7 +597,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
+ bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo);
+
+- if (use_dma_api)
++ if (virtio_gpu_is_shmem(bo) && use_dma_api)
+ dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
+ shmem->pages, DMA_TO_DEVICE);
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+index 2aceac7856e21..089046fa21bea 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+@@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
+
+ if (desc_len < 0) {
+ atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
++ __free_page(page);
+ return -EFAULT;
+ }
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 6ce92830b5d1f..c4308d4988dc0 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -1141,6 +1141,12 @@ config HID_TOPSEED
+ Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
+ CLLRCMCE remote control.
+
++config HID_TOPRE
++ tristate "Topre REALFORCE keyboards"
++ depends on HID
++ help
++ Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
++
+ config HID_THINGM
+ tristate "ThingM blink(1) USB RGB LED"
+ depends on HID
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index b0bef80981394..bccaec0d77d36 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -123,6 +123,7 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
+ obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
+ obj-$(CONFIG_HID_TIVO) += hid-tivo.o
+ obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
++obj-$(CONFIG_HID_TOPRE) += hid-topre.o
+ obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
+ obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o
+ hid-uclogic-objs := hid-uclogic-core.o \
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+index 70436f9fad2f2..33e039e1e01d4 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+@@ -110,6 +110,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
+ amd_sfh1_1_set_desc_ops(mp2_ops);
+
+ cl_data->num_hid_devices = amd_sfh_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
++ if (cl_data->num_hid_devices == 0)
++ return -ENODEV;
+
+ INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
+ INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index f80d6193fca6e..50bab12d9476f 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -1231,6 +1231,9 @@
+ #define USB_DEVICE_ID_TIVO_SLIDE 0x1201
+ #define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
+
++#define USB_VENDOR_ID_TOPRE 0x0853
++#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108 0x0148
++
+ #define USB_VENDOR_ID_TOPSEED 0x0766
+ #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 2e72922e36f56..91a4d3fc30e08 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1186,7 +1186,7 @@ static void mt_touch_report(struct hid_device *hid,
+ int contact_count = -1;
+
+ /* sticky fingers release in progress, abort */
+- if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
++ if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+ return;
+
+ scantime = *app->scantime;
+@@ -1267,7 +1267,7 @@ static void mt_touch_report(struct hid_device *hid,
+ del_timer(&td->release_timer);
+ }
+
+- clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
++ clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
+
+ static int mt_touch_input_configured(struct hid_device *hdev,
+@@ -1699,11 +1699,11 @@ static void mt_expired_timeout(struct timer_list *t)
+ * An input report came in just before we release the sticky fingers,
+ * it will take care of the sticky fingers.
+ */
+- if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
++ if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+ return;
+ if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
+ mt_release_contacts(hdev);
+- clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
++ clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
+
+ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
+index 6028af3c3aae5..c3774a468b229 100644
+--- a/drivers/hid/hid-nintendo.c
++++ b/drivers/hid/hid-nintendo.c
+@@ -760,12 +760,31 @@ static int joycon_read_stick_calibration(struct joycon_ctlr *ctlr, u16 cal_addr,
+ cal_y->max = cal_y->center + y_max_above;
+ cal_y->min = cal_y->center - y_min_below;
+
+- return 0;
++ /* check if calibration values are plausible */
++ if (cal_x->min >= cal_x->center || cal_x->center >= cal_x->max ||
++ cal_y->min >= cal_y->center || cal_y->center >= cal_y->max)
++ ret = -EINVAL;
++
++ return ret;
+ }
+
+ static const u16 DFLT_STICK_CAL_CEN = 2000;
+ static const u16 DFLT_STICK_CAL_MAX = 3500;
+ static const u16 DFLT_STICK_CAL_MIN = 500;
++static void joycon_use_default_calibration(struct hid_device *hdev,
++ struct joycon_stick_cal *cal_x,
++ struct joycon_stick_cal *cal_y,
++ const char *stick, int ret)
++{
++ hid_warn(hdev,
++ "Failed to read %s stick cal, using defaults; e=%d\n",
++ stick, ret);
++
++ cal_x->center = cal_y->center = DFLT_STICK_CAL_CEN;
++ cal_x->max = cal_y->max = DFLT_STICK_CAL_MAX;
++ cal_x->min = cal_y->min = DFLT_STICK_CAL_MIN;
++}
++
+ static int joycon_request_calibration(struct joycon_ctlr *ctlr)
+ {
+ u16 left_stick_addr = JC_CAL_FCT_DATA_LEFT_ADDR;
+@@ -793,38 +812,24 @@ static int joycon_request_calibration(struct joycon_ctlr *ctlr)
+ &ctlr->left_stick_cal_x,
+ &ctlr->left_stick_cal_y,
+ true);
+- if (ret) {
+- hid_warn(ctlr->hdev,
+- "Failed to read left stick cal, using dflts; e=%d\n",
+- ret);
+-
+- ctlr->left_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+- ctlr->left_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+- ctlr->left_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+
+- ctlr->left_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+- ctlr->left_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+- ctlr->left_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+- }
++ if (ret)
++ joycon_use_default_calibration(ctlr->hdev,
++ &ctlr->left_stick_cal_x,
++ &ctlr->left_stick_cal_y,
++ "left", ret);
+
+ /* read the right stick calibration data */
+ ret = joycon_read_stick_calibration(ctlr, right_stick_addr,
+ &ctlr->right_stick_cal_x,
+ &ctlr->right_stick_cal_y,
+ false);
+- if (ret) {
+- hid_warn(ctlr->hdev,
+- "Failed to read right stick cal, using dflts; e=%d\n",
+- ret);
+-
+- ctlr->right_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+- ctlr->right_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+- ctlr->right_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+
+- ctlr->right_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+- ctlr->right_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+- ctlr->right_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+- }
++ if (ret)
++ joycon_use_default_calibration(ctlr->hdev,
++ &ctlr->right_stick_cal_x,
++ &ctlr->right_stick_cal_y,
++ "right", ret);
+
+ hid_dbg(ctlr->hdev, "calibration:\n"
+ "l_x_c=%d l_x_max=%d l_x_min=%d\n"
+diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
+index 26373b82fe812..6da80e442fdd1 100644
+--- a/drivers/hid/hid-roccat.c
++++ b/drivers/hid/hid-roccat.c
+@@ -257,6 +257,8 @@ int roccat_report_event(int minor, u8 const *data)
+ if (!new_value)
+ return -ENOMEM;
+
++ mutex_lock(&device->cbuf_lock);
++
+ report = &device->cbuf[device->cbuf_end];
+
+ /* passing NULL is safe */
+@@ -276,6 +278,8 @@ int roccat_report_event(int minor, u8 const *data)
+ reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
+ }
+
++ mutex_unlock(&device->cbuf_lock);
++
+ wake_up_interruptible(&device->wait);
+ return 0;
+ }
+diff --git a/drivers/hid/hid-topre.c b/drivers/hid/hid-topre.c
+new file mode 100644
+index 0000000000000..88a91cdad5f80
+--- /dev/null
++++ b/drivers/hid/hid-topre.c
+@@ -0,0 +1,49 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * HID driver for Topre REALFORCE Keyboards
++ *
++ * Copyright (c) 2022 Harry Stern <harry@harrystern.net>
++ *
++ * Based on the hid-macally driver
++ */
++
++#include <linux/hid.h>
++#include <linux/module.h>
++
++#include "hid-ids.h"
++
++MODULE_AUTHOR("Harry Stern <harry@harrystern.net>");
++MODULE_DESCRIPTION("REALFORCE R2 Keyboard driver");
++MODULE_LICENSE("GPL");
++
++/*
++ * Fix the REALFORCE R2's non-boot interface's report descriptor to match the
++ * events it's actually sending. It claims to send array events but is instead
++ * sending variable events.
++ */
++static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
++ unsigned int *rsize)
++{
++ if (*rsize >= 119 && rdesc[69] == 0x29 && rdesc[70] == 0xe7 &&
++ rdesc[71] == 0x81 && rdesc[72] == 0x00) {
++ hid_info(hdev,
++ "fixing up Topre REALFORCE keyboard report descriptor\n");
++ rdesc[72] = 0x02;
++ }
++ return rdesc;
++}
++
++static const struct hid_device_id topre_id_table[] = {
++ { HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
++ USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
++ { }
++};
++MODULE_DEVICE_TABLE(hid, topre_id_table);
++
++static struct hid_driver topre_driver = {
++ .name = "topre",
++ .id_table = topre_id_table,
++ .report_fixup = topre_report_fixup,
++};
++
++module_hid_driver(topre_driver);
+diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
+index 47a17375c7fce..ff46604ef1d8c 100644
+--- a/drivers/hid/hid-uclogic-core.c
++++ b/drivers/hid/hid-uclogic-core.c
+@@ -153,6 +153,7 @@ static int uclogic_input_configured(struct hid_device *hdev,
+ suffix = "Pad";
+ break;
+ case HID_DG_PEN:
++ case HID_DG_DIGITIZER:
+ suffix = "Pen";
+ break;
+ case HID_CP_CONSUMER_CONTROL:
+diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
+index 3d68e8b0784d0..81ca22398ed55 100644
+--- a/drivers/hid/hid-uclogic-rdesc.c
++++ b/drivers/hid/hid-uclogic-rdesc.c
+@@ -1113,7 +1113,7 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
+ memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
+ p[sizeof(pen_head)] < param_num) {
+ v = param_list[p[sizeof(pen_head)]];
+- put_unaligned(cpu_to_le32(v), (s32 *)p);
++ put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p);
+ p += sizeof(pen_head) + 1;
+ } else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
+ p[sizeof(btn_head)] < param_num) {
+diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
+index 21f11a5b965b1..49ffd808d17ff 100644
+--- a/drivers/hsi/clients/ssi_protocol.c
++++ b/drivers/hsi/clients/ssi_protocol.c
+@@ -931,6 +931,7 @@ static int ssip_pn_open(struct net_device *dev)
+ if (err < 0) {
+ dev_err(&cl->device, "Register HSI port event failed (%d)\n",
+ err);
++ hsi_release_port(cl);
+ return err;
+ }
+ dev_dbg(&cl->device, "Configuring SSI port\n");
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index 44a3f5660c109..eb98201583185 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -524,6 +524,7 @@ static int ssi_probe(struct platform_device *pd)
+ if (!childpdev) {
+ err = -ENODEV;
+ dev_err(&pd->dev, "failed to create ssi controller port\n");
++ of_node_put(child);
+ goto out3;
+ }
+ }
+diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c
+index a0cb5be246e1c..b9495b720f1bd 100644
+--- a/drivers/hsi/controllers/omap_ssi_port.c
++++ b/drivers/hsi/controllers/omap_ssi_port.c
+@@ -230,10 +230,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch)
+ if (msg->ttype == HSI_MSG_READ) {
+ err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents,
+ DMA_FROM_DEVICE);
+- if (err < 0) {
++ if (!err) {
+ dev_dbg(&ssi->device, "DMA map SG failed !\n");
+ pm_runtime_put_autosuspend(omap_port->pdev);
+- return err;
++ return -EIO;
+ }
+ csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT |
+ SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT |
+@@ -247,10 +247,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch)
+ } else {
+ err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents,
+ DMA_TO_DEVICE);
+- if (err < 0) {
++ if (!err) {
+ dev_dbg(&ssi->device, "DMA map SG failed !\n");
+ pm_runtime_put_autosuspend(omap_port->pdev);
+- return err;
++ return -EIO;
+ }
+ csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT |
+ SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT |
+diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c
+index d64be48f1ef6c..b60ec95b5edbf 100644
+--- a/drivers/hwmon/gsc-hwmon.c
++++ b/drivers/hwmon/gsc-hwmon.c
+@@ -267,6 +267,7 @@ gsc_hwmon_get_devtree_pdata(struct device *dev)
+ pdata->nchannels = nchannels;
+
+ /* fan controller base address */
++ of_node_get(dev->parent->of_node);
+ fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan");
+ if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) {
+ of_node_put(fan);
+diff --git a/drivers/hwmon/occ/p9_sbe.c b/drivers/hwmon/occ/p9_sbe.c
+index c1e0a1d96cd47..f3791a589b01b 100644
+--- a/drivers/hwmon/occ/p9_sbe.c
++++ b/drivers/hwmon/occ/p9_sbe.c
+@@ -14,6 +14,8 @@
+
+ #include "common.h"
+
++#define OCC_CHECKSUM_RETRIES 3
++
+ struct p9_sbe_occ {
+ struct occ occ;
+ bool sbe_error;
+@@ -80,18 +82,23 @@ done:
+ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len,
+ void *resp, size_t resp_len)
+ {
++ size_t original_resp_len = resp_len;
+ struct p9_sbe_occ *ctx = to_p9_sbe_occ(occ);
+- int rc;
++ int rc, i;
+
+- rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len);
+- if (rc < 0) {
++ for (i = 0; i < OCC_CHECKSUM_RETRIES; ++i) {
++ rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len);
++ if (rc >= 0)
++ break;
+ if (resp_len) {
+ if (p9_sbe_occ_save_ffdc(ctx, resp, resp_len))
+ sysfs_notify(&occ->bus_dev->kobj, NULL,
+ bin_attr_ffdc.attr.name);
++ return rc;
+ }
+-
+- return rc;
++ if (rc != -EBADE)
++ return rc;
++ resp_len = original_resp_len;
+ }
+
+ switch (((struct occ_response *)resp)->return_status) {
+diff --git a/drivers/hwmon/pmbus/mp2888.c b/drivers/hwmon/pmbus/mp2888.c
+index 8ecd4adfef40e..24e5194706cf6 100644
+--- a/drivers/hwmon/pmbus/mp2888.c
++++ b/drivers/hwmon/pmbus/mp2888.c
+@@ -34,7 +34,7 @@ struct mp2888_data {
+ int curr_sense_gain;
+ };
+
+-#define to_mp2888_data(x) container_of(x, struct mp2888_data, info)
++#define to_mp2888_data(x) container_of(x, struct mp2888_data, info)
+
+ static int mp2888_read_byte_data(struct i2c_client *client, int page, int reg)
+ {
+@@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,
+ * - Kcs is the DrMOS current sense gain of power stage, which is obtained from the
+ * register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS
+ * (data->curr_sense_gain):
+- * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A.
++ * 00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A.
+ * - Rcs is the internal phase current sense resistor. This parameter depends on hardware
+ * assembly. By default it is set to 1kΩ. In case of different assembly, user should
+ * scale this parameter by dividing it by Rcs.
+@@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,
+ * because sampling of current occurrence of bit weight has a big deviation, especially for
+ * light load.
+ */
+- ret = DIV_ROUND_CLOSEST(ret * 100 - 9800, data->curr_sense_gain);
+- ret = (data->phase_curr_resolution) ? ret * 2 : ret;
++ ret = DIV_ROUND_CLOSEST(ret * 200 - 19600, data->curr_sense_gain);
+ /* Scale according to total current resolution. */
+- ret = (data->total_curr_resolution) ? ret * 8 : ret * 4;
++ ret = (data->total_curr_resolution) ? ret * 2 : ret;
+ return ret;
+ }
+
+@@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+- ret = data->total_curr_resolution ? ret * 2 : ret;
++ ret = data->total_curr_resolution ? ret : DIV_ROUND_CLOSEST(ret, 2);
+ break;
+ case PMBUS_POUT_OP_WARN_LIMIT:
+ ret = pmbus_read_word_data(client, page, phase, reg);
+@@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,
+ * set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling
+ * is needed to match both.
+ */
+- ret = data->total_curr_resolution ? ret * 4 : ret * 2;
++ ret = data->total_curr_resolution ? ret * 2 : ret;
+ break;
+ /*
+ * The below registers are not implemented by device or implemented not according to the
+diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
+index c19df3ade48e3..13ac2d8f22c79 100644
+--- a/drivers/hwmon/sht4x.c
++++ b/drivers/hwmon/sht4x.c
+@@ -129,7 +129,7 @@ unlock:
+
+ static ssize_t sht4x_interval_write(struct sht4x_data *data, long val)
+ {
+- data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, UINT_MAX);
++ data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, INT_MAX);
+
+ return 0;
+ }
+diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
+index 70b80e7109905..4d3a3b464ecd8 100644
+--- a/drivers/i2c/busses/i2c-designware-core.h
++++ b/drivers/i2c/busses/i2c-designware-core.h
+@@ -126,8 +126,9 @@
+ * status codes
+ */
+ #define STATUS_IDLE 0x0
+-#define STATUS_WRITE_IN_PROGRESS 0x1
+-#define STATUS_READ_IN_PROGRESS 0x2
++#define STATUS_ACTIVE 0x1
++#define STATUS_WRITE_IN_PROGRESS 0x2
++#define STATUS_READ_IN_PROGRESS 0x4
+
+ /*
+ * operation modes
+@@ -334,12 +335,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev);
+
+ static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
+ {
++ dev->status |= STATUS_ACTIVE;
+ regmap_write(dev->map, DW_IC_ENABLE, 1);
+ }
+
+ static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
+ {
+ regmap_write(dev->map, DW_IC_ENABLE, 0);
++ dev->status &= ~STATUS_ACTIVE;
+ }
+
+ void __i2c_dw_disable(struct dw_i2c_dev *dev);
+diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
+index 44a94b225ed82..dc3c5a15a95b9 100644
+--- a/drivers/i2c/busses/i2c-designware-master.c
++++ b/drivers/i2c/busses/i2c-designware-master.c
+@@ -716,6 +716,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
+ u32 stat;
+
+ stat = i2c_dw_read_clear_intrbits(dev);
++
++ if (!(dev->status & STATUS_ACTIVE)) {
++ /*
++ * Unexpected interrupt in driver point of view. State
++ * variables are either unset or stale so acknowledge and
++ * disable interrupts for suppressing further interrupts if
++ * interrupt really came from this HW (E.g. firmware has left
++ * the HW active).
++ */
++ regmap_write(dev->map, DW_IC_INTR_MASK, 0);
++ return 0;
++ }
++
+ if (stat & DW_IC_INTR_TX_ABRT) {
+ dev->cmd_err |= DW_IC_ERR_TX_ABRT;
+ dev->status = STATUS_IDLE;
+diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
+index 608e612094556..ca368482b2464 100644
+--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
+@@ -27,7 +27,6 @@
+ #include "i2c-ccgx-ucsi.h"
+
+ #define DRIVER_NAME "i2c-designware-pci"
+-#define AMD_CLK_RATE_HZ 100000
+
+ enum dw_pci_ctl_id_t {
+ medfield,
+@@ -100,11 +99,6 @@ static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev)
+ return 25000;
+ }
+
+-static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
+-{
+- return AMD_CLK_RATE_HZ;
+-}
+-
+ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ {
+ struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+@@ -126,15 +120,6 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ return -ENODEV;
+ }
+
+-static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+-{
+- struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+-
+- dev->flags |= MODEL_AMD_NAVI_GPU;
+- dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
+- return 0;
+-}
+-
+ static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ {
+ /*
+@@ -159,6 +144,20 @@ static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev)
+ return 100000;
+ }
+
++static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
++{
++ return 100000;
++}
++
++static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
++{
++ struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
++
++ dev->flags |= MODEL_AMD_NAVI_GPU;
++ dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
++ return 0;
++}
++
+ static struct dw_pci_controller dw_pci_controllers[] = {
+ [medfield] = {
+ .bus_num = -1,
+@@ -389,6 +388,7 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
+ { PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake },
+ { PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake },
+ { PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake },
++ /* AMD NAVI */
+ { PCI_VDEVICE(ATI, 0x7314), navi_amd },
+ { PCI_VDEVICE(ATI, 0x73a4), navi_amd },
+ { PCI_VDEVICE(ATI, 0x73e4), navi_amd },
+diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
+index ad5efd7497d1c..0e840eba4fd64 100644
+--- a/drivers/i2c/busses/i2c-mlxbf.c
++++ b/drivers/i2c/busses/i2c-mlxbf.c
+@@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency;
+ * exact.
+ */
+ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */
++#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */
+
+ /* Encapsulates timing parameters. */
+ struct mlxbf_i2c_timings {
+@@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv)
+ return false;
+ }
+
++/*
++ * wait for the lock to be released before acquiring it.
++ */
++static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv)
++{
++ if (mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW,
++ MLXBF_I2C_MASTER_LOCK_BIT, true,
++ MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT))
++ return true;
++
++ return false;
++}
++
++static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv)
++{
++ /* Clear the gw to clear the lock */
++ writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW);
++}
++
+ static bool mlxbf_i2c_smbus_transaction_success(u32 master_status,
+ u32 cause_status)
+ {
+@@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ slave = request->slave & GENMASK(6, 0);
+ addr = slave << 1;
+
+- /* First of all, check whether the HW is idle. */
+- if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv)))
++ /*
++ * Try to acquire the smbus gw lock before any reads of the GW register since
++ * a read sets the lock.
++ */
++ if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv)))
+ return -EBUSY;
+
++ /* Check whether the HW is idle */
++ if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) {
++ ret = -EBUSY;
++ goto out_unlock;
++ }
++
+ /* Set first byte. */
+ data_desc[data_idx++] = addr;
+
+@@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ write_en = 1;
+ write_len += operation->length;
+ if (data_idx + operation->length >
+- MLXBF_I2C_MASTER_DATA_DESC_SIZE)
+- return -ENOBUFS;
++ MLXBF_I2C_MASTER_DATA_DESC_SIZE) {
++ ret = -ENOBUFS;
++ goto out_unlock;
++ }
+ memcpy(data_desc + data_idx,
+ operation->buffer, operation->length);
+ data_idx += operation->length;
+@@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en,
+ pec_en, 0);
+ if (ret)
+- return ret;
++ goto out_unlock;
+ }
+
+ if (read_en) {
+@@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM);
+ }
+
++out_unlock:
++ mlxbf_i2c_smbus_master_unlock(priv);
++
+ return ret;
+ }
+
+diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
+index edad1f30121dd..502253f53d966 100644
+--- a/drivers/iio/adc/ad7923.c
++++ b/drivers/iio/adc/ad7923.c
+@@ -93,6 +93,7 @@ enum ad7923_id {
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
++ .shift = 12 - (bits), \
+ .endianness = IIO_BE, \
+ }, \
+ }
+@@ -268,7 +269,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev,
+ return ret;
+
+ if (chan->address == EXTRACT(ret, 12, 4))
+- *val = EXTRACT(ret, 0, 12);
++ *val = EXTRACT(ret, chan->scan_type.shift,
++ chan->scan_type.realbits);
+ else
+ return -EIO;
+
+diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
+index 279430c1d88c3..e2c82c5a2fac0 100644
+--- a/drivers/iio/adc/at91-sama5d2_adc.c
++++ b/drivers/iio/adc/at91-sama5d2_adc.c
+@@ -77,7 +77,7 @@ struct at91_adc_reg_layout {
+ #define AT91_SAMA5D2_MR_ANACH BIT(23)
+ /* Tracking Time */
+ #define AT91_SAMA5D2_MR_TRACKTIM(v) ((v) << 24)
+-#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xff
++#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xf
+ /* Transfer Time */
+ #define AT91_SAMA5D2_MR_TRANSFER(v) ((v) << 28)
+ #define AT91_SAMA5D2_MR_TRANSFER_MAX 0x3
+@@ -1542,10 +1542,12 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
+ ret = at91_adc_read_position(st, chan->channel,
+ &tmp_val);
+ *val = tmp_val;
++ if (ret > 0)
++ ret = at91_adc_adjust_val_osr(st, val);
+ mutex_unlock(&st->lock);
+ iio_device_release_direct_mode(indio_dev);
+
+- return at91_adc_adjust_val_osr(st, val);
++ return ret;
+ }
+ if (chan->type == IIO_PRESSURE) {
+ ret = iio_device_claim_direct_mode(indio_dev);
+@@ -1556,10 +1558,12 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
+ ret = at91_adc_read_pressure(st, chan->channel,
+ &tmp_val);
+ *val = tmp_val;
++ if (ret > 0)
++ ret = at91_adc_adjust_val_osr(st, val);
+ mutex_unlock(&st->lock);
+ iio_device_release_direct_mode(indio_dev);
+
+- return at91_adc_adjust_val_osr(st, val);
++ return ret;
+ }
+
+ /* in this case we have a voltage channel */
+@@ -1646,16 +1650,20 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,
+ /* if no change, optimize out */
+ if (val == st->oversampling_ratio)
+ return 0;
++ mutex_lock(&st->lock);
+ st->oversampling_ratio = val;
+ /* update ratio */
+ at91_adc_config_emr(st);
++ mutex_unlock(&st->lock);
+ return 0;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val < st->soc_info.min_sample_rate ||
+ val > st->soc_info.max_sample_rate)
+ return -EINVAL;
+
++ mutex_lock(&st->lock);
+ at91_adc_setup_samp_freq(indio_dev, val);
++ mutex_unlock(&st->lock);
+ return 0;
+ default:
+ return -EINVAL;
+@@ -2108,6 +2116,9 @@ static int at91_adc_suspend(struct device *dev)
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct at91_adc_state *st = iio_priv(indio_dev);
+
++ if (iio_buffer_enabled(indio_dev))
++ at91_adc_buffer_postdisable(indio_dev);
++
+ /*
+ * Do a sofware reset of the ADC before we go to suspend.
+ * this will ensure that all pins are free from being muxed by the ADC
+@@ -2151,14 +2162,11 @@ static int at91_adc_resume(struct device *dev)
+ if (!iio_buffer_enabled(indio_dev))
+ return 0;
+
+- /* check if we are enabling triggered buffer or the touchscreen */
+- if (at91_adc_current_chan_is_touch(indio_dev))
+- return at91_adc_configure_touch(st, true);
+- else
+- return at91_adc_configure_trigger(st->trig, true);
++ ret = at91_adc_buffer_prepare(indio_dev);
++ if (ret)
++ goto vref_disable_resume;
+
+- /* not needed but more explicit */
+- return 0;
++ return at91_adc_configure_trigger(st->trig, true);
+
+ vref_disable_resume:
+ regulator_disable(st->vref);
+diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
+index f7c786f37ceb1..78b93c99cc47c 100644
+--- a/drivers/iio/adc/ltc2497.c
++++ b/drivers/iio/adc/ltc2497.c
+@@ -41,6 +41,19 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
+ }
+
+ *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
++
++ /*
++ * The part started a new conversion at the end of the above i2c
++ * transfer, so if the address didn't change since the last call
++ * everything is fine and we can return early.
++ * If not (which should only happen when some sort of bulk
++ * conversion is implemented) we have to program the new
++ * address. Note that this probably fails as the conversion that
++ * was triggered above is like not complete yet and the two
++ * operations have to be done in a single transfer.
++ */
++ if (ddata->addr_prev == address)
++ return 0;
+ }
+
+ ret = i2c_smbus_write_byte(st->client,
+diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c
+index 34e1319a97126..356dc0bab1153 100644
+--- a/drivers/iio/dac/ad5593r.c
++++ b/drivers/iio/dac/ad5593r.c
+@@ -13,6 +13,8 @@
+ #include <linux/module.h>
+ #include <linux/mod_devicetable.h>
+
++#include <asm/unaligned.h>
++
+ #define AD5593R_MODE_CONF (0 << 4)
+ #define AD5593R_MODE_DAC_WRITE (1 << 4)
+ #define AD5593R_MODE_ADC_READBACK (4 << 4)
+@@ -20,6 +22,24 @@
+ #define AD5593R_MODE_GPIO_READBACK (6 << 4)
+ #define AD5593R_MODE_REG_READBACK (7 << 4)
+
++static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value)
++{
++ int ret;
++ u8 buf[2];
++
++ ret = i2c_smbus_write_byte(i2c, reg);
++ if (ret < 0)
++ return ret;
++
++ ret = i2c_master_recv(i2c, buf, sizeof(buf));
++ if (ret < 0)
++ return ret;
++
++ *value = get_unaligned_be16(buf);
++
++ return 0;
++}
++
+ static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value)
+ {
+ struct i2c_client *i2c = to_i2c_client(st->dev);
+@@ -38,13 +58,7 @@ static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value)
+ if (val < 0)
+ return (int) val;
+
+- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK);
+- if (val < 0)
+- return (int) val;
+-
+- *value = (u16) val;
+-
+- return 0;
++ return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value);
+ }
+
+ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
+@@ -58,25 +72,19 @@ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
+ static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value)
+ {
+ struct i2c_client *i2c = to_i2c_client(st->dev);
+- s32 val;
+-
+- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg);
+- if (val < 0)
+- return (int) val;
+
+- *value = (u16) val;
+-
+- return 0;
++ return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value);
+ }
+
+ static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value)
+ {
+ struct i2c_client *i2c = to_i2c_client(st->dev);
+- s32 val;
++ u16 val;
++ int ret;
+
+- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK);
+- if (val < 0)
+- return (int) val;
++ ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val);
++ if (ret)
++ return ret;
+
+ *value = (u8) val;
+
+diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
+index 0f4dbda3b9d36..921d8e8643a26 100644
+--- a/drivers/iio/industrialio-core.c
++++ b/drivers/iio/industrialio-core.c
+@@ -1621,6 +1621,8 @@ static void iio_dev_release(struct device *device)
+
+ iio_device_detach_buffers(indio_dev);
+
++ lockdep_unregister_key(&iio_dev_opaque->mlock_key);
++
+ ida_free(&iio_ida, iio_dev_opaque->id);
+ kfree(iio_dev_opaque);
+ }
+@@ -1680,6 +1682,9 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
+ INIT_LIST_HEAD(&iio_dev_opaque->buffer_list);
+ INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
+
++ lockdep_register_key(&iio_dev_opaque->mlock_key);
++ lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key);
++
+ return indio_dev;
+ }
+ EXPORT_SYMBOL(iio_device_alloc);
+diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
+index df74765d33dcb..87fd2a0d44f2a 100644
+--- a/drivers/iio/inkern.c
++++ b/drivers/iio/inkern.c
+@@ -165,9 +165,10 @@ static int __of_iio_channel_get(struct iio_channel *channel,
+
+ idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
+ iio_dev_node_match);
+- of_node_put(iiospec.np);
+- if (idev == NULL)
++ if (idev == NULL) {
++ of_node_put(iiospec.np);
+ return -EPROBE_DEFER;
++ }
+
+ indio_dev = dev_to_iio_dev(idev);
+ channel->indio_dev = indio_dev;
+@@ -175,6 +176,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
+ index = indio_dev->info->of_xlate(indio_dev, &iiospec);
+ else
+ index = __of_iio_simple_xlate(indio_dev, &iiospec);
++ of_node_put(iiospec.np);
+ if (index < 0)
+ goto err_put;
+ channel->channel = &indio_dev->channels[index];
+@@ -410,6 +412,8 @@ struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev,
+ channel = of_iio_channel_get_by_name(np, channel_name);
+ if (IS_ERR(channel))
+ return channel;
++ if (!channel)
++ return ERR_PTR(-ENODEV);
+
+ ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel);
+ if (ret)
+diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
+index aeaa4da6923b4..d1f16729c60ed 100644
+--- a/drivers/iio/magnetometer/yamaha-yas530.c
++++ b/drivers/iio/magnetometer/yamaha-yas530.c
+@@ -132,7 +132,7 @@ struct yas5xx {
+ unsigned int version;
+ char name[16];
+ struct yas5xx_calibration calibration;
+- u8 hard_offsets[3];
++ s8 hard_offsets[3];
+ struct iio_mount_matrix orientation;
+ struct regmap *map;
+ struct regulator_bulk_data regs[2];
+diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
+index 36fb7ae0d0a9d..984a3f511a1ae 100644
+--- a/drivers/iio/pressure/dps310.c
++++ b/drivers/iio/pressure/dps310.c
+@@ -89,6 +89,7 @@ struct dps310_data {
+ s32 c00, c10, c20, c30, c01, c11, c21;
+ s32 pressure_raw;
+ s32 temp_raw;
++ bool timeout_recovery_failed;
+ };
+
+ static const struct iio_chan_spec dps310_channels[] = {
+@@ -159,6 +160,102 @@ static int dps310_get_coefs(struct dps310_data *data)
+ return 0;
+ }
+
++/*
++ * Some versions of the chip will read temperatures in the ~60C range when
++ * it's actually ~20C. This is the manufacturer recommended workaround
++ * to correct the issue. The registers used below are undocumented.
++ */
++static int dps310_temp_workaround(struct dps310_data *data)
++{
++ int rc;
++ int reg;
++
++ rc = regmap_read(data->regmap, 0x32, ®);
++ if (rc)
++ return rc;
++
++ /*
++ * If bit 1 is set then the device is okay, and the workaround does not
++ * need to be applied
++ */
++ if (reg & BIT(1))
++ return 0;
++
++ rc = regmap_write(data->regmap, 0x0e, 0xA5);
++ if (rc)
++ return rc;
++
++ rc = regmap_write(data->regmap, 0x0f, 0x96);
++ if (rc)
++ return rc;
++
++ rc = regmap_write(data->regmap, 0x62, 0x02);
++ if (rc)
++ return rc;
++
++ rc = regmap_write(data->regmap, 0x0e, 0x00);
++ if (rc)
++ return rc;
++
++ return regmap_write(data->regmap, 0x0f, 0x00);
++}
++
++static int dps310_startup(struct dps310_data *data)
++{
++ int rc;
++ int ready;
++
++ /*
++ * Set up pressure sensor in single sample, one measurement per second
++ * mode
++ */
++ rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0);
++ if (rc)
++ return rc;
++
++ /*
++ * Set up external (MEMS) temperature sensor in single sample, one
++ * measurement per second mode
++ */
++ rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT);
++ if (rc)
++ return rc;
++
++ /* Temp and pressure shifts are disabled when PRC <= 8 */
++ rc = regmap_write_bits(data->regmap, DPS310_CFG_REG,
++ DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0);
++ if (rc)
++ return rc;
++
++ /* MEAS_CFG doesn't update correctly unless first written with 0 */
++ rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
++ DPS310_MEAS_CTRL_BITS, 0);
++ if (rc)
++ return rc;
++
++ /* Turn on temperature and pressure measurement in the background */
++ rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
++ DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN |
++ DPS310_TEMP_EN | DPS310_BACKGROUND);
++ if (rc)
++ return rc;
++
++ /*
++ * Calibration coefficients required for reporting temperature.
++ * They are available 40ms after the device has started
++ */
++ rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
++ ready & DPS310_COEF_RDY, 10000, 40000);
++ if (rc)
++ return rc;
++
++ rc = dps310_get_coefs(data);
++ if (rc)
++ return rc;
++
++ return dps310_temp_workaround(data);
++}
++
+ static int dps310_get_pres_precision(struct dps310_data *data)
+ {
+ int rc;
+@@ -297,11 +394,69 @@ static int dps310_get_temp_k(struct dps310_data *data)
+ return scale_factors[ilog2(rc)];
+ }
+
++static int dps310_reset_wait(struct dps310_data *data)
++{
++ int rc;
++
++ rc = regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
++ if (rc)
++ return rc;
++
++ /* Wait for device chip access: 2.5ms in specification */
++ usleep_range(2500, 12000);
++ return 0;
++}
++
++static int dps310_reset_reinit(struct dps310_data *data)
++{
++ int rc;
++
++ rc = dps310_reset_wait(data);
++ if (rc)
++ return rc;
++
++ return dps310_startup(data);
++}
++
++static int dps310_ready_status(struct dps310_data *data, int ready_bit, int timeout)
++{
++ int sleep = DPS310_POLL_SLEEP_US(timeout);
++ int ready;
++
++ return regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ready & ready_bit,
++ sleep, timeout);
++}
++
++static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout)
++{
++ int rc;
++
++ rc = dps310_ready_status(data, ready_bit, timeout);
++ if (rc) {
++ if (rc == -ETIMEDOUT && !data->timeout_recovery_failed) {
++ /* Reset and reinitialize the chip. */
++ if (dps310_reset_reinit(data)) {
++ data->timeout_recovery_failed = true;
++ } else {
++ /* Try again to get sensor ready status. */
++ if (dps310_ready_status(data, ready_bit, timeout))
++ data->timeout_recovery_failed = true;
++ else
++ return 0;
++ }
++ }
++
++ return rc;
++ }
++
++ data->timeout_recovery_failed = false;
++ return 0;
++}
++
+ static int dps310_read_pres_raw(struct dps310_data *data)
+ {
+ int rc;
+ int rate;
+- int ready;
+ int timeout;
+ s32 raw;
+ u8 val[3];
+@@ -313,9 +468,7 @@ static int dps310_read_pres_raw(struct dps310_data *data)
+ timeout = DPS310_POLL_TIMEOUT_US(rate);
+
+ /* Poll for sensor readiness; base the timeout upon the sample rate. */
+- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+- ready & DPS310_PRS_RDY,
+- DPS310_POLL_SLEEP_US(timeout), timeout);
++ rc = dps310_ready(data, DPS310_PRS_RDY, timeout);
+ if (rc)
+ goto done;
+
+@@ -352,7 +505,6 @@ static int dps310_read_temp_raw(struct dps310_data *data)
+ {
+ int rc;
+ int rate;
+- int ready;
+ int timeout;
+
+ if (mutex_lock_interruptible(&data->lock))
+@@ -362,10 +514,8 @@ static int dps310_read_temp_raw(struct dps310_data *data)
+ timeout = DPS310_POLL_TIMEOUT_US(rate);
+
+ /* Poll for sensor readiness; base the timeout upon the sample rate. */
+- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+- ready & DPS310_TMP_RDY,
+- DPS310_POLL_SLEEP_US(timeout), timeout);
+- if (rc < 0)
++ rc = dps310_ready(data, DPS310_TMP_RDY, timeout);
++ if (rc)
+ goto done;
+
+ rc = dps310_read_temp_ready(data);
+@@ -660,7 +810,7 @@ static void dps310_reset(void *action_data)
+ {
+ struct dps310_data *data = action_data;
+
+- regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
++ dps310_reset_wait(data);
+ }
+
+ static const struct regmap_config dps310_regmap_config = {
+@@ -677,52 +827,12 @@ static const struct iio_info dps310_info = {
+ .write_raw = dps310_write_raw,
+ };
+
+-/*
+- * Some verions of chip will read temperatures in the ~60C range when
+- * its actually ~20C. This is the manufacturer recommended workaround
+- * to correct the issue. The registers used below are undocumented.
+- */
+-static int dps310_temp_workaround(struct dps310_data *data)
+-{
+- int rc;
+- int reg;
+-
+- rc = regmap_read(data->regmap, 0x32, ®);
+- if (rc < 0)
+- return rc;
+-
+- /*
+- * If bit 1 is set then the device is okay, and the workaround does not
+- * need to be applied
+- */
+- if (reg & BIT(1))
+- return 0;
+-
+- rc = regmap_write(data->regmap, 0x0e, 0xA5);
+- if (rc < 0)
+- return rc;
+-
+- rc = regmap_write(data->regmap, 0x0f, 0x96);
+- if (rc < 0)
+- return rc;
+-
+- rc = regmap_write(data->regmap, 0x62, 0x02);
+- if (rc < 0)
+- return rc;
+-
+- rc = regmap_write(data->regmap, 0x0e, 0x00);
+- if (rc < 0)
+- return rc;
+-
+- return regmap_write(data->regmap, 0x0f, 0x00);
+-}
+-
+ static int dps310_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+ {
+ struct dps310_data *data;
+ struct iio_dev *iio;
+- int rc, ready;
++ int rc;
+
+ iio = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!iio)
+@@ -747,54 +857,8 @@ static int dps310_probe(struct i2c_client *client,
+ if (rc)
+ return rc;
+
+- /*
+- * Set up pressure sensor in single sample, one measurement per second
+- * mode
+- */
+- rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0);
+-
+- /*
+- * Set up external (MEMS) temperature sensor in single sample, one
+- * measurement per second mode
+- */
+- rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT);
+- if (rc < 0)
+- return rc;
+-
+- /* Temp and pressure shifts are disabled when PRC <= 8 */
+- rc = regmap_write_bits(data->regmap, DPS310_CFG_REG,
+- DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0);
+- if (rc < 0)
+- return rc;
+-
+- /* MEAS_CFG doesn't update correctly unless first written with 0 */
+- rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
+- DPS310_MEAS_CTRL_BITS, 0);
+- if (rc < 0)
+- return rc;
+-
+- /* Turn on temperature and pressure measurement in the background */
+- rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
+- DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN |
+- DPS310_TEMP_EN | DPS310_BACKGROUND);
+- if (rc < 0)
+- return rc;
+-
+- /*
+- * Calibration coefficients required for reporting temperature.
+- * They are available 40ms after the device has started
+- */
+- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+- ready & DPS310_COEF_RDY, 10000, 40000);
+- if (rc < 0)
+- return rc;
+-
+- rc = dps310_get_coefs(data);
+- if (rc < 0)
+- return rc;
+-
+- rc = dps310_temp_workaround(data);
+- if (rc < 0)
++ rc = dps310_startup(data);
++ if (rc)
+ return rc;
+
+ rc = devm_iio_device_register(&client->dev, iio);
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index b985e0d9bc05e..5c910f5c01b35 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -1632,14 +1632,13 @@ static void cm_path_set_rec_type(struct ib_device *ib_device, u32 port_num,
+
+ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,
+ struct sa_path_rec *primary_path,
+- struct sa_path_rec *alt_path)
++ struct sa_path_rec *alt_path,
++ struct ib_wc *wc)
+ {
+ u32 lid;
+
+ if (primary_path->rec_type != SA_PATH_REC_TYPE_OPA) {
+- sa_path_set_dlid(primary_path,
+- IBA_GET(CM_REQ_PRIMARY_LOCAL_PORT_LID,
+- req_msg));
++ sa_path_set_dlid(primary_path, wc->slid);
+ sa_path_set_slid(primary_path,
+ IBA_GET(CM_REQ_PRIMARY_REMOTE_PORT_LID,
+ req_msg));
+@@ -1676,7 +1675,8 @@ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,
+
+ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+ struct sa_path_rec *primary_path,
+- struct sa_path_rec *alt_path)
++ struct sa_path_rec *alt_path,
++ struct ib_wc *wc)
+ {
+ primary_path->dgid =
+ *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg);
+@@ -1734,7 +1734,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+ if (sa_path_is_roce(alt_path))
+ alt_path->roce.route_resolved = false;
+ }
+- cm_format_path_lid_from_req(req_msg, primary_path, alt_path);
++ cm_format_path_lid_from_req(req_msg, primary_path, alt_path, wc);
+ }
+
+ static u16 cm_get_bth_pkey(struct cm_work *work)
+@@ -2148,7 +2148,7 @@ static int cm_req_handler(struct cm_work *work)
+ if (cm_req_has_alt_path(req_msg))
+ work->path[1].rec_type = work->path[0].rec_type;
+ cm_format_paths_from_req(req_msg, &work->path[0],
+- &work->path[1]);
++ &work->path[1], work->mad_recv_wc->wc);
+ if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
+ sa_path_set_dmac(&work->path[0],
+ cm_id_priv->av.ah_attr.roce.dmac);
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index 046376bd68e27..4796f6a8828ca 100644
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -739,6 +739,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
+ mr->uobject = uobj;
+ atomic_inc(&pd->usecnt);
+ mr->iova = cmd.hca_va;
++ mr->length = cmd.length;
+
+ rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
+ rdma_restrack_set_name(&mr->res, NULL);
+@@ -861,8 +862,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
+ mr->pd = new_pd;
+ atomic_inc(&new_pd->usecnt);
+ }
+- if (cmd.flags & IB_MR_REREG_TRANS)
++ if (cmd.flags & IB_MR_REREG_TRANS) {
+ mr->iova = cmd.hca_va;
++ mr->length = cmd.length;
++ }
+ }
+
+ memset(&resp, 0, sizeof(resp));
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index e54b3f1b730e0..f8964c8cf0ade 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -2149,6 +2149,8 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ mr->pd = pd;
+ mr->dm = NULL;
+ atomic_inc(&pd->usecnt);
++ mr->iova = virt_addr;
++ mr->length = length;
+
+ rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
+ rdma_restrack_parent_name(&mr->res, &pd->res);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 867972c2a894d..dedfa56f57731 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -249,7 +249,6 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ goto err_alloc_pbl;
+
+ mr->ibmr.rkey = mr->ibmr.lkey = mr->key;
+- mr->ibmr.length = length;
+
+ return &mr->ibmr;
+
+diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h
+index e03e03082a5fb..c1906cab5c8ad 100644
+--- a/drivers/infiniband/hw/irdma/defs.h
++++ b/drivers/infiniband/hw/irdma/defs.h
+@@ -314,6 +314,7 @@ enum irdma_cqp_op_type {
+ #define IRDMA_AE_IB_REMOTE_ACCESS_ERROR 0x020d
+ #define IRDMA_AE_IB_REMOTE_OP_ERROR 0x020e
+ #define IRDMA_AE_WQE_LSMM_TOO_LONG 0x0220
++#define IRDMA_AE_INVALID_REQUEST 0x0223
+ #define IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN 0x0301
+ #define IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER 0x0303
+ #define IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION 0x0304
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 4f132c6fb653b..ab246447520bd 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -138,59 +138,68 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,
+ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+
+ switch (info->ae_id) {
+- case IRDMA_AE_AMP_UNALLOCATED_STAG:
+ case IRDMA_AE_AMP_BOUNDS_VIOLATION:
+ case IRDMA_AE_AMP_INVALID_STAG:
+- qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+- fallthrough;
++ case IRDMA_AE_AMP_RIGHTS_VIOLATION:
++ case IRDMA_AE_AMP_UNALLOCATED_STAG:
+ case IRDMA_AE_AMP_BAD_PD:
+- case IRDMA_AE_UDA_XMIT_BAD_PD:
++ case IRDMA_AE_AMP_BAD_QP:
++ case IRDMA_AE_AMP_BAD_STAG_KEY:
++ case IRDMA_AE_AMP_BAD_STAG_INDEX:
++ case IRDMA_AE_AMP_TO_WRAP:
++ case IRDMA_AE_PRIV_OPERATION_DENIED:
+ qp->flush_code = FLUSH_PROT_ERR;
++ qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ break;
+- case IRDMA_AE_AMP_BAD_QP:
++ case IRDMA_AE_UDA_XMIT_BAD_PD:
+ case IRDMA_AE_WQE_UNEXPECTED_OPCODE:
+ qp->flush_code = FLUSH_LOC_QP_OP_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
++ break;
++ case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
++ case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
++ case IRDMA_AE_UDA_L4LEN_INVALID:
++ case IRDMA_AE_DDP_UBE_INVALID_MO:
++ case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
++ qp->flush_code = FLUSH_LOC_LEN_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ break;
+- case IRDMA_AE_AMP_BAD_STAG_KEY:
+- case IRDMA_AE_AMP_BAD_STAG_INDEX:
+- case IRDMA_AE_AMP_TO_WRAP:
+- case IRDMA_AE_AMP_RIGHTS_VIOLATION:
+ case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
+- case IRDMA_AE_PRIV_OPERATION_DENIED:
+- case IRDMA_AE_IB_INVALID_REQUEST:
+ case IRDMA_AE_IB_REMOTE_ACCESS_ERROR:
+ qp->flush_code = FLUSH_REM_ACCESS_ERR;
+ qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ break;
+ case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
+- case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
+- case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
+- case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
+- case IRDMA_AE_UDA_L4LEN_INVALID:
++ case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
+ case IRDMA_AE_ROCE_RSP_LENGTH_ERROR:
+- qp->flush_code = FLUSH_LOC_LEN_ERR;
++ case IRDMA_AE_IB_REMOTE_OP_ERROR:
++ qp->flush_code = FLUSH_REM_OP_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ break;
+ case IRDMA_AE_LCE_QP_CATASTROPHIC:
+ qp->flush_code = FLUSH_FATAL_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ break;
+- case IRDMA_AE_DDP_UBE_INVALID_MO:
+ case IRDMA_AE_IB_RREQ_AND_Q1_FULL:
+- case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
+ qp->flush_code = FLUSH_GENERAL_ERR;
+ break;
+ case IRDMA_AE_LLP_TOO_MANY_RETRIES:
+ qp->flush_code = FLUSH_RETRY_EXC_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ break;
+ case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS:
+ case IRDMA_AE_AMP_MWBIND_BIND_DISABLED:
+ case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS:
+ qp->flush_code = FLUSH_MW_BIND_ERR;
++ qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ break;
+- case IRDMA_AE_IB_REMOTE_OP_ERROR:
+- qp->flush_code = FLUSH_REM_OP_ERR;
++ case IRDMA_AE_IB_INVALID_REQUEST:
++ qp->flush_code = FLUSH_REM_INV_REQ_ERR;
++ qp->event_type = IRDMA_QP_EVENT_REQ_ERR;
+ break;
+ default:
+- qp->flush_code = FLUSH_FATAL_ERR;
++ qp->flush_code = FLUSH_GENERAL_ERR;
++ qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ break;
+ }
+ }
+diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h
+index 9e7b8ecb137ab..517d41a1c2894 100644
+--- a/drivers/infiniband/hw/irdma/type.h
++++ b/drivers/infiniband/hw/irdma/type.h
+@@ -98,6 +98,7 @@ enum irdma_term_mpa_errors {
+ enum irdma_qp_event_type {
+ IRDMA_QP_EVENT_CATASTROPHIC,
+ IRDMA_QP_EVENT_ACCESS_ERR,
++ IRDMA_QP_EVENT_REQ_ERR,
+ };
+
+ enum irdma_hw_stats_index_32b {
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index ddd0ebbdd7d54..2ef61923c9268 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -103,6 +103,7 @@ enum irdma_flush_opcode {
+ FLUSH_FATAL_ERR,
+ FLUSH_RETRY_EXC_ERR,
+ FLUSH_MW_BIND_ERR,
++ FLUSH_REM_INV_REQ_ERR,
+ };
+
+ enum irdma_cmpl_status {
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 075defaabee53..8dfc9e154d733 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -2479,6 +2479,9 @@ void irdma_ib_qp_event(struct irdma_qp *iwqp, enum irdma_qp_event_type event)
+ case IRDMA_QP_EVENT_ACCESS_ERR:
+ ibevent.event = IB_EVENT_QP_ACCESS_ERR;
+ break;
++ case IRDMA_QP_EVENT_REQ_ERR:
++ ibevent.event = IB_EVENT_QP_REQ_ERR;
++ break;
+ }
+ ibevent.device = iwqp->ibqp.device;
+ ibevent.element.qp = &iwqp->ibqp;
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 9b207f5084eb7..a22afbb25bc58 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -299,13 +299,19 @@ static void irdma_alloc_push_page(struct irdma_qp *iwqp)
+ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ struct ib_udata *udata)
+ {
++#define IRDMA_ALLOC_UCTX_MIN_REQ_LEN offsetofend(struct irdma_alloc_ucontext_req, rsvd8)
++#define IRDMA_ALLOC_UCTX_MIN_RESP_LEN offsetofend(struct irdma_alloc_ucontext_resp, rsvd)
+ struct ib_device *ibdev = uctx->device;
+ struct irdma_device *iwdev = to_iwdev(ibdev);
+- struct irdma_alloc_ucontext_req req;
++ struct irdma_alloc_ucontext_req req = {};
+ struct irdma_alloc_ucontext_resp uresp = {};
+ struct irdma_ucontext *ucontext = to_ucontext(uctx);
+ struct irdma_uk_attrs *uk_attrs;
+
++ if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN ||
++ udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
++ return -EINVAL;
++
+ if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen)))
+ return -EINVAL;
+
+@@ -317,7 +323,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+
+ uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
+ /* GEN_1 legacy support with libi40iw */
+- if (udata->outlen < sizeof(uresp)) {
++ if (udata->outlen == IRDMA_ALLOC_UCTX_MIN_RESP_LEN) {
+ if (uk_attrs->hw_rev != IRDMA_GEN_1)
+ return -EOPNOTSUPP;
+
+@@ -389,6 +395,7 @@ static void irdma_dealloc_ucontext(struct ib_ucontext *context)
+ */
+ static int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+ {
++#define IRDMA_ALLOC_PD_MIN_RESP_LEN offsetofend(struct irdma_alloc_pd_resp, rsvd)
+ struct irdma_pd *iwpd = to_iwpd(pd);
+ struct irdma_device *iwdev = to_iwdev(pd->device);
+ struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
+@@ -398,6 +405,9 @@ static int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+ u32 pd_id = 0;
+ int err;
+
++ if (udata && udata->outlen < IRDMA_ALLOC_PD_MIN_RESP_LEN)
++ return -EINVAL;
++
+ err = irdma_alloc_rsrc(rf, rf->allocated_pds, rf->max_pd, &pd_id,
+ &rf->next_pd);
+ if (err)
+@@ -814,12 +824,14 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_QP_MIN_REQ_LEN offsetofend(struct irdma_create_qp_req, user_compl_ctx)
++#define IRDMA_CREATE_QP_MIN_RESP_LEN offsetofend(struct irdma_create_qp_resp, rsvd)
+ struct ib_pd *ibpd = ibqp->pd;
+ struct irdma_pd *iwpd = to_iwpd(ibpd);
+ struct irdma_device *iwdev = to_iwdev(ibpd->device);
+ struct irdma_pci_f *rf = iwdev->rf;
+ struct irdma_qp *iwqp = to_iwqp(ibqp);
+- struct irdma_create_qp_req req;
++ struct irdma_create_qp_req req = {};
+ struct irdma_create_qp_resp uresp = {};
+ u32 qp_num = 0;
+ int err_code;
+@@ -836,6 +848,10 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ if (err_code)
+ return err_code;
+
++ if (udata && (udata->inlen < IRDMA_CREATE_QP_MIN_REQ_LEN ||
++ udata->outlen < IRDMA_CREATE_QP_MIN_RESP_LEN))
++ return -EINVAL;
++
+ sq_size = init_attr->cap.max_send_wr;
+ rq_size = init_attr->cap.max_recv_wr;
+
+@@ -1120,6 +1136,8 @@ static int irdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index,
+ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+ {
++#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
++#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
+ struct irdma_pd *iwpd = to_iwpd(ibqp->pd);
+ struct irdma_qp *iwqp = to_iwqp(ibqp);
+ struct irdma_device *iwdev = iwqp->iwdev;
+@@ -1138,6 +1156,13 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ roce_info = &iwqp->roce_info;
+ udp_info = &iwqp->udp_info;
+
++ if (udata) {
++ /* udata inlen/outlen can be 0 when supporting legacy libi40iw */
++ if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
++ (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
++ return -EINVAL;
++ }
++
+ if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
+ return -EOPNOTSUPP;
+
+@@ -1374,7 +1399,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+
+ if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
+ spin_unlock_irqrestore(&iwqp->lock, flags);
+- if (udata) {
++ if (udata && udata->inlen) {
+ if (ib_copy_from_udata(&ureq, udata,
+ min(sizeof(ureq), udata->inlen)))
+ return -EINVAL;
+@@ -1426,7 +1451,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ } else {
+ iwqp->ibqp_state = attr->qp_state;
+ }
+- if (udata && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
++ if (udata && udata->outlen && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
+ struct irdma_ucontext *ucontext;
+
+ ucontext = rdma_udata_to_drv_context(udata,
+@@ -1466,6 +1491,8 @@ exit:
+ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata)
+ {
++#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
++#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
+ struct irdma_qp *iwqp = to_iwqp(ibqp);
+ struct irdma_device *iwdev = iwqp->iwdev;
+ struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
+@@ -1480,6 +1507,13 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ int err;
+ unsigned long flags;
+
++ if (udata) {
++ /* udata inlen/outlen can be 0 when supporting legacy libi40iw */
++ if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
++ (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
++ return -EINVAL;
++ }
++
+ if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
+ return -EOPNOTSUPP;
+
+@@ -1565,7 +1599,7 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ case IB_QPS_RESET:
+ if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
+ spin_unlock_irqrestore(&iwqp->lock, flags);
+- if (udata) {
++ if (udata && udata->inlen) {
+ if (ib_copy_from_udata(&ureq, udata,
+ min(sizeof(ureq), udata->inlen)))
+ return -EINVAL;
+@@ -1662,7 +1696,7 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ }
+ }
+ }
+- if (attr_mask & IB_QP_STATE && udata &&
++ if (attr_mask & IB_QP_STATE && udata && udata->outlen &&
+ dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
+ struct irdma_ucontext *ucontext;
+
+@@ -1797,6 +1831,7 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
+ struct ib_udata *udata)
+ {
++#define IRDMA_RESIZE_CQ_MIN_REQ_LEN offsetofend(struct irdma_resize_cq_req, user_cq_buffer)
+ struct irdma_cq *iwcq = to_iwcq(ibcq);
+ struct irdma_sc_dev *dev = iwcq->sc_cq.dev;
+ struct irdma_cqp_request *cqp_request;
+@@ -1819,6 +1854,9 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
+ IRDMA_FEATURE_CQ_RESIZE))
+ return -EOPNOTSUPP;
+
++ if (udata && udata->inlen < IRDMA_RESIZE_CQ_MIN_REQ_LEN)
++ return -EINVAL;
++
+ if (entries > rf->max_cqe)
+ return -EINVAL;
+
+@@ -1951,6 +1989,8 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_CQ_MIN_REQ_LEN offsetofend(struct irdma_create_cq_req, user_cq_buf)
++#define IRDMA_CREATE_CQ_MIN_RESP_LEN offsetofend(struct irdma_create_cq_resp, cq_size)
+ struct ib_device *ibdev = ibcq->device;
+ struct irdma_device *iwdev = to_iwdev(ibdev);
+ struct irdma_pci_f *rf = iwdev->rf;
+@@ -1969,6 +2009,11 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ err_code = cq_validate_flags(attr->flags, dev->hw_attrs.uk_attrs.hw_rev);
+ if (err_code)
+ return err_code;
++
++ if (udata && (udata->inlen < IRDMA_CREATE_CQ_MIN_REQ_LEN ||
++ udata->outlen < IRDMA_CREATE_CQ_MIN_RESP_LEN))
++ return -EINVAL;
++
+ err_code = irdma_alloc_rsrc(rf, rf->allocated_cqs, rf->max_cq, &cq_num,
+ &rf->next_cq);
+ if (err_code)
+@@ -2746,6 +2791,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ u64 virt, int access,
+ struct ib_udata *udata)
+ {
++#define IRDMA_MEM_REG_MIN_REQ_LEN offsetofend(struct irdma_mem_reg_req, sq_pages)
+ struct irdma_device *iwdev = to_iwdev(pd->device);
+ struct irdma_ucontext *ucontext;
+ struct irdma_pble_alloc *palloc;
+@@ -2763,6 +2809,9 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size)
+ return ERR_PTR(-EINVAL);
+
++ if (udata->inlen < IRDMA_MEM_REG_MIN_REQ_LEN)
++ return ERR_PTR(-EINVAL);
++
+ region = ib_umem_get(pd->device, start, len, access);
+
+ if (IS_ERR(region)) {
+@@ -3315,6 +3364,8 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode
+ return IB_WC_RETRY_EXC_ERR;
+ case FLUSH_MW_BIND_ERR:
+ return IB_WC_MW_BIND_ERR;
++ case FLUSH_REM_INV_REQ_ERR:
++ return IB_WC_REM_INV_REQ_ERR;
+ case FLUSH_FATAL_ERR:
+ default:
+ return IB_WC_FATAL_ERR;
+@@ -4296,12 +4347,16 @@ static int irdma_create_user_ah(struct ib_ah *ibah,
+ struct rdma_ah_init_attr *attr,
+ struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_AH_MIN_RESP_LEN offsetofend(struct irdma_create_ah_resp, rsvd)
+ struct irdma_ah *ah = container_of(ibah, struct irdma_ah, ibah);
+ struct irdma_device *iwdev = to_iwdev(ibah->pd->device);
+ struct irdma_create_ah_resp uresp;
+ struct irdma_ah *parent_ah;
+ int err;
+
++ if (udata && udata->outlen < IRDMA_CREATE_AH_MIN_RESP_LEN)
++ return -EINVAL;
++
+ err = irdma_setup_ah(ibah, attr);
+ if (err)
+ return err;
+diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
+index 04a67b4816086..a40bf58bcdd3a 100644
+--- a/drivers/infiniband/hw/mlx4/mr.c
++++ b/drivers/infiniband/hw/mlx4/mr.c
+@@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ goto err_mr;
+
+ mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;
+- mr->ibmr.length = length;
+ mr->ibmr.page_size = 1U << shift;
+
+ return &mr->ibmr;
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 883d7c60143e8..1aa0c772b44d9 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -1826,6 +1826,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
+ if (MLX5_CAP_GEN(dev->mdev, drain_sigerr))
+ resp->comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS;
+
++ resp->comp_mask |=
++ MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG;
++
+ return 0;
+ }
+
+diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
+index e305bf1dc6c22..901a8b0302360 100644
+--- a/drivers/infiniband/hw/mlx5/odp.c
++++ b/drivers/infiniband/hw/mlx5/odp.c
+@@ -795,7 +795,8 @@ static bool mkey_is_eq(struct mlx5_ib_mkey *mmkey, u32 key)
+ {
+ if (!mmkey)
+ return false;
+- if (mmkey->type == MLX5_MKEY_MW)
++ if (mmkey->type == MLX5_MKEY_MW ||
++ mmkey->type == MLX5_MKEY_INDIRECT_DEVX)
+ return mlx5_base_mkey(mmkey->key) == mlx5_base_mkey(key);
+ return mmkey->key == key;
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 22f6cc31d1d63..c2a5c8814a48b 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -64,10 +64,10 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
+
+ /* rxe_mr.c */
+ u8 rxe_get_next_key(u32 last_key);
+-void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr);
+-int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
++void rxe_mr_init_dma(int access, struct rxe_mr *mr);
++int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ int access, struct rxe_mr *mr);
+-int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr);
++int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr);
+ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length,
+ enum rxe_mr_copy_dir dir);
+ int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma,
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index 850b80f5ad8bd..af34f198e6456 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -103,17 +103,16 @@ err1:
+ return -ENOMEM;
+ }
+
+-void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr)
++void rxe_mr_init_dma(int access, struct rxe_mr *mr)
+ {
+ rxe_mr_init(access, mr);
+
+- mr->ibmr.pd = &pd->ibpd;
+ mr->access = access;
+ mr->state = RXE_MR_STATE_VALID;
+ mr->type = IB_MR_TYPE_DMA;
+ }
+
+-int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
++int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ int access, struct rxe_mr *mr)
+ {
+ struct rxe_map **map;
+@@ -125,7 +124,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
+ int err;
+ int i;
+
+- umem = ib_umem_get(pd->ibpd.device, start, length, access);
++ umem = ib_umem_get(&rxe->ib_dev, start, length, access);
+ if (IS_ERR(umem)) {
+ pr_warn("%s: Unable to pin memory region err = %d\n",
+ __func__, (int)PTR_ERR(umem));
+@@ -175,7 +174,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
+ }
+ }
+
+- mr->ibmr.pd = &pd->ibpd;
+ mr->umem = umem;
+ mr->access = access;
+ mr->length = length;
+@@ -197,7 +195,7 @@ err_out:
+ return err;
+ }
+
+-int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr)
++int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)
+ {
+ int err;
+
+@@ -208,7 +206,6 @@ int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr)
+ if (err)
+ goto err1;
+
+- mr->ibmr.pd = &pd->ibpd;
+ mr->max_buf = max_pages;
+ mr->state = RXE_MR_STATE_FREE;
+ mr->type = IB_MR_TYPE_MEM_REG;
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 516bf9b95e489..d776dfda43b16 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -797,7 +797,9 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+ rxe_cleanup_task(&qp->comp.task);
+
+ /* flush out any receive wr's or pending requests */
+- __rxe_do_task(&qp->req.task);
++ if (qp->req.task.func)
++ __rxe_do_task(&qp->req.task);
++
+ if (qp->sq.queue) {
+ __rxe_do_task(&qp->comp.task);
+ __rxe_do_task(&qp->req.task);
+@@ -833,8 +835,10 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+
+ free_rd_atomic_resources(qp);
+
+- kernel_sock_shutdown(qp->sk, SHUT_RDWR);
+- sock_release(qp->sk);
++ if (qp->sk) {
++ kernel_sock_shutdown(qp->sk, SHUT_RDWR);
++ sock_release(qp->sk);
++ }
+ }
+
+ /* called when the last reference to the qp is dropped */
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c
+index dbd4971039c0c..d6dbf5a0058dc 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.c
++++ b/drivers/infiniband/sw/rxe/rxe_queue.c
+@@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q,
+ unsigned int num_elem)
+ {
+ enum queue_type type = q->type;
++ u32 new_prod;
+ u32 prod;
+ u32 cons;
+
+ if (!queue_empty(q, q->type) && (num_elem < queue_count(q, type)))
+ return -EINVAL;
+
+- prod = queue_get_producer(new_q, type);
++ new_prod = queue_get_producer(new_q, type);
++ prod = queue_get_producer(q, type);
+ cons = queue_get_consumer(q, type);
+
+- while (!queue_empty(q, type)) {
+- memcpy(queue_addr_from_index(new_q, prod),
++ while ((prod - cons) & q->index_mask) {
++ memcpy(queue_addr_from_index(new_q, new_prod),
+ queue_addr_from_index(q, cons), new_q->elem_size);
+- prod = queue_next_index(new_q, prod);
++ new_prod = queue_next_index(new_q, new_prod);
+ cons = queue_next_index(q, cons);
+ }
+
+- new_q->buf->producer_index = prod;
++ new_q->buf->producer_index = new_prod;
+ q->buf->consumer_index = cons;
+
+ /* update private index copies */
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index b36ec5c4d5e07..7c336db5cb547 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -809,10 +809,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+ if (!skb)
+ return RESPST_ERR_RNR;
+
+- err = rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
+- payload, RXE_FROM_MR_OBJ);
+- if (err)
+- pr_err("Failed copying memory\n");
++ rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
++ payload, RXE_FROM_MR_OBJ);
+ if (mr)
+ rxe_put(mr);
+
+@@ -823,10 +821,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+ }
+
+ err = rxe_xmit_packet(qp, &ack_pkt, skb);
+- if (err) {
+- pr_err("Failed sending RDMA reply.\n");
++ if (err)
+ return RESPST_ERR_RNR;
+- }
+
+ res->read.va += payload;
+ res->read.resid -= payload;
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
+index e264cf69bf558..f54a3eba652f2 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
+@@ -903,7 +903,9 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
+ return ERR_PTR(-ENOMEM);
+
+ rxe_get(pd);
+- rxe_mr_init_dma(pd, access, mr);
++ mr->ibmr.pd = ibpd;
++
++ rxe_mr_init_dma(access, mr);
+ rxe_finalize(mr);
+
+ return &mr->ibmr;
+@@ -928,8 +930,9 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
+
+
+ rxe_get(pd);
++ mr->ibmr.pd = ibpd;
+
+- err = rxe_mr_init_user(pd, start, length, iova, access, mr);
++ err = rxe_mr_init_user(rxe, start, length, iova, access, mr);
+ if (err)
+ goto err3;
+
+@@ -938,7 +941,6 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
+ return &mr->ibmr;
+
+ err3:
+- rxe_put(pd);
+ rxe_cleanup(mr);
+ err2:
+ return ERR_PTR(err);
+@@ -962,8 +964,9 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ }
+
+ rxe_get(pd);
++ mr->ibmr.pd = ibpd;
+
+- err = rxe_mr_init_fast(pd, max_num_sg, mr);
++ err = rxe_mr_init_fast(max_num_sg, mr);
+ if (err)
+ goto err2;
+
+@@ -972,7 +975,6 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ return &mr->ibmr;
+
+ err2:
+- rxe_put(pd);
+ rxe_cleanup(mr);
+ err1:
+ return ERR_PTR(err);
+diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h
+index df03d84c6868a..2f3a9cda3850f 100644
+--- a/drivers/infiniband/sw/siw/siw.h
++++ b/drivers/infiniband/sw/siw/siw.h
+@@ -418,6 +418,7 @@ struct siw_qp {
+ struct ib_qp base_qp;
+ struct siw_device *sdev;
+ struct kref ref;
++ struct completion qp_free;
+ struct list_head devq;
+ int tx_cpu;
+ struct siw_qp_attrs attrs;
+diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c
+index 7e01f2438afc5..e6f634971228e 100644
+--- a/drivers/infiniband/sw/siw/siw_qp.c
++++ b/drivers/infiniband/sw/siw/siw_qp.c
+@@ -1342,6 +1342,6 @@ void siw_free_qp(struct kref *ref)
+ vfree(qp->orq);
+
+ siw_put_tx_cpu(qp->tx_cpu);
+-
++ complete(&qp->qp_free);
+ atomic_dec(&sdev->num_qp);
+ }
+diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
+index 875ea6f1b04a2..fd721cc19682e 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_rx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
+@@ -961,27 +961,28 @@ out:
+ static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx)
+ {
+ struct sk_buff *skb = srx->skb;
++ int avail = min(srx->skb_new, srx->fpdu_part_rem);
+ u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad;
+ __wsum crc_in, crc_own = 0;
+
+ siw_dbg_qp(qp, "expected %d, available %d, pad %u\n",
+ srx->fpdu_part_rem, srx->skb_new, srx->pad);
+
+- if (srx->skb_new < srx->fpdu_part_rem)
+- return -EAGAIN;
+-
+- skb_copy_bits(skb, srx->skb_offset, tbuf, srx->fpdu_part_rem);
++ skb_copy_bits(skb, srx->skb_offset, tbuf, avail);
+
+- if (srx->mpa_crc_hd && srx->pad)
+- crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
++ srx->skb_new -= avail;
++ srx->skb_offset += avail;
++ srx->skb_copied += avail;
++ srx->fpdu_part_rem -= avail;
+
+- srx->skb_new -= srx->fpdu_part_rem;
+- srx->skb_offset += srx->fpdu_part_rem;
+- srx->skb_copied += srx->fpdu_part_rem;
++ if (srx->fpdu_part_rem)
++ return -EAGAIN;
+
+ if (!srx->mpa_crc_hd)
+ return 0;
+
++ if (srx->pad)
++ crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
+ /*
+ * CRC32 is computed, transmitted and received directly in NBO,
+ * so there's never a reason to convert byte order.
+@@ -1083,10 +1084,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
+ * completely received.
+ */
+ if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) {
+- bytes = iwarp_pktinfo[opcode].hdr_len - MIN_DDP_HDR;
++ int hdrlen = iwarp_pktinfo[opcode].hdr_len;
+
+- if (srx->skb_new < bytes)
+- return -EAGAIN;
++ bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new);
+
+ skb_copy_bits(skb, srx->skb_offset,
+ (char *)c_hdr + srx->fpdu_part_rcvd, bytes);
+@@ -1096,6 +1096,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
+ srx->skb_new -= bytes;
+ srx->skb_offset += bytes;
+ srx->skb_copied += bytes;
++
++ if (srx->fpdu_part_rcvd < hdrlen)
++ return -EAGAIN;
+ }
+
+ /*
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 8dedae7ae79e6..3e814cfb298cf 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -480,6 +480,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
++ init_completion(&qp->qp_free);
++
+ return 0;
+
+ err_out_xa:
+@@ -624,6 +626,7 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
+ qp->scq = qp->rcq = NULL;
+
+ siw_qp_put(qp);
++ wait_for_completion(&qp->qp_free);
+
+ return 0;
+ }
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index d7f69e593a63f..9c9872868aeea 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -2789,7 +2789,7 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
+ static int srp_abort(struct scsi_cmnd *scmnd)
+ {
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+- struct srp_request *req = (struct srp_request *) scmnd->host_scribble;
++ struct srp_request *req = scsi_cmd_priv(scmnd);
+ u32 tag;
+ u16 ch_idx;
+ struct srp_rdma_ch *ch;
+@@ -2797,8 +2797,6 @@ static int srp_abort(struct scsi_cmnd *scmnd)
+
+ shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
+
+- if (!req)
+- return SUCCESS;
+ tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmnd));
+ ch_idx = blk_mq_unique_tag_to_hwq(tag);
+ if (WARN_ON_ONCE(ch_idx >= target->ch_count))
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index d32b02336411d..71f7edded9cf2 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -2817,6 +2817,26 @@ static int arm_smmu_dev_disable_feature(struct device *dev,
+ }
+ }
+
++/*
++ * HiSilicon PCIe tune and trace device can be used to trace TLP headers on the
++ * PCIe link and save the data to memory by DMA. The hardware is restricted to
++ * use identity mapping only.
++ */
++#define IS_HISI_PTT_DEVICE(pdev) ((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \
++ (pdev)->device == 0xa12e)
++
++static int arm_smmu_def_domain_type(struct device *dev)
++{
++ if (dev_is_pci(dev)) {
++ struct pci_dev *pdev = to_pci_dev(dev);
++
++ if (IS_HISI_PTT_DEVICE(pdev))
++ return IOMMU_DOMAIN_IDENTITY;
++ }
++
++ return 0;
++}
++
+ static struct iommu_ops arm_smmu_ops = {
+ .capable = arm_smmu_capable,
+ .domain_alloc = arm_smmu_domain_alloc,
+@@ -2831,6 +2851,7 @@ static struct iommu_ops arm_smmu_ops = {
+ .sva_unbind = arm_smmu_sva_unbind,
+ .sva_get_pasid = arm_smmu_sva_get_pasid,
+ .page_response = arm_smmu_page_response,
++ .def_domain_type = arm_smmu_def_domain_type,
+ .pgsize_bitmap = -1UL, /* Restricted during device attach */
+ .owner = THIS_MODULE,
+ .default_domain_ops = &(const struct iommu_domain_ops) {
+diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
+index a99afb5d9011c..259f65291d909 100644
+--- a/drivers/iommu/omap-iommu-debug.c
++++ b/drivers/iommu/omap-iommu-debug.c
+@@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj)
+ ssize_t bytes; \
+ const char *str = "%20s: %08x\n"; \
+ const int maxcol = 32; \
+- bytes = snprintf(p, maxcol, str, __stringify(name), \
++ if (len < maxcol) \
++ goto out; \
++ bytes = scnprintf(p, maxcol, str, __stringify(name), \
+ iommu_read_reg(obj, MMU_##name)); \
+ p += bytes; \
+ len -= bytes; \
+- if (len < maxcol) \
+- goto out; \
+ } while (0)
+
+ static ssize_t
+diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
+index 7ea10db20e3a6..48133d0228120 100644
+--- a/drivers/isdn/mISDN/l1oip.h
++++ b/drivers/isdn/mISDN/l1oip.h
+@@ -59,6 +59,7 @@ struct l1oip {
+ int bundle; /* bundle channels in one frm */
+ int codec; /* codec to use for transmis. */
+ int limit; /* limit number of bchannels */
++ bool shutdown; /* if card is released */
+
+ /* timer */
+ struct timer_list keep_tl;
+diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
+index 2c40412466e6f..a77195e378b7b 100644
+--- a/drivers/isdn/mISDN/l1oip_core.c
++++ b/drivers/isdn/mISDN/l1oip_core.c
+@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
+ p = frame;
+
+ /* restart timer */
+- if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ))
++ if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown)
+ mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
+ else
+ hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
+@@ -601,7 +601,9 @@ multiframe:
+ goto multiframe;
+
+ /* restart timer */
+- if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) {
++ if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) ||
++ !hc->timeout_on) &&
++ !hc->shutdown) {
+ hc->timeout_on = 1;
+ mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
+ } else /* only adjust timer */
+@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc)
+ {
+ int ch;
+
+- if (timer_pending(&hc->keep_tl))
+- del_timer(&hc->keep_tl);
++ hc->shutdown = true;
+
+- if (timer_pending(&hc->timeout_tl))
+- del_timer(&hc->timeout_tl);
++ del_timer_sync(&hc->keep_tl);
++ del_timer_sync(&hc->timeout_tl);
+
+ cancel_work_sync(&hc->workq);
+
+diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c
+index d0e1d4814042e..3d12727482017 100644
+--- a/drivers/leds/flash/leds-lm3601x.c
++++ b/drivers/leds/flash/leds-lm3601x.c
+@@ -444,8 +444,6 @@ static int lm3601x_remove(struct i2c_client *client)
+ {
+ struct lm3601x_led *led = i2c_get_clientdata(client);
+
+- mutex_destroy(&led->lock);
+-
+ return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+ LM3601X_ENABLE_MASK,
+ LM3601X_MODE_STANDBY);
+diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c
+index fda16f76401e0..bf6e86b0ed09c 100644
+--- a/drivers/mailbox/bcm-flexrm-mailbox.c
++++ b/drivers/mailbox/bcm-flexrm-mailbox.c
+@@ -622,15 +622,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg)
+
+ rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
+ DMA_TO_DEVICE);
+- if (rc < 0)
+- return rc;
++ if (!rc)
++ return -EIO;
+
+ rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst),
+ DMA_FROM_DEVICE);
+- if (rc < 0) {
++ if (!rc) {
+ dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
+ DMA_TO_DEVICE);
+- return rc;
++ return -EIO;
+ }
+
+ return 0;
+diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
+index 02922073c9efd..20f2ec880ad69 100644
+--- a/drivers/mailbox/imx-mailbox.c
++++ b/drivers/mailbox/imx-mailbox.c
+@@ -904,7 +904,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
+ .xTR = 0x20,
+ .xRR = 0x40,
+ .xSR = {0x60, 0x60, 0x60, 0x60},
+- .xCR = {0x64, 0x64, 0x64, 0x64},
++ .xCR = {0x64, 0x64, 0x64, 0x64, 0x64},
+ };
+
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
+@@ -927,7 +927,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = {
+ .xTR = 0x200,
+ .xRR = 0x280,
+ .xSR = {0xC, 0x118, 0x124, 0x12C},
+- .xCR = {0x110, 0x114, 0x120, 0x128},
++ .xCR = {0x8, 0x110, 0x114, 0x120, 0x128},
+ };
+
+ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
+@@ -938,7 +938,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
+ .xTR = 0x200,
+ .xRR = 0x280,
+ .xSR = {0xC, 0x118, 0x124, 0x12C},
+- .xCR = {0x110, 0x114, 0x120, 0x128},
++ .xCR = {0x8, 0x110, 0x114, 0x120, 0x128},
+ };
+
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
+@@ -949,7 +949,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
+ .xTR = 0x0,
+ .xRR = 0x10,
+ .xSR = {0x20, 0x20, 0x20, 0x20},
+- .xCR = {0x24, 0x24, 0x24, 0x24},
++ .xCR = {0x24, 0x24, 0x24, 0x24, 0x24},
+ };
+
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
+@@ -960,7 +960,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
+ .xTR = 0x0,
+ .xRR = 0x10,
+ .xSR = {0x20, 0x20, 0x20, 0x20},
+- .xCR = {0x24, 0x24, 0x24, 0x24},
++ .xCR = {0x24, 0x24, 0x24, 0x24, 0x24},
+ };
+
+ static const struct of_device_id imx_mu_dt_ids[] = {
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
+index 4e34854d12389..cfacb3f320a64 100644
+--- a/drivers/mailbox/mailbox-mpfs.c
++++ b/drivers/mailbox/mailbox-mpfs.c
+@@ -62,6 +62,7 @@ struct mpfs_mbox {
+ struct mbox_controller controller;
+ struct device *dev;
+ int irq;
++ void __iomem *ctrl_base;
+ void __iomem *mbox_base;
+ void __iomem *int_reg;
+ struct mbox_chan chans[1];
+@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
+ {
+ u32 status;
+
+- status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET);
++ status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
+
+ return status & SCB_STATUS_BUSY_MASK;
+ }
+@@ -99,29 +100,27 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
+
+ for (index = 0; index < (msg->cmd_data_size / 4); index++)
+ writel_relaxed(word_buf[index],
+- mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
++ mbox->mbox_base + msg->mbox_offset + index * 0x4);
+ if (extra_bits) {
+ u8 i;
+ u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
+ u8 *byte_buf = msg->cmd_data + byte_off;
+
+- val = readl_relaxed(mbox->mbox_base +
+- MAILBOX_REG_OFFSET + index * 0x4);
++ val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4);
+
+ for (i = 0u; i < extra_bits; i++) {
+ val &= ~(0xffu << (i * 8u));
+ val |= (byte_buf[i] << (i * 8u));
+ }
+
+- writel_relaxed(val,
+- mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
++ writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4);
+ }
+ }
+
+ opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
+ tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK;
+ tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK;
+- writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET);
++ writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET);
+
+ return 0;
+ }
+@@ -141,7 +140,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
+ if (!mpfs_mbox_busy(mbox)) {
+ for (i = 0; i < num_words; i++) {
+ response->resp_msg[i] =
+- readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET
++ readl_relaxed(mbox->mbox_base
+ + mbox->resp_offset + i * 0x4);
+ }
+ }
+@@ -200,14 +199,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
+ if (!mbox)
+ return -ENOMEM;
+
+- mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);
+- if (IS_ERR(mbox->mbox_base))
+- return PTR_ERR(mbox->mbox_base);
++ mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);
++ if (IS_ERR(mbox->ctrl_base))
++ return PTR_ERR(mbox->ctrl_base);
+
+ mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, ®s);
+ if (IS_ERR(mbox->int_reg))
+ return PTR_ERR(mbox->int_reg);
+
++ mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, ®s);
++ if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs
++ mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET;
++
+ mbox->irq = platform_get_irq(pdev, 0);
+ if (mbox->irq < 0)
+ return mbox->irq;
+diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
+index 3f0ff3aab6f23..9c227e4a84654 100644
+--- a/drivers/md/bcache/writeback.c
++++ b/drivers/md/bcache/writeback.c
+@@ -157,6 +157,53 @@ static void __update_writeback_rate(struct cached_dev *dc)
+ dc->writeback_rate_target = target;
+ }
+
++static bool idle_counter_exceeded(struct cache_set *c)
++{
++ int counter, dev_nr;
++
++ /*
++ * If c->idle_counter is overflow (idel for really long time),
++ * reset as 0 and not set maximum rate this time for code
++ * simplicity.
++ */
++ counter = atomic_inc_return(&c->idle_counter);
++ if (counter <= 0) {
++ atomic_set(&c->idle_counter, 0);
++ return false;
++ }
++
++ dev_nr = atomic_read(&c->attached_dev_nr);
++ if (dev_nr == 0)
++ return false;
++
++ /*
++ * c->idle_counter is increased by writeback thread of all
++ * attached backing devices, in order to represent a rough
++ * time period, counter should be divided by dev_nr.
++ * Otherwise the idle time cannot be larger with more backing
++ * device attached.
++ * The following calculation equals to checking
++ * (counter / dev_nr) < (dev_nr * 6)
++ */
++ if (counter < (dev_nr * dev_nr * 6))
++ return false;
++
++ return true;
++}
++
++/*
++ * Idle_counter is increased every time when update_writeback_rate() is
++ * called. If all backing devices attached to the same cache set have
++ * identical dc->writeback_rate_update_seconds values, it is about 6
++ * rounds of update_writeback_rate() on each backing device before
++ * c->at_max_writeback_rate is set to 1, and then max wrteback rate set
++ * to each dc->writeback_rate.rate.
++ * In order to avoid extra locking cost for counting exact dirty cached
++ * devices number, c->attached_dev_nr is used to calculate the idle
++ * throushold. It might be bigger if not all cached device are in write-
++ * back mode, but it still works well with limited extra rounds of
++ * update_writeback_rate().
++ */
+ static bool set_at_max_writeback_rate(struct cache_set *c,
+ struct cached_dev *dc)
+ {
+@@ -167,21 +214,8 @@ static bool set_at_max_writeback_rate(struct cache_set *c,
+ /* Don't set max writeback rate if gc is running */
+ if (!c->gc_mark_valid)
+ return false;
+- /*
+- * Idle_counter is increased everytime when update_writeback_rate() is
+- * called. If all backing devices attached to the same cache set have
+- * identical dc->writeback_rate_update_seconds values, it is about 6
+- * rounds of update_writeback_rate() on each backing device before
+- * c->at_max_writeback_rate is set to 1, and then max wrteback rate set
+- * to each dc->writeback_rate.rate.
+- * In order to avoid extra locking cost for counting exact dirty cached
+- * devices number, c->attached_dev_nr is used to calculate the idle
+- * throushold. It might be bigger if not all cached device are in write-
+- * back mode, but it still works well with limited extra rounds of
+- * update_writeback_rate().
+- */
+- if (atomic_inc_return(&c->idle_counter) <
+- atomic_read(&c->attached_dev_nr) * 6)
++
++ if (!idle_counter_exceeded(c))
+ return false;
+
+ if (atomic_read(&c->at_max_writeback_rate) != 1)
+@@ -195,13 +229,10 @@ static bool set_at_max_writeback_rate(struct cache_set *c,
+ dc->writeback_rate_change = 0;
+
+ /*
+- * Check c->idle_counter and c->at_max_writeback_rate agagain in case
+- * new I/O arrives during before set_at_max_writeback_rate() returns.
+- * Then the writeback rate is set to 1, and its new value should be
+- * decided via __update_writeback_rate().
++ * In case new I/O arrives during before
++ * set_at_max_writeback_rate() returns.
+ */
+- if ((atomic_read(&c->idle_counter) <
+- atomic_read(&c->attached_dev_nr) * 6) ||
++ if (!idle_counter_exceeded(c) ||
+ !atomic_read(&c->at_max_writeback_rate))
+ return false;
+
+diff --git a/drivers/md/dm-verity-loadpin.c b/drivers/md/dm-verity-loadpin.c
+index 387ec43aef728..4f78cc55c2514 100644
+--- a/drivers/md/dm-verity-loadpin.c
++++ b/drivers/md/dm-verity-loadpin.c
+@@ -14,6 +14,7 @@ LIST_HEAD(dm_verity_loadpin_trusted_root_digests);
+
+ static bool is_trusted_verity_target(struct dm_target *ti)
+ {
++ int verity_mode;
+ u8 *root_digest;
+ unsigned int digest_size;
+ struct dm_verity_loadpin_trusted_root_digest *trd;
+@@ -22,6 +23,13 @@ static bool is_trusted_verity_target(struct dm_target *ti)
+ if (!dm_is_verity_target(ti))
+ return false;
+
++ verity_mode = dm_verity_get_mode(ti);
++
++ if ((verity_mode != DM_VERITY_MODE_EIO) &&
++ (verity_mode != DM_VERITY_MODE_RESTART) &&
++ (verity_mode != DM_VERITY_MODE_PANIC))
++ return false;
++
+ if (dm_verity_get_root_digest(ti, &root_digest, &digest_size))
+ return false;
+
+diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
+index 94b6cb599db4f..8a00cc42e4985 100644
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -1446,6 +1446,22 @@ bool dm_is_verity_target(struct dm_target *ti)
+ return ti->type->module == THIS_MODULE;
+ }
+
++/*
++ * Get the verity mode (error behavior) of a verity target.
++ *
++ * Returns the verity mode of the target, or -EINVAL if 'ti' is not a verity
++ * target.
++ */
++int dm_verity_get_mode(struct dm_target *ti)
++{
++ struct dm_verity *v = ti->private;
++
++ if (!dm_is_verity_target(ti))
++ return -EINVAL;
++
++ return v->mode;
++}
++
+ /*
+ * Get the root digest of a verity target.
+ *
+diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
+index 45455de1b4bc5..98f306ec6a33d 100644
+--- a/drivers/md/dm-verity.h
++++ b/drivers/md/dm-verity.h
+@@ -134,6 +134,7 @@ extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
+ sector_t block, u8 *digest, bool *is_zero);
+
+ extern bool dm_is_verity_target(struct dm_target *ti);
++extern int dm_verity_get_mode(struct dm_target *ti);
+ extern int dm_verity_get_root_digest(struct dm_target *ti, u8 **root_digest,
+ unsigned int *digest_size);
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 729be2c5296c6..470a975e4be9b 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8156,7 +8156,6 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos)
+ list_for_each(tmp,&all_mddevs)
+ if (!l--) {
+ mddev = list_entry(tmp, struct mddev, all_mddevs);
+- mddev_get(mddev);
+ if (!mddev_get(mddev))
+ continue;
+ spin_unlock(&all_mddevs_lock);
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 78addfe4a0c92..857c49399c28e 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -47,7 +47,7 @@ static void dump_zones(struct mddev *mddev)
+ int len = 0;
+
+ for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
+- len += snprintf(line+len, 200-len, "%s%pg", k?"/":"",
++ len += scnprintf(line+len, 200-len, "%s%pg", k?"/":"",
+ conf->devlist[j * raid_disks + k]->bdev);
+ pr_debug("md: zone%d=[%s]\n", j, line);
+
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 31a0cbf63384d..caaae10e33f81 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -36,6 +36,7 @@
+ */
+
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -4047,7 +4048,7 @@ static void handle_stripe_fill(struct stripe_head *sh,
+ * back cache (prexor with orig_page, and then xor with
+ * page) in the read path
+ */
+- if (s->injournal && s->failed) {
++ if (s->to_read && s->injournal && s->failed) {
+ if (test_bit(STRIPE_R5C_CACHING, &sh->state))
+ r5c_make_stripe_write_out(sh);
+ goto out;
+@@ -5542,7 +5543,6 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
+
+ if (is_badblock(rdev, sector, bio_sectors(raid_bio), &first_bad,
+ &bad_sectors)) {
+- bio_put(raid_bio);
+ rdev_dec_pending(rdev, mddev);
+ return 0;
+ }
+@@ -6781,7 +6781,18 @@ static void raid5d(struct md_thread *thread)
+ spin_unlock_irq(&conf->device_lock);
+ md_check_recovery(mddev);
+ spin_lock_irq(&conf->device_lock);
++
++ /*
++ * Waiting on MD_SB_CHANGE_PENDING below may deadlock
++ * seeing md_check_recovery() is needed to clear
++ * the flag when using mdmon.
++ */
++ continue;
+ }
++
++ wait_event_lock_irq(mddev->sb_wait,
++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags),
++ conf->device_lock);
+ }
+ pr_debug("%d stripes handled\n", handled);
+
+diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
+index a075788c64d45..469aeaa725ad9 100644
+--- a/drivers/media/pci/cx88/cx88-vbi.c
++++ b/drivers/media/pci/cx88/cx88-vbi.c
+@@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ return -EINVAL;
+ vb2_set_plane_payload(vb, 0, size);
+
+- cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
+- 0, VBI_LINE_LENGTH * lines,
+- VBI_LINE_LENGTH, 0,
+- lines);
+- return 0;
++ return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
++ 0, VBI_LINE_LENGTH * lines,
++ VBI_LINE_LENGTH, 0,
++ lines);
+ }
+
+ static void buffer_finish(struct vb2_buffer *vb)
+diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
+index d3729be892529..b509c2a03852b 100644
+--- a/drivers/media/pci/cx88/cx88-video.c
++++ b/drivers/media/pci/cx88/cx88-video.c
+@@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q,
+
+ static int buffer_prepare(struct vb2_buffer *vb)
+ {
++ int ret;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx88_core *core = dev->core;
+@@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb)
+
+ switch (core->field) {
+ case V4L2_FIELD_TOP:
+- cx88_risc_buffer(dev->pci, &buf->risc,
+- sgt->sgl, 0, UNSET,
+- buf->bpl, 0, core->height);
++ ret = cx88_risc_buffer(dev->pci, &buf->risc,
++ sgt->sgl, 0, UNSET,
++ buf->bpl, 0, core->height);
+ break;
+ case V4L2_FIELD_BOTTOM:
+- cx88_risc_buffer(dev->pci, &buf->risc,
+- sgt->sgl, UNSET, 0,
+- buf->bpl, 0, core->height);
++ ret = cx88_risc_buffer(dev->pci, &buf->risc,
++ sgt->sgl, UNSET, 0,
++ buf->bpl, 0, core->height);
+ break;
+ case V4L2_FIELD_SEQ_TB:
+- cx88_risc_buffer(dev->pci, &buf->risc,
+- sgt->sgl,
+- 0, buf->bpl * (core->height >> 1),
+- buf->bpl, 0,
+- core->height >> 1);
++ ret = cx88_risc_buffer(dev->pci, &buf->risc,
++ sgt->sgl,
++ 0, buf->bpl * (core->height >> 1),
++ buf->bpl, 0,
++ core->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_BT:
+- cx88_risc_buffer(dev->pci, &buf->risc,
+- sgt->sgl,
+- buf->bpl * (core->height >> 1), 0,
+- buf->bpl, 0,
+- core->height >> 1);
++ ret = cx88_risc_buffer(dev->pci, &buf->risc,
++ sgt->sgl,
++ buf->bpl * (core->height >> 1), 0,
++ buf->bpl, 0,
++ core->height >> 1);
+ break;
+ case V4L2_FIELD_INTERLACED:
+ default:
+- cx88_risc_buffer(dev->pci, &buf->risc,
+- sgt->sgl, 0, buf->bpl,
+- buf->bpl, buf->bpl,
+- core->height >> 1);
++ ret = cx88_risc_buffer(dev->pci, &buf->risc,
++ sgt->sgl, 0, buf->bpl,
++ buf->bpl, buf->bpl,
++ core->height >> 1);
+ break;
+ }
+ dprintk(2,
+@@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ buf, buf->vb.vb2_buf.index, __func__,
+ core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
+ (unsigned long)buf->risc.dma);
+- return 0;
++ return ret;
+ }
+
+ static void buffer_finish(struct vb2_buffer *vb)
+diff --git a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+index 5e7b319f300df..142d421a8d769 100644
+--- a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
++++ b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+@@ -1030,7 +1030,6 @@ static int ge2d_remove(struct platform_device *pdev)
+
+ video_unregister_device(ge2d->vfd);
+ v4l2_m2m_release(ge2d->m2m_dev);
+- video_device_release(ge2d->vfd);
+ v4l2_device_unregister(&ge2d->v4l2_dev);
+ clk_disable_unprepare(ge2d->clk);
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 9e64041cc1c1d..feb75dc204de8 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -808,14 +808,6 @@ static void vdec_init_fmt(struct vpu_inst *inst)
+ inst->cap_format.field = V4L2_FIELD_NONE;
+ else
+ inst->cap_format.field = V4L2_FIELD_SEQ_TB;
+- if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+- vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+- if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+- vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+- if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+- vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+- if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+- vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+ }
+
+ static void vdec_init_crop(struct vpu_inst *inst)
+@@ -1555,6 +1547,14 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
+ vdec->codec_info.frame_rate.numerator,
+ vdec->codec_info.frame_rate.denominator);
+ break;
++ case 9:
++ num = scnprintf(str, size, "colorspace: %d, %d, %d, %d (%d)\n",
++ vdec->codec_info.color_primaries,
++ vdec->codec_info.transfer_chars,
++ vdec->codec_info.matrix_coeffs,
++ vdec->codec_info.full_range,
++ vdec->codec_info.vui_present);
++ break;
+ default:
+ break;
+ }
+diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
+index 461524dd1e441..37212f087fdd9 100644
+--- a/drivers/media/platform/amphion/venc.c
++++ b/drivers/media/platform/amphion/venc.c
+@@ -644,7 +644,7 @@ static int venc_ctrl_init(struct vpu_inst *inst)
+ BITRATE_DEFAULT_PEAK);
+
+ v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+- V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
++ V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);
+
+ v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index f914de6ed81e9..beac0309ca8d9 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -119,7 +119,6 @@ struct vpu_mbox {
+ enum vpu_core_state {
+ VPU_CORE_DEINIT = 0,
+ VPU_CORE_ACTIVE,
+- VPU_CORE_SNAPSHOT,
+ VPU_CORE_HANG
+ };
+
+diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
+index 73faa50d28653..f9ec1753f7c86 100644
+--- a/drivers/media/platform/amphion/vpu_core.c
++++ b/drivers/media/platform/amphion/vpu_core.c
+@@ -89,7 +89,7 @@ static int vpu_core_boot_done(struct vpu_core *core)
+ core->supported_instance_count = min(core->supported_instance_count, count);
+ }
+ core->fw_version = fw_version;
+- core->state = VPU_CORE_ACTIVE;
++ vpu_core_set_state(core, VPU_CORE_ACTIVE);
+
+ return 0;
+ }
+@@ -172,10 +172,26 @@ int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+ return __vpu_alloc_dma(core->dev, buf);
+ }
+
+-static void vpu_core_check_hang(struct vpu_core *core)
++void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state)
+ {
+- if (core->hang_mask)
+- core->state = VPU_CORE_HANG;
++ if (state != core->state)
++ vpu_trace(core->dev, "vpu core state change from %d to %d\n", core->state, state);
++ core->state = state;
++ if (core->state == VPU_CORE_DEINIT)
++ core->hang_mask = 0;
++}
++
++static void vpu_core_update_state(struct vpu_core *core)
++{
++ if (!vpu_iface_get_power_state(core)) {
++ if (core->request_count)
++ vpu_core_set_state(core, VPU_CORE_HANG);
++ else
++ vpu_core_set_state(core, VPU_CORE_DEINIT);
++
++ } else if (core->state == VPU_CORE_ACTIVE && core->hang_mask) {
++ vpu_core_set_state(core, VPU_CORE_HANG);
++ }
+ }
+
+ static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+@@ -188,11 +204,13 @@ static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 ty
+ dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state);
+ if (c->type != type)
+ continue;
++ mutex_lock(&c->lock);
++ vpu_core_update_state(c);
++ mutex_unlock(&c->lock);
+ if (c->state == VPU_CORE_DEINIT) {
+ core = c;
+ break;
+ }
+- vpu_core_check_hang(c);
+ if (c->state != VPU_CORE_ACTIVE)
+ continue;
+ if (c->request_count < request_count) {
+@@ -409,6 +427,12 @@ int vpu_inst_register(struct vpu_inst *inst)
+ }
+
+ mutex_lock(&core->lock);
++ if (core->state != VPU_CORE_ACTIVE) {
++ dev_err(core->dev, "vpu core is not active, state = %d\n", core->state);
++ ret = -EINVAL;
++ goto exit;
++ }
++
+ if (inst->id >= 0 && inst->id < core->supported_instance_count)
+ goto exit;
+
+@@ -450,7 +474,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
+ vpu_core_release_instance(core, inst->id);
+ inst->id = VPU_INST_NULL_ID;
+ }
+- vpu_core_check_hang(core);
++ vpu_core_update_state(core);
+ if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+ int err;
+
+@@ -459,7 +483,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
+ err = vpu_core_sw_reset(core);
+ mutex_lock(&core->lock);
+ if (!err) {
+- core->state = VPU_CORE_ACTIVE;
++ vpu_core_set_state(core, VPU_CORE_ACTIVE);
+ core->hang_mask = 0;
+ }
+ }
+@@ -609,7 +633,7 @@ static int vpu_core_probe(struct platform_device *pdev)
+ mutex_init(&core->cmd_lock);
+ init_completion(&core->cmp);
+ init_waitqueue_head(&core->ack_wq);
+- core->state = VPU_CORE_DEINIT;
++ vpu_core_set_state(core, VPU_CORE_DEINIT);
+
+ core->res = of_device_get_match_data(dev);
+ if (!core->res)
+@@ -758,33 +782,18 @@ static int __maybe_unused vpu_core_resume(struct device *dev)
+ mutex_lock(&core->lock);
+ pm_runtime_resume_and_get(dev);
+ vpu_core_get_vpu(core);
+- if (core->state != VPU_CORE_SNAPSHOT)
+- goto exit;
+
+- if (!vpu_iface_get_power_state(core)) {
+- if (!list_empty(&core->instances)) {
++ if (core->request_count) {
++ if (!vpu_iface_get_power_state(core))
+ ret = vpu_core_boot(core, false);
+- if (ret) {
+- dev_err(core->dev, "%s boot fail\n", __func__);
+- core->state = VPU_CORE_DEINIT;
+- goto exit;
+- }
+- } else {
+- core->state = VPU_CORE_DEINIT;
+- }
+- } else {
+- if (!list_empty(&core->instances)) {
++ else
+ ret = vpu_core_sw_reset(core);
+- if (ret) {
+- dev_err(core->dev, "%s sw_reset fail\n", __func__);
+- core->state = VPU_CORE_HANG;
+- goto exit;
+- }
++ if (ret) {
++ dev_err(core->dev, "resume fail\n");
++ vpu_core_set_state(core, VPU_CORE_HANG);
+ }
+- core->state = VPU_CORE_ACTIVE;
+ }
+-
+-exit:
++ vpu_core_update_state(core);
+ pm_runtime_put_sync(dev);
+ mutex_unlock(&core->lock);
+
+@@ -798,18 +807,11 @@ static int __maybe_unused vpu_core_suspend(struct device *dev)
+ int ret = 0;
+
+ mutex_lock(&core->lock);
+- if (core->state == VPU_CORE_ACTIVE) {
+- if (!list_empty(&core->instances)) {
+- ret = vpu_core_snapshot(core);
+- if (ret) {
+- mutex_unlock(&core->lock);
+- return ret;
+- }
+- }
+-
+- core->state = VPU_CORE_SNAPSHOT;
+- }
++ if (core->request_count)
++ ret = vpu_core_snapshot(core);
+ mutex_unlock(&core->lock);
++ if (ret)
++ return ret;
+
+ vpu_core_cancel_work(core);
+
+diff --git a/drivers/media/platform/amphion/vpu_core.h b/drivers/media/platform/amphion/vpu_core.h
+index 00a662997da4f..65b562642603a 100644
+--- a/drivers/media/platform/amphion/vpu_core.h
++++ b/drivers/media/platform/amphion/vpu_core.h
+@@ -11,5 +11,6 @@ u32 csr_readl(struct vpu_core *core, u32 reg);
+ int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+ void vpu_free_dma(struct vpu_buffer *buf);
+ struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
++void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state);
+
+ #endif
+diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
+index f72c8a506b220..260f1c4b8f8dc 100644
+--- a/drivers/media/platform/amphion/vpu_dbg.c
++++ b/drivers/media/platform/amphion/vpu_dbg.c
+@@ -15,6 +15,7 @@
+ #include <linux/debugfs.h>
+ #include "vpu.h"
+ #include "vpu_defs.h"
++#include "vpu_core.h"
+ #include "vpu_helpers.h"
+ #include "vpu_cmds.h"
+ #include "vpu_rpc.h"
+@@ -233,6 +234,10 @@ static int vpu_dbg_core(struct seq_file *s, void *data)
+ if (seq_write(s, str, num))
+ return 0;
+
++ num = scnprintf(str, sizeof(str), "power %s\n",
++ vpu_iface_get_power_state(core) ? "on" : "off");
++ if (seq_write(s, str, num))
++ return 0;
+ num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+ if (seq_write(s, str, num))
+ return 0;
+@@ -346,10 +351,10 @@ static ssize_t vpu_dbg_core_write(struct file *file,
+
+ pm_runtime_resume_and_get(core->dev);
+ mutex_lock(&core->lock);
+- if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
++ if (vpu_iface_get_power_state(core) && !core->request_count) {
+ dev_info(core->dev, "reset\n");
+ if (!vpu_core_sw_reset(core)) {
+- core->state = VPU_CORE_ACTIVE;
++ vpu_core_set_state(core, VPU_CORE_ACTIVE);
+ core->hang_mask = 0;
+ }
+ }
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index f4a488bf98801..51e0702f9ae17 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -1293,7 +1293,7 @@ static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+ vbuf = to_vb2_v4l2_buffer(scode->vb);
+ data = vb2_plane_vaddr(scode->vb, 0);
+
+- if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
++ if (scode->inst->total_input_count == 0 || vpu_vb_is_codecconfig(vbuf))
+ return 0;
+ if (MALONE_VC1_CONTAIN_NAL(*data))
+ return 0;
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+index 87685a62a5c23..3071b61946c3b 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+@@ -1414,7 +1414,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
+
+ pm_runtime_disable(&pdev->dev);
+ video_unregister_device(jpeg->vdev);
+- video_device_release(jpeg->vdev);
+ v4l2_m2m_release(jpeg->m2m_dev);
+ v4l2_device_unregister(&jpeg->v4l2_dev);
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+index 25e8168635975..27c5fdaabed45 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+@@ -1403,7 +1403,8 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
+ V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
+ v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+- 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
++ ~(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
++ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+
+ if (handler->error) {
+diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+index e3072d69c49fa..a7704ff069d6c 100644
+--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+@@ -213,6 +213,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is)
+
+ if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
+ of_node_put(child);
++ of_node_put(i2c_bus);
+ return ret;
+ }
+ index++;
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+index 761341934925e..f85d1eebaface 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+@@ -1399,6 +1399,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
+ /* Deinit MFC if probe had failed */
+ err_enc_reg:
+ video_unregister_device(dev->vfd_dec);
++ dev->vfd_dec = NULL;
+ err_dec_reg:
+ video_device_release(dev->vfd_enc);
+ err_enc_alloc:
+@@ -1444,8 +1445,6 @@ static int s5p_mfc_remove(struct platform_device *pdev)
+
+ video_unregister_device(dev->vfd_enc);
+ video_unregister_device(dev->vfd_dec);
+- video_device_release(dev->vfd_enc);
+- video_device_release(dev->vfd_dec);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ s5p_mfc_unconfigure_dma_memory(dev);
+
+diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
+index f34f8b077e03c..0a16c218a50a7 100644
+--- a/drivers/media/platform/xilinx/xilinx-vipp.c
++++ b/drivers/media/platform/xilinx/xilinx-vipp.c
+@@ -471,7 +471,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
+ {
+ struct device_node *ports;
+ struct device_node *port;
+- int ret;
++ int ret = 0;
+
+ ports = of_get_child_by_name(xdev->dev->of_node, "ports");
+ if (ports == NULL) {
+@@ -481,13 +481,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
+
+ for_each_child_of_node(ports, port) {
+ ret = xvip_graph_dma_init_one(xdev, port);
+- if (ret < 0) {
++ if (ret) {
+ of_node_put(port);
+- return ret;
++ break;
+ }
+ }
+
+- return 0;
++ of_node_put(ports);
++ return ret;
+ }
+
+ static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
+diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
+index 240a7cc56777d..7b1c40132555b 100644
+--- a/drivers/media/usb/airspy/airspy.c
++++ b/drivers/media/usb/airspy/airspy.c
+@@ -1070,6 +1070,10 @@ static int airspy_probe(struct usb_interface *intf,
+ ret);
+ goto err_free_controls;
+ }
++
++ /* Free buf if success*/
++ kfree(buf);
++
+ dev_info(s->dev, "Registered as %s\n",
+ video_device_node_name(&s->vdev));
+ dev_notice(s->dev, "SDR API is still slightly experimental and functionality changes may follow\n");
+diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
+index 8c208db9600b4..53250ea75dfb7 100644
+--- a/drivers/media/usb/uvc/uvc_ctrl.c
++++ b/drivers/media/usb/uvc/uvc_ctrl.c
+@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
+ return value;
+ }
+
+-static int __uvc_ctrl_get(struct uvc_video_chain *chain,
+- struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
+- s32 *value)
++static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
++ struct uvc_control *ctrl)
+ {
++ u8 *data;
+ int ret;
+
+- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
+- return -EACCES;
++ if (ctrl->loaded)
++ return 0;
+
+- if (!ctrl->loaded) {
+- if (ctrl->entity->get_cur) {
+- ret = ctrl->entity->get_cur(chain->dev,
+- ctrl->entity,
+- ctrl->info.selector,
+- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+- ctrl->info.size);
+- } else {
+- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+- ctrl->entity->id,
+- chain->dev->intfnum,
+- ctrl->info.selector,
+- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+- ctrl->info.size);
+- }
+- if (ret < 0)
+- return ret;
++ data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
+
++ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
++ memset(data, 0, ctrl->info.size);
+ ctrl->loaded = 1;
++
++ return 0;
+ }
+
++ if (ctrl->entity->get_cur)
++ ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,
++ ctrl->info.selector, data,
++ ctrl->info.size);
++ else
++ ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
++ ctrl->entity->id, chain->dev->intfnum,
++ ctrl->info.selector, data,
++ ctrl->info.size);
++
++ if (ret < 0)
++ return ret;
++
++ ctrl->loaded = 1;
++
++ return ret;
++}
++
++static int __uvc_ctrl_get(struct uvc_video_chain *chain,
++ struct uvc_control *ctrl,
++ struct uvc_control_mapping *mapping,
++ s32 *value)
++{
++ int ret;
++
++ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
++ return -EACCES;
++
++ ret = __uvc_ctrl_load_cur(chain, ctrl);
++ if (ret < 0)
++ return ret;
++
+ *value = __uvc_ctrl_get_value(mapping,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+
+@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,
+ * needs to be loaded from the device to perform the read-modify-write
+ * operation.
+ */
+- if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
+- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
+- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+- 0, ctrl->info.size);
+- } else {
+- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+- ctrl->entity->id, chain->dev->intfnum,
+- ctrl->info.selector,
+- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+- ctrl->info.size);
+- if (ret < 0)
+- return ret;
+- }
+-
+- ctrl->loaded = 1;
++ if ((ctrl->info.size * 8) != mapping->size) {
++ ret = __uvc_ctrl_load_cur(chain, ctrl);
++ if (ret < 0)
++ return ret;
+ }
+
+ /* Backup the current value in case we need to rollback later. */
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index d509a4a2f08e9..822e9694f0926 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1553,10 +1553,6 @@ static int uvc_gpio_parse(struct uvc_device *dev)
+ if (IS_ERR_OR_NULL(gpio_privacy))
+ return PTR_ERR_OR_ZERO(gpio_privacy);
+
+- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
+- if (!unit)
+- return -ENOMEM;
+-
+ irq = gpiod_to_irq(gpio_privacy);
+ if (irq < 0) {
+ if (irq != EPROBE_DEFER)
+@@ -1565,6 +1561,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
+ return irq;
+ }
+
++ unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
++ if (!unit)
++ return -ENOMEM;
++
+ unit->gpio.gpio_privacy = gpio_privacy;
+ unit->gpio.irq = irq;
+ unit->gpio.bControlSize = 1;
+diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c
+index dbdf87bc0b78e..fcd20d85d3857 100644
+--- a/drivers/memory/of_memory.c
++++ b/drivers/memory/of_memory.c
+@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,
+ for_each_child_of_node(np_ddr, np_tim) {
+ if (of_device_is_compatible(np_tim, tim_compat)) {
+ if (of_do_get_timings(np_tim, &timings[i])) {
++ of_node_put(np_tim);
+ devm_kfree(dev, timings);
+ goto default_timings;
+ }
+@@ -284,6 +285,7 @@ const struct lpddr3_timings
+ if (of_device_is_compatible(np_tim, tim_compat)) {
+ if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
+ devm_kfree(dev, timings);
++ of_node_put(np_tim);
+ goto default_timings;
+ }
+ i++;
+diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c
+index f84b98278745c..d39ee7d06665b 100644
+--- a/drivers/memory/pl353-smc.c
++++ b/drivers/memory/pl353-smc.c
+@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
+ }
+
+ of_platform_device_create(child, NULL, &adev->dev);
++ of_node_put(child);
+
+ return 0;
+
+diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
+index 2774b2cbaea6d..c2acdbcd5d6b6 100644
+--- a/drivers/mfd/da9062-core.c
++++ b/drivers/mfd/da9062-core.c
+@@ -453,6 +453,7 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = {
+ regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
+ regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+ regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
++ regmap_reg_range(DA9062AA_CONFIG_J, DA9062AA_CONFIG_J),
+ regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
+ };
+
+diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c
+index 37e5e02a1d059..823595bcc9b7c 100644
+--- a/drivers/mfd/fsl-imx25-tsadc.c
++++ b/drivers/mfd/fsl-imx25-tsadc.c
+@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,
+ int irq;
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq <= 0)
++ if (irq < 0)
+ return irq;
+
+ tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
+@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,
+ return 0;
+ }
+
++static int mx25_tsadc_unset_irq(struct platform_device *pdev)
++{
++ struct mx25_tsadc *tsadc = platform_get_drvdata(pdev);
++ int irq = platform_get_irq(pdev, 0);
++
++ if (irq >= 0) {
++ irq_set_chained_handler_and_data(irq, NULL, NULL);
++ irq_domain_remove(tsadc->domain);
++ }
++
++ return 0;
++}
++
+ static void mx25_tsadc_setup_clk(struct platform_device *pdev,
+ struct mx25_tsadc *tsadc)
+ {
+@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, tsadc);
+
+- return devm_of_platform_populate(dev);
++ ret = devm_of_platform_populate(dev);
++ if (ret)
++ goto err_irq;
++
++ return 0;
++
++err_irq:
++ mx25_tsadc_unset_irq(pdev);
++
++ return ret;
+ }
+
+ static int mx25_tsadc_remove(struct platform_device *pdev)
+ {
+- struct mx25_tsadc *tsadc = platform_get_drvdata(pdev);
+- int irq = platform_get_irq(pdev, 0);
+-
+- if (irq) {
+- irq_set_chained_handler_and_data(irq, NULL, NULL);
+- irq_domain_remove(tsadc->domain);
+- }
++ mx25_tsadc_unset_irq(pdev);
+
+ return 0;
+ }
+diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
+index 5e8c94e008ed1..85d070bce0e2b 100644
+--- a/drivers/mfd/intel_soc_pmic_core.c
++++ b/drivers/mfd/intel_soc_pmic_core.c
+@@ -77,6 +77,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
+ return 0;
+
+ err_del_irq_chip:
++ pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup));
+ regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
+ return ret;
+ }
+diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
+index 348439a3fbbd4..39006297f3d27 100644
+--- a/drivers/mfd/lp8788-irq.c
++++ b/drivers/mfd/lp8788-irq.c
+@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq)
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "lp8788-irq", irqd);
+ if (ret) {
++ irq_domain_remove(lp->irqdm);
+ dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
+ return ret;
+ }
+@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp)
+ {
+ if (lp->irq)
+ free_irq(lp->irq, lp->irqdm);
++ if (lp->irqdm)
++ irq_domain_remove(lp->irqdm);
+ }
+diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
+index c223d2c6a3635..998e8cc408a0e 100644
+--- a/drivers/mfd/lp8788.c
++++ b/drivers/mfd/lp8788.c
+@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+ if (ret)
+ return ret;
+
+- return mfd_add_devices(lp->dev, -1, lp8788_devs,
+- ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
++ ret = mfd_add_devices(lp->dev, -1, lp8788_devs,
++ ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
++ if (ret)
++ goto err_exit_irq;
++
++ return 0;
++
++err_exit_irq:
++ lp8788_irq_exit(lp);
++ return ret;
+ }
+
+ static int lp8788_remove(struct i2c_client *cl)
+diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
+index bc0a2c38653e5..3ac4508a6742a 100644
+--- a/drivers/mfd/sm501.c
++++ b/drivers/mfd/sm501.c
+@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = {
+
+ static int __init sm501_base_init(void)
+ {
+- platform_driver_register(&sm501_plat_driver);
++ int ret;
++
++ ret = platform_driver_register(&sm501_plat_driver);
++ if (ret < 0)
++ return ret;
++
+ return pci_register_driver(&sm501_pci_driver);
+ }
+
+diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
+index 6777c419a8da2..d46dba2df5a10 100644
+--- a/drivers/misc/ocxl/file.c
++++ b/drivers/misc/ocxl/file.c
+@@ -257,6 +257,8 @@ static long afu_ioctl(struct file *file, unsigned int cmd,
+ if (IS_ERR(ev_ctx))
+ return PTR_ERR(ev_ctx);
+ rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx);
++ if (rc)
++ eventfd_ctx_put(ev_ctx);
+ break;
+
+ case OCXL_IOCTL_GET_METADATA:
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index ce89611a136e9..54cd009aee50e 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -1140,8 +1140,12 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
+ {
+ struct mmc_blk_data *md = mq->blkdata;
+ struct mmc_card *card = md->queue.card;
++ unsigned int arg = card->erase_arg;
+
+- mmc_blk_issue_erase_rq(mq, req, MMC_BLK_DISCARD, card->erase_arg);
++ if (mmc_card_broken_sd_discard(card))
++ arg = SD_ERASE_ARG;
++
++ mmc_blk_issue_erase_rq(mq, req, MMC_BLK_DISCARD, arg);
+ }
+
+ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
+diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
+index 99045e138ba48..cfdd1ff40b865 100644
+--- a/drivers/mmc/core/card.h
++++ b/drivers/mmc/core/card.h
+@@ -73,6 +73,7 @@ struct mmc_fixup {
+ #define EXT_CSD_REV_ANY (-1u)
+
+ #define CID_MANFID_SANDISK 0x2
++#define CID_MANFID_SANDISK_SD 0x3
+ #define CID_MANFID_ATP 0x9
+ #define CID_MANFID_TOSHIBA 0x11
+ #define CID_MANFID_MICRON 0x13
+@@ -258,4 +259,9 @@ static inline int mmc_card_broken_hpi(const struct mmc_card *c)
+ return c->quirks & MMC_QUIRK_BROKEN_HPI;
+ }
+
++static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
++{
++ return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
++}
++
+ #endif
+diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
+index be43939880868..29b9497936df9 100644
+--- a/drivers/mmc/core/quirks.h
++++ b/drivers/mmc/core/quirks.h
+@@ -100,6 +100,12 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
+ MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_TRIM_BROKEN),
+
++ /*
++ * Some SD cards reports discard support while they don't
++ */
++ MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
++ MMC_QUIRK_BROKEN_SD_DISCARD),
++
+ END_FIXUP
+ };
+
+diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
+index a9a0837153d87..c88b039dc9fbd 100644
+--- a/drivers/mmc/host/au1xmmc.c
++++ b/drivers/mmc/host/au1xmmc.c
+@@ -1097,8 +1097,9 @@ out5:
+ if (host->platdata && host->platdata->cd_setup &&
+ !(mmc->caps & MMC_CAP_NEEDS_POLL))
+ host->platdata->cd_setup(mmc, 0);
+-out_clk:
++
+ clk_disable_unprepare(host->clk);
++out_clk:
+ clk_put(host->clk);
+ out_irq:
+ free_irq(host->irq, host);
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index 6edbf5c161ab9..b970699743e0a 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -128,6 +128,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ struct clk *ref_clk = priv->clk;
+ unsigned int freq, diff, best_freq = 0, diff_min = ~0;
+ unsigned int new_clock, clkh_shift = 0;
++ unsigned int new_upper_limit;
+ int i;
+
+ /*
+@@ -153,13 +154,20 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ * greater than, new_clock. As we can divide by 1 << i for
+ * any i in [0, 9] we want the input clock to be as close as
+ * possible, but no greater than, new_clock << i.
++ *
++ * Add an upper limit of 1/1024 rate higher to the clock rate to fix
++ * clk rate jumping to lower rate due to rounding error (eg: RZ/G2L has
++ * 3 clk sources 533.333333 MHz, 400 MHz and 266.666666 MHz. The request
++ * for 533.333333 MHz will selects a slower 400 MHz due to rounding
++ * error (533333333 Hz / 4 * 4 = 533333332 Hz < 533333333 Hz)).
+ */
+ for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
+ freq = clk_round_rate(ref_clk, new_clock << i);
+- if (freq > (new_clock << i)) {
++ new_upper_limit = (new_clock << i) + ((new_clock << i) >> 10);
++ if (freq > new_upper_limit) {
+ /* Too fast; look for a slightly slower option */
+ freq = clk_round_rate(ref_clk, (new_clock << i) / 4 * 3);
+- if (freq > (new_clock << i))
++ if (freq > new_upper_limit)
+ continue;
+ }
+
+@@ -181,6 +189,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
+ unsigned int new_clock)
+ {
++ unsigned int clk_margin;
+ u32 clk = 0, clock;
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+@@ -194,7 +203,13 @@ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
+ host->mmc->actual_clock = renesas_sdhi_clk_update(host, new_clock);
+ clock = host->mmc->actual_clock / 512;
+
+- for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
++ /*
++ * Add a margin of 1/1024 rate higher to the clock rate in order
++ * to avoid clk variable setting a value of 0 due to the margin
++ * provided for actual_clock in renesas_sdhi_clk_update().
++ */
++ clk_margin = new_clock >> 10;
++ for (clk = 0x80000080; new_clock + clk_margin >= (clock << 1); clk >>= 1)
+ clock <<= 1;
+
+ /* 1/1 clock is option */
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index dc2991422a873..3a091a387ecbc 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -2441,6 +2441,7 @@ static const struct of_device_id sdhci_msm_dt_match[] = {
+ */
+ {.compatible = "qcom,sdhci-msm-v4", .data = &sdhci_msm_mci_var},
+ {.compatible = "qcom,sdhci-msm-v5", .data = &sdhci_msm_v5_var},
++ {.compatible = "qcom,sdm670-sdhci", .data = &sdm845_sdhci_var},
+ {.compatible = "qcom,sdm845-sdhci", .data = &sdm845_sdhci_var},
+ {.compatible = "qcom,sc7180-sdhci", .data = &sdm845_sdhci_var},
+ {},
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index f33e9349e4e62..3b88c9d3ddf90 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -309,7 +309,7 @@ static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host)
+
+ static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host)
+ {
+- return 400000;
++ return 100000;
+ }
+
+ static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host,
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 2d2d8260c6814..413925bce0ca8 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -773,7 +773,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+ dev_err(dev, "failed to set clk rate to %luHz: %d\n",
+ host_clk, err);
+
+- tegra_host->curr_clk_rate = host_clk;
++ tegra_host->curr_clk_rate = clk_get_rate(pltfm_host->clk);
+ if (tegra_host->ddr_signaling)
+ host->max_clk = host_clk;
+ else
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 163ac9df8cca0..9b5c503e3a3fc 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -846,7 +846,7 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->clk_sdmmc)) {
+ dev_err(&pdev->dev, "Error getting clock\n");
+ ret = PTR_ERR(priv->clk_sdmmc);
+- goto fail5;
++ goto fail5_and_a_half;
+ }
+
+ ret = clk_prepare_enable(priv->clk_sdmmc);
+@@ -863,6 +863,9 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ return 0;
+ fail6:
+ clk_put(priv->clk_sdmmc);
++fail5_and_a_half:
++ dma_free_coherent(&pdev->dev, mmc->max_blk_count * 16,
++ priv->dma_desc_buffer, priv->dma_desc_device_addr);
+ fail5:
+ free_irq(dma_irq, priv);
+ fail4:
+diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
+index 5b0ae5ddad745..27c08f22dec8c 100644
+--- a/drivers/mtd/devices/docg3.c
++++ b/drivers/mtd/devices/docg3.c
+@@ -1974,9 +1974,14 @@ static int __init docg3_probe(struct platform_device *pdev)
+ dev_err(dev, "No I/O memory resource defined\n");
+ return ret;
+ }
+- base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE);
+
+ ret = -ENOMEM;
++ base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE);
++ if (!base) {
++ dev_err(dev, "devm_ioremap dev failed\n");
++ return ret;
++ }
++
+ cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade),
+ GFP_KERNEL);
+ if (!cascade)
+diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
+index c9ac3baf68c02..41c6bd6e2d72c 100644
+--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
++++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
+@@ -405,6 +405,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
+
+ dma_async_issue_pending(nc->dmac);
+ wait_for_completion(&finished);
++ dma_unmap_single(nc->dev, buf_dma, len, dir);
+
+ return 0;
+
+diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+index aab93b9e6052d..a18d121396aa5 100644
+--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
++++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+@@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
+ struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ unsigned int al;
+
+- switch (chip->ecc.engine_type) {
+ /*
+ * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
+ * CS Base Register
+ */
+- case NAND_ECC_ENGINE_TYPE_NONE:
++ if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) {
+ /* If CS Base Register selects full hardware ECC then use it */
+ if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
+ BR_DECC_CHK_GEN) {
+- chip->ecc.read_page = fsl_elbc_read_page;
+- chip->ecc.write_page = fsl_elbc_write_page;
+- chip->ecc.write_subpage = fsl_elbc_write_subpage;
+-
+ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
+- mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
+- chip->ecc.size = 512;
+- chip->ecc.bytes = 3;
+- chip->ecc.strength = 1;
+ } else {
+ /* otherwise fall back to default software ECC */
+ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+ chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
+ }
++ }
++
++ switch (chip->ecc.engine_type) {
++ /* if HW ECC was chosen, setup ecc and oob layout */
++ case NAND_ECC_ENGINE_TYPE_ON_HOST:
++ chip->ecc.read_page = fsl_elbc_read_page;
++ chip->ecc.write_page = fsl_elbc_write_page;
++ chip->ecc.write_subpage = fsl_elbc_write_subpage;
++ mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
++ chip->ecc.size = 512;
++ chip->ecc.bytes = 3;
++ chip->ecc.strength = 1;
+ break;
+
+- /* if SW ECC was chosen in DT, we do not need to set anything here */
++ /* if none or SW ECC was chosen, we do not need to set anything here */
++ case NAND_ECC_ENGINE_TYPE_NONE:
+ case NAND_ECC_ENGINE_TYPE_SOFT:
++ case NAND_ECC_ENGINE_TYPE_ON_DIE:
+ break;
+
+- /* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */
+ default:
+ return -EINVAL;
+ }
+diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
+index e91b879b32bdb..056835fd45622 100644
+--- a/drivers/mtd/nand/raw/intel-nand-controller.c
++++ b/drivers/mtd/nand/raw/intel-nand-controller.c
+@@ -16,6 +16,7 @@
+ #include <linux/mtd/rawnand.h>
+ #include <linux/mtd/nand.h>
+
++#include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+@@ -580,6 +581,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+ struct ebu_nand_controller *ebu_host;
++ struct device_node *chip_np;
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
+ struct resource *res;
+@@ -604,7 +606,12 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ if (IS_ERR(ebu_host->hsnand))
+ return PTR_ERR(ebu_host->hsnand);
+
+- ret = device_property_read_u32(dev, "reg", &cs);
++ chip_np = of_get_next_child(dev->of_node, NULL);
++ if (!chip_np)
++ return dev_err_probe(dev, -EINVAL,
++ "Could not find child node for the NAND chip\n");
++
++ ret = of_property_read_u32(chip_np, "reg", &cs);
+ if (ret) {
+ dev_err(dev, "failed to get chip select: %d\n", ret);
+ return ret;
+@@ -660,7 +667,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
+ ebu_host->ebu + EBU_ADDR_SEL(cs));
+
+- nand_set_flash_node(&ebu_host->chip, dev->of_node);
++ nand_set_flash_node(&ebu_host->chip, chip_np);
+
+ mtd = nand_to_mtd(&ebu_host->chip);
+ if (!mtd->name) {
+@@ -716,7 +723,6 @@ static int ebu_nand_remove(struct platform_device *pdev)
+ }
+
+ static const struct of_device_id ebu_nand_match[] = {
+- { .compatible = "intel,nand-controller" },
+ { .compatible = "intel,lgm-ebunand" },
+ {}
+ };
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index 829b76b303aae..ad2ffd0ca8006 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -454,7 +454,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips,
+ if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) {
+ mtd->ecc_stats.corrected += ECC_ERR_CNT(*info);
+ *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info));
+- *correct_bitmap |= 1 >> i;
++ *correct_bitmap |= BIT_ULL(i);
+ continue;
+ }
+ if ((nand->options & NAND_NEED_SCRAMBLING) &&
+@@ -800,7 +800,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf,
+ u8 *data = buf + i * ecc->size;
+ u8 *oob = nand->oob_poi + i * (ecc->bytes + 2);
+
+- if (correct_bitmap & (1 << i))
++ if (correct_bitmap & BIT_ULL(i))
+ continue;
+ ret = nand_check_erased_ecc_chunk(data, ecc->size,
+ oob, ecc->bytes + 2,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index 841da29cef939..f6c0938027ece 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -178,6 +178,8 @@ struct kvaser_usb_dev_cfg {
+ extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops;
+ extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
+
++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv);
++
+ int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,
+ int *actual_len);
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 824cab80aa02f..e91648ed73862 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -477,7 +477,7 @@ static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv)
+ /* This method might sleep. Do not call it in the atomic context
+ * of URB completions.
+ */
+-static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
+ {
+ usb_kill_anchored_urbs(&priv->tx_submitted);
+ kvaser_usb_reset_tx_urb_contexts(priv);
+@@ -729,6 +729,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ init_usb_anchor(&priv->tx_submitted);
+ init_completion(&priv->start_comp);
+ init_completion(&priv->stop_comp);
++ init_completion(&priv->flush_comp);
+ priv->can.ctrlmode_supported = 0;
+
+ priv->dev = dev;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index dd65c101bfb8e..3dcd35979e6fd 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -1916,7 +1916,7 @@ static int kvaser_usb_hydra_flush_queue(struct kvaser_usb_net_priv *priv)
+ {
+ int err;
+
+- init_completion(&priv->flush_comp);
++ reinit_completion(&priv->flush_comp);
+
+ err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE,
+ priv->channel);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 07f687f29b341..50f2ac8319ff8 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -310,6 +310,38 @@ struct kvaser_cmd {
+ } u;
+ } __packed;
+
++#define CMD_SIZE_ANY 0xff
++#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field)
++
++static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple),
++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple),
++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo),
++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header),
++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo),
++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can),
++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can),
++ [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message),
++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event),
++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event),
++ /* ignored events: */
++ [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY,
++};
++
++static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple),
++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple),
++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo),
++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header),
++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo),
++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can),
++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can),
++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event),
++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event),
++ /* ignored events: */
++ [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
++};
++
+ /* Summary of a kvaser error event, for a unified Leaf/Usbcan error
+ * handling. Some discrepancies between the two families exist:
+ *
+@@ -397,6 +429,43 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = {
+ .bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+
++static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev,
++ const struct kvaser_cmd *cmd)
++{
++ /* buffer size >= cmd->len ensured by caller */
++ u8 min_size = 0;
++
++ switch (dev->driver_info->family) {
++ case KVASER_LEAF:
++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf))
++ min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id];
++ break;
++ case KVASER_USBCAN:
++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan))
++ min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id];
++ break;
++ }
++
++ if (min_size == CMD_SIZE_ANY)
++ return 0;
++
++ if (min_size) {
++ min_size += CMD_HEADER_LEN;
++ if (cmd->len >= min_size)
++ return 0;
++
++ dev_err_ratelimited(&dev->intf->dev,
++ "Received command %u too short (size %u, needed %u)",
++ cmd->id, cmd->len, min_size);
++ return -EIO;
++ }
++
++ dev_warn_ratelimited(&dev->intf->dev,
++ "Unhandled command (%d, size %d)\n",
++ cmd->id, cmd->len);
++ return -EINVAL;
++}
++
+ static void *
+ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ const struct sk_buff *skb, int *cmd_len,
+@@ -502,6 +571,9 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+ end:
+ kfree(buf);
+
++ if (err == 0)
++ err = kvaser_usb_leaf_verify_size(dev, cmd);
++
+ return err;
+ }
+
+@@ -1133,6 +1205,9 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev,
+ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ const struct kvaser_cmd *cmd)
+ {
++ if (kvaser_usb_leaf_verify_size(dev, cmd) < 0)
++ return;
++
+ switch (cmd->id) {
+ case CMD_START_CHIP_REPLY:
+ kvaser_usb_leaf_start_chip_reply(dev, cmd);
+@@ -1351,9 +1426,13 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev,
+
+ switch (mode) {
+ case CAN_MODE_START:
++ kvaser_usb_unlink_tx_urbs(priv);
++
+ err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP);
+ if (err)
+ return err;
++
++ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ break;
+ default:
+ return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
+index a89b93cb4e26d..d5939586c82ee 100644
+--- a/drivers/net/ethernet/atheros/alx/main.c
++++ b/drivers/net/ethernet/atheros/alx/main.c
+@@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev)
+
+ if (!netif_running(alx->dev))
+ return 0;
++
++ rtnl_lock();
+ netif_device_detach(alx->dev);
+
+ mutex_lock(&alx->mtx);
+ __alx_stop(alx);
+ mutex_unlock(&alx->mtx);
++ rtnl_unlock();
+
+ return 0;
+ }
+@@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev)
+ struct alx_hw *hw = &alx->hw;
+ int err;
+
++ rtnl_lock();
+ mutex_lock(&alx->mtx);
+ alx_reset_phy(hw);
+
+@@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev)
+
+ unlock:
+ mutex_unlock(&alx->mtx);
++ rtnl_unlock();
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+index 712b5595bc393..24bfc65e28e10 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -789,6 +789,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ BNX2X_ERR("skb_put is about to fail... pad %d len %d rx_buf_size %d\n",
+ pad, len, fp->rx_buf_size);
+ bnx2x_panic();
++ bnx2x_frag_free(fp, new_data);
+ return;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+index 8e316367f6ced..2132ce63193ce 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+@@ -505,9 +505,13 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
+ ptp->tstamp_filters = flags;
+
+ if (netif_running(bp->dev)) {
+- rc = bnxt_close_nic(bp, false, false);
+- if (!rc)
+- rc = bnxt_open_nic(bp, false, false);
++ if (ptp->rx_filter == HWTSTAMP_FILTER_ALL) {
++ rc = bnxt_close_nic(bp, false, false);
++ if (!rc)
++ rc = bnxt_open_nic(bp, false, false);
++ } else {
++ bnxt_ptp_cfg_tstamp_filters(bp);
++ }
+ if (!rc && !ptp->tstamp_filters)
+ rc = -EIO;
+ }
+diff --git a/drivers/net/ethernet/engleder/tsnep_hw.h b/drivers/net/ethernet/engleder/tsnep_hw.h
+index 916ceac3ada23..e03aaafab559f 100644
+--- a/drivers/net/ethernet/engleder/tsnep_hw.h
++++ b/drivers/net/ethernet/engleder/tsnep_hw.h
+@@ -92,8 +92,7 @@
+
+ /* tsnep register */
+ #define TSNEP_INFO 0x0100
+-#define TSNEP_INFO_RX_ASSIGN 0x00010000
+-#define TSNEP_INFO_TX_TIME 0x00020000
++#define TSNEP_INFO_TX_TIME 0x00010000
+ #define TSNEP_CONTROL 0x0108
+ #define TSNEP_CONTROL_TX_RESET 0x00000001
+ #define TSNEP_CONTROL_TX_ENABLE 0x00000002
+diff --git a/drivers/net/ethernet/faraday/ftmac100.h b/drivers/net/ethernet/faraday/ftmac100.h
+index fe986f1673fc6..8af32f9070f4c 100644
+--- a/drivers/net/ethernet/faraday/ftmac100.h
++++ b/drivers/net/ethernet/faraday/ftmac100.h
+@@ -122,9 +122,9 @@
+ * Transmit descriptor, aligned to 16 bytes
+ */
+ struct ftmac100_txdes {
+- unsigned int txdes0;
+- unsigned int txdes1;
+- unsigned int txdes2; /* TXBUF_BADR */
++ __le32 txdes0;
++ __le32 txdes1;
++ __le32 txdes2; /* TXBUF_BADR */
+ unsigned int txdes3; /* not used by HW */
+ } __attribute__ ((aligned(16)));
+
+@@ -143,9 +143,9 @@ struct ftmac100_txdes {
+ * Receive descriptor, aligned to 16 bytes
+ */
+ struct ftmac100_rxdes {
+- unsigned int rxdes0;
+- unsigned int rxdes1;
+- unsigned int rxdes2; /* RXBUF_BADR */
++ __le32 rxdes0;
++ __le32 rxdes1;
++ __le32 rxdes2; /* RXBUF_BADR */
+ unsigned int rxdes3; /* not used by HW */
+ } __attribute__ ((aligned(16)));
+
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+index 99fe2c210d0f6..61f4b6e50d29b 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
+ return -EINVAL;
+
+ fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0);
+- if (!fep->fcc.fccp)
++ if (!fep->fec.fecp)
+ return -EINVAL;
+
+ return 0;
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 0c89f16bf1e23..79fef8c59d652 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1267,66 +1267,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
+ }
+
+ /**
+- * iavf_down - Shutdown the connection processing
++ * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
++ * yet and mark other to be removed.
+ * @adapter: board private structure
+- *
+- * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
+ **/
+-void iavf_down(struct iavf_adapter *adapter)
++static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
+ {
+- struct net_device *netdev = adapter->netdev;
+- struct iavf_vlan_filter *vlf;
+- struct iavf_cloud_filter *cf;
+- struct iavf_fdir_fltr *fdir;
+- struct iavf_mac_filter *f;
+- struct iavf_adv_rss *rss;
+-
+- if (adapter->state <= __IAVF_DOWN_PENDING)
+- return;
+-
+- netif_carrier_off(netdev);
+- netif_tx_disable(netdev);
+- adapter->link_up = false;
+- iavf_napi_disable_all(adapter);
+- iavf_irq_disable(adapter);
++ struct iavf_vlan_filter *vlf, *vlftmp;
++ struct iavf_mac_filter *f, *ftmp;
+
+ spin_lock_bh(&adapter->mac_vlan_list_lock);
+-
+ /* clear the sync flag on all filters */
+ __dev_uc_unsync(adapter->netdev, NULL);
+ __dev_mc_unsync(adapter->netdev, NULL);
+
+ /* remove all MAC filters */
+- list_for_each_entry(f, &adapter->mac_filter_list, list) {
+- f->remove = true;
++ list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list,
++ list) {
++ if (f->add) {
++ list_del(&f->list);
++ kfree(f);
++ } else {
++ f->remove = true;
++ }
+ }
+
+ /* remove all VLAN filters */
+- list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
+- vlf->remove = true;
++ list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
++ list) {
++ if (vlf->add) {
++ list_del(&vlf->list);
++ kfree(vlf);
++ } else {
++ vlf->remove = true;
++ }
+ }
+-
+ spin_unlock_bh(&adapter->mac_vlan_list_lock);
++}
++
++/**
++ * iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and
++ * mark other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_cloud_filters(struct iavf_adapter *adapter)
++{
++ struct iavf_cloud_filter *cf, *cftmp;
+
+ /* remove all cloud filters */
+ spin_lock_bh(&adapter->cloud_filter_list_lock);
+- list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
+- cf->del = true;
++ list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
++ list) {
++ if (cf->add) {
++ list_del(&cf->list);
++ kfree(cf);
++ adapter->num_cloud_filters--;
++ } else {
++ cf->del = true;
++ }
+ }
+ spin_unlock_bh(&adapter->cloud_filter_list_lock);
++}
++
++/**
++ * iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark
++ * other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_fdir_filters(struct iavf_adapter *adapter)
++{
++ struct iavf_fdir_fltr *fdir, *fdirtmp;
+
+ /* remove all Flow Director filters */
+ spin_lock_bh(&adapter->fdir_fltr_lock);
+- list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
+- fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
++ list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head,
++ list) {
++ if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
++ list_del(&fdir->list);
++ kfree(fdir);
++ adapter->fdir_active_fltr--;
++ } else {
++ fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
++ }
+ }
+ spin_unlock_bh(&adapter->fdir_fltr_lock);
++}
++
++/**
++ * iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark
++ * other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter)
++{
++ struct iavf_adv_rss *rss, *rsstmp;
+
+ /* remove all advance RSS configuration */
+ spin_lock_bh(&adapter->adv_rss_lock);
+- list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
+- rss->state = IAVF_ADV_RSS_DEL_REQUEST;
++ list_for_each_entry_safe(rss, rsstmp, &adapter->adv_rss_list_head,
++ list) {
++ if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
++ list_del(&rss->list);
++ kfree(rss);
++ } else {
++ rss->state = IAVF_ADV_RSS_DEL_REQUEST;
++ }
++ }
+ spin_unlock_bh(&adapter->adv_rss_lock);
++}
++
++/**
++ * iavf_down - Shutdown the connection processing
++ * @adapter: board private structure
++ *
++ * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
++ **/
++void iavf_down(struct iavf_adapter *adapter)
++{
++ struct net_device *netdev = adapter->netdev;
++
++ if (adapter->state <= __IAVF_DOWN_PENDING)
++ return;
++
++ netif_carrier_off(netdev);
++ netif_tx_disable(netdev);
++ adapter->link_up = false;
++ iavf_napi_disable_all(adapter);
++ iavf_irq_disable(adapter);
++
++ iavf_clear_mac_vlan_filters(adapter);
++ iavf_clear_cloud_filters(adapter);
++ iavf_clear_fdir_filters(adapter);
++ iavf_clear_adv_rss_conf(adapter);
+
+ if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
+ /* cancel any current operation */
+@@ -1335,11 +1407,16 @@ void iavf_down(struct iavf_adapter *adapter)
+ * here for this to complete. The watchdog is still running
+ * and it will take care of this.
+ */
+- adapter->aq_required = IAVF_FLAG_AQ_DEL_MAC_FILTER;
+- adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
+- adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
+- adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
+- adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
++ if (!list_empty(&adapter->mac_filter_list))
++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
++ if (!list_empty(&adapter->vlan_filter_list))
++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
++ if (!list_empty(&adapter->cloud_filter_list))
++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
++ if (!list_empty(&adapter->fdir_list_head))
++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
++ if (!list_empty(&adapter->adv_rss_list_head))
++ adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
+ adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
+ }
+
+@@ -4178,6 +4255,7 @@ err_unlock:
+ static int iavf_close(struct net_device *netdev)
+ {
+ struct iavf_adapter *adapter = netdev_priv(netdev);
++ u64 aq_to_restore;
+ int status;
+
+ mutex_lock(&adapter->crit_lock);
+@@ -4190,6 +4268,29 @@ static int iavf_close(struct net_device *netdev)
+ set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+ if (CLIENT_ENABLED(adapter))
+ adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_CLOSE;
++ /* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before
++ * IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl
++ * deadlock with adminq_task() until iavf_close timeouts. We must send
++ * IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make
++ * disable queues possible for vf. Give only necessary flags to
++ * iavf_down and save other to set them right before iavf_close()
++ * returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and
++ * iavf will be in DOWN state.
++ */
++ aq_to_restore = adapter->aq_required;
++ adapter->aq_required &= IAVF_FLAG_AQ_GET_CONFIG;
++
++ /* Remove flags which we do not want to send after close or we want to
++ * send before disable queues.
++ */
++ aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG |
++ IAVF_FLAG_AQ_ENABLE_QUEUES |
++ IAVF_FLAG_AQ_CONFIGURE_QUEUES |
++ IAVF_FLAG_AQ_ADD_VLAN_FILTER |
++ IAVF_FLAG_AQ_ADD_MAC_FILTER |
++ IAVF_FLAG_AQ_ADD_CLOUD_FILTER |
++ IAVF_FLAG_AQ_ADD_FDIR_FILTER |
++ IAVF_FLAG_AQ_ADD_ADV_RSS_CFG);
+
+ iavf_down(adapter);
+ iavf_change_state(adapter, __IAVF_DOWN_PENDING);
+@@ -4213,6 +4314,10 @@ static int iavf_close(struct net_device *netdev)
+ msecs_to_jiffies(500));
+ if (!status)
+ netdev_warn(netdev, "Device resources not yet released\n");
++
++ mutex_lock(&adapter->crit_lock);
++ adapter->aq_required |= aq_to_restore;
++ mutex_unlock(&adapter->crit_lock);
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+index a6fff8ebaf9d9..bbf6a300078e5 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+@@ -2826,6 +2826,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
+ tx_rings[i].count = new_tx_cnt;
+ tx_rings[i].desc = NULL;
+ tx_rings[i].tx_buf = NULL;
++ tx_rings[i].tx_tstamps = &pf->ptp.port.tx;
+ err = ice_setup_tx_ring(&tx_rings[i]);
+ if (err) {
+ while (i--)
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+index ad73a488fc5fb..11e603686a276 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+@@ -1530,6 +1530,7 @@ u32 mvpp2_read(struct mvpp2 *priv, u32 offset);
+ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name);
+
+ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv);
++void mvpp2_dbgfs_exit(void);
+
+ void mvpp23_rx_fifo_fc_en(struct mvpp2 *priv, int port, bool en);
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
+index 4a3baa7e01424..75e83ea2a926e 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
+@@ -691,6 +691,13 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent,
+ return 0;
+ }
+
++static struct dentry *mvpp2_root;
++
++void mvpp2_dbgfs_exit(void)
++{
++ debugfs_remove(mvpp2_root);
++}
++
+ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
+ {
+ debugfs_remove_recursive(priv->dbgfs_dir);
+@@ -700,10 +707,9 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
+
+ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
+ {
+- struct dentry *mvpp2_dir, *mvpp2_root;
++ struct dentry *mvpp2_dir;
+ int ret, i;
+
+- mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL);
+ if (!mvpp2_root)
+ mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index b84128b549b44..eaa51cd7456b6 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7706,7 +7706,18 @@ static struct platform_driver mvpp2_driver = {
+ },
+ };
+
+-module_platform_driver(mvpp2_driver);
++static int __init mvpp2_driver_init(void)
++{
++ return platform_driver_register(&mvpp2_driver);
++}
++module_init(mvpp2_driver_init);
++
++static void __exit mvpp2_driver_exit(void)
++{
++ platform_driver_unregister(&mvpp2_driver);
++ mvpp2_dbgfs_exit();
++}
++module_exit(mvpp2_driver_exit);
+
+ MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com");
+ MODULE_AUTHOR("Marcin Wojtas <mw@semihalf.com>");
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.c b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
+index 3d4b85f2d5414..f6b2933859d00 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
+@@ -178,10 +178,14 @@ err_rhashtable_init:
+ return ERR_PTR(err);
+ }
+
+-void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
+- void *keymask)
++int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
++ void *keymask)
+ {
+ ruleset->keymask = kmemdup(keymask, ACL_KEYMASK_SIZE, GFP_KERNEL);
++ if (!ruleset->keymask)
++ return -ENOMEM;
++
++ return 0;
+ }
+
+ int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset)
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.h b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
+index 03fc5b9dc9258..131bfbc87cd75 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.h
++++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
+@@ -185,8 +185,8 @@ struct prestera_acl_ruleset *
+ prestera_acl_ruleset_lookup(struct prestera_acl *acl,
+ struct prestera_flow_block *block,
+ u32 chain_index);
+-void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
+- void *keymask);
++int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
++ void *keymask);
+ bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
+ int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
+ void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+index 19d3b55c578ee..cf551a8379aca 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+@@ -452,7 +452,9 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,
+ }
+
+ /* preserve keymask/template to this ruleset */
+- prestera_acl_ruleset_keymask_set(ruleset, rule.re_key.match.mask);
++ err = prestera_acl_ruleset_keymask_set(ruleset, rule.re_key.match.mask);
++ if (err)
++ goto err_ruleset_keymask_set;
+
+ /* skip error, as it is not possible to reject template operation,
+ * so, keep the reference to the ruleset for rules to be added
+@@ -468,6 +470,8 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,
+ list_add_rcu(&template->list, &block->template_list);
+ return 0;
+
++err_ruleset_keymask_set:
++ prestera_acl_ruleset_put(ruleset);
+ err_ruleset_get:
+ kfree(template);
+ err_malloc:
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+index a895862b48212..a0ad0bcbf89f4 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -799,32 +799,30 @@ static void prestera_port_handle_event(struct prestera_switch *sw,
+
+ caching_dw = &port->cached_hw_stats.caching_dw;
+
+- if (port->phy_link) {
+- memset(&smac, 0, sizeof(smac));
+- smac.valid = true;
+- smac.oper = pevt->data.mac.oper;
+- if (smac.oper) {
+- smac.mode = pevt->data.mac.mode;
+- smac.speed = pevt->data.mac.speed;
+- smac.duplex = pevt->data.mac.duplex;
+- smac.fc = pevt->data.mac.fc;
+- smac.fec = pevt->data.mac.fec;
+- phylink_mac_change(port->phy_link, true);
+- } else {
+- phylink_mac_change(port->phy_link, false);
+- }
+- prestera_port_mac_state_cache_write(port, &smac);
++ memset(&smac, 0, sizeof(smac));
++ smac.valid = true;
++ smac.oper = pevt->data.mac.oper;
++ if (smac.oper) {
++ smac.mode = pevt->data.mac.mode;
++ smac.speed = pevt->data.mac.speed;
++ smac.duplex = pevt->data.mac.duplex;
++ smac.fc = pevt->data.mac.fc;
++ smac.fec = pevt->data.mac.fec;
+ }
++ prestera_port_mac_state_cache_write(port, &smac);
+
+ if (port->state_mac.oper) {
+- if (!port->phy_link)
++ if (port->phy_link)
++ phylink_mac_change(port->phy_link, true);
++ else
+ netif_carrier_on(port->dev);
+
+ if (!delayed_work_pending(caching_dw))
+ queue_delayed_work(prestera_wq, caching_dw, 0);
+- } else if (netif_running(port->dev) &&
+- netif_carrier_ok(port->dev)) {
+- if (!port->phy_link)
++ } else {
++ if (port->phy_link)
++ phylink_mac_change(port->phy_link, false);
++ else if (netif_running(port->dev) && netif_carrier_ok(port->dev))
+ netif_carrier_off(port->dev);
+
+ if (delayed_work_pending(caching_dw))
+diff --git a/drivers/net/ethernet/micrel/ks8851_spi.c b/drivers/net/ethernet/micrel/ks8851_spi.c
+index 82d55fc27edc6..70bc7253454f6 100644
+--- a/drivers/net/ethernet/micrel/ks8851_spi.c
++++ b/drivers/net/ethernet/micrel/ks8851_spi.c
+@@ -413,7 +413,8 @@ static int ks8851_probe_spi(struct spi_device *spi)
+
+ spi->bits_per_word = 8;
+
+- ks = netdev_priv(netdev);
++ kss = netdev_priv(netdev);
++ ks = &kss->ks8851;
+
+ ks->lock = ks8851_lock_spi;
+ ks->unlock = ks8851_unlock_spi;
+@@ -433,8 +434,6 @@ static int ks8851_probe_spi(struct spi_device *spi)
+ IRQ_RXPSI) /* RX process stop */
+ ks->rc_ier = STD_IRQ;
+
+- kss = to_ks8851_spi(ks);
+-
+ kss->spidev = spi;
+ mutex_init(&kss->lock);
+ INIT_WORK(&kss->tx_work, ks8851_tx_work);
+diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
+index 6a11e2ceb013b..da3ea905adbb8 100644
+--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
+@@ -1049,6 +1049,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
+ enum ptp_pin_function func,
+ unsigned int chan)
+ {
++ struct lan743x_ptp *lan_ptp =
++ container_of(ptp, struct lan743x_ptp, ptp_clock_info);
++ struct lan743x_adapter *adapter =
++ container_of(lan_ptp, struct lan743x_adapter, ptp);
+ int result = 0;
+
+ /* Confirm the requested function is supported. Parameter
+@@ -1057,7 +1061,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
+ switch (func) {
+ case PTP_PF_NONE:
+ case PTP_PF_PEROUT:
++ break;
+ case PTP_PF_EXTTS:
++ if (!adapter->is_pci11x1x)
++ result = -1;
+ break;
+ case PTP_PF_PHYSYNC:
+ default:
+diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+index 546206640492b..61d1d07dc0704 100644
+--- a/drivers/net/ethernet/sunplus/spl2sw_driver.c
++++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+@@ -248,8 +248,8 @@ static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node *
+
+ /* Check if mac address is valid */
+ if (!is_valid_ether_addr(mac)) {
+- kfree(mac);
+ dev_info(dev, "Invalid mac address in nvmem (%pM)!\n", mac);
++ kfree(mac);
+ return -EINVAL;
+ }
+
+diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
+index fb30bc5d56cb7..fce06663e1e11 100644
+--- a/drivers/net/ethernet/ti/Kconfig
++++ b/drivers/net/ethernet/ti/Kconfig
+@@ -33,6 +33,7 @@ config TI_DAVINCI_MDIO
+ tristate "TI DaVinci MDIO Support"
+ depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
+ select PHYLIB
++ select MDIO_BITBANG
+ help
+ This driver supports TI's DaVinci MDIO module.
+
+diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
+index ea37726180431..946b9753ccfb3 100644
+--- a/drivers/net/ethernet/ti/davinci_mdio.c
++++ b/drivers/net/ethernet/ti/davinci_mdio.c
+@@ -26,6 +26,8 @@
+ #include <linux/of_device.h>
+ #include <linux/of_mdio.h>
+ #include <linux/pinctrl/consumer.h>
++#include <linux/mdio-bitbang.h>
++#include <linux/sys_soc.h>
+
+ /*
+ * This timeout definition is a worst-case ultra defensive measure against
+@@ -41,6 +43,7 @@
+
+ struct davinci_mdio_of_param {
+ int autosuspend_delay_ms;
++ bool manual_mode;
+ };
+
+ struct davinci_mdio_regs {
+@@ -49,6 +52,15 @@ struct davinci_mdio_regs {
+ #define CONTROL_IDLE BIT(31)
+ #define CONTROL_ENABLE BIT(30)
+ #define CONTROL_MAX_DIV (0xffff)
++#define CONTROL_CLKDIV GENMASK(15, 0)
++
++#define MDIO_MAN_MDCLK_O BIT(2)
++#define MDIO_MAN_OE BIT(1)
++#define MDIO_MAN_PIN BIT(0)
++#define MDIO_MANUALMODE BIT(31)
++
++#define MDIO_PIN 0
++
+
+ u32 alive;
+ u32 link;
+@@ -59,7 +71,9 @@ struct davinci_mdio_regs {
+ u32 userintmasked;
+ u32 userintmaskset;
+ u32 userintmaskclr;
+- u32 __reserved_1[20];
++ u32 manualif;
++ u32 poll;
++ u32 __reserved_1[18];
+
+ struct {
+ u32 access;
+@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {
+
+ struct davinci_mdio_data {
+ struct mdio_platform_data pdata;
++ struct mdiobb_ctrl bb_ctrl;
+ struct davinci_mdio_regs __iomem *regs;
+ struct clk *clk;
+ struct device *dev;
+@@ -90,6 +105,7 @@ struct davinci_mdio_data {
+ */
+ bool skip_scan;
+ u32 clk_div;
++ bool manual_mode;
+ };
+
+ static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
+@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)
+ writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
+ }
+
+-static int davinci_mdio_reset(struct mii_bus *bus)
++static void davinci_mdio_disable(struct davinci_mdio_data *data)
++{
++ u32 reg;
++
++ /* Disable MDIO state machine */
++ reg = readl(&data->regs->control);
++
++ reg &= ~CONTROL_CLKDIV;
++ reg |= data->clk_div;
++
++ reg &= ~CONTROL_ENABLE;
++ writel(reg, &data->regs->control);
++}
++
++static void davinci_mdio_enable_manual_mode(struct davinci_mdio_data *data)
++{
++ u32 reg;
++ /* set manual mode */
++ reg = readl(&data->regs->poll);
++ reg |= MDIO_MANUALMODE;
++ writel(reg, &data->regs->poll);
++}
++
++static void davinci_set_mdc(struct mdiobb_ctrl *ctrl, int level)
++{
++ struct davinci_mdio_data *data;
++ u32 reg;
++
++ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++ reg = readl(&data->regs->manualif);
++
++ if (level)
++ reg |= MDIO_MAN_MDCLK_O;
++ else
++ reg &= ~MDIO_MAN_MDCLK_O;
++
++ writel(reg, &data->regs->manualif);
++}
++
++static void davinci_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output)
++{
++ struct davinci_mdio_data *data;
++ u32 reg;
++
++ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++ reg = readl(&data->regs->manualif);
++
++ if (output)
++ reg |= MDIO_MAN_OE;
++ else
++ reg &= ~MDIO_MAN_OE;
++
++ writel(reg, &data->regs->manualif);
++}
++
++static void davinci_set_mdio_data(struct mdiobb_ctrl *ctrl, int value)
++{
++ struct davinci_mdio_data *data;
++ u32 reg;
++
++ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++ reg = readl(&data->regs->manualif);
++
++ if (value)
++ reg |= MDIO_MAN_PIN;
++ else
++ reg &= ~MDIO_MAN_PIN;
++
++ writel(reg, &data->regs->manualif);
++}
++
++static int davinci_get_mdio_data(struct mdiobb_ctrl *ctrl)
++{
++ struct davinci_mdio_data *data;
++ unsigned long reg;
++
++ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++ reg = readl(&data->regs->manualif);
++ return test_bit(MDIO_PIN, ®);
++}
++
++static int davinci_mdiobb_read(struct mii_bus *bus, int phy, int reg)
++{
++ int ret;
++
++ ret = pm_runtime_resume_and_get(bus->parent);
++ if (ret < 0)
++ return ret;
++
++ ret = mdiobb_read(bus, phy, reg);
++
++ pm_runtime_mark_last_busy(bus->parent);
++ pm_runtime_put_autosuspend(bus->parent);
++
++ return ret;
++}
++
++static int davinci_mdiobb_write(struct mii_bus *bus, int phy, int reg,
++ u16 val)
++{
++ int ret;
++
++ ret = pm_runtime_resume_and_get(bus->parent);
++ if (ret < 0)
++ return ret;
++
++ ret = mdiobb_write(bus, phy, reg, val);
++
++ pm_runtime_mark_last_busy(bus->parent);
++ pm_runtime_put_autosuspend(bus->parent);
++
++ return ret;
++}
++
++static int davinci_mdio_common_reset(struct davinci_mdio_data *data)
+ {
+- struct davinci_mdio_data *data = bus->priv;
+ u32 phy_mask, ver;
+ int ret;
+
+@@ -138,6 +267,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)
+ if (ret < 0)
+ return ret;
+
++ if (data->manual_mode) {
++ davinci_mdio_disable(data);
++ davinci_mdio_enable_manual_mode(data);
++ }
++
+ /* wait for scan logic to settle */
+ msleep(PHY_MAX_ADDR * data->access_time);
+
+@@ -171,6 +305,23 @@ done:
+ return 0;
+ }
+
++static int davinci_mdio_reset(struct mii_bus *bus)
++{
++ struct davinci_mdio_data *data = bus->priv;
++
++ return davinci_mdio_common_reset(data);
++}
++
++static int davinci_mdiobb_reset(struct mii_bus *bus)
++{
++ struct mdiobb_ctrl *ctrl = bus->priv;
++ struct davinci_mdio_data *data;
++
++ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++
++ return davinci_mdio_common_reset(data);
++}
++
+ /* wait until hardware is ready for another user access */
+ static inline int wait_for_user_access(struct davinci_mdio_data *data)
+ {
+@@ -318,6 +469,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,
+ return 0;
+ }
+
++struct k3_mdio_soc_data {
++ bool manual_mode;
++};
++
++static const struct k3_mdio_soc_data am65_mdio_soc_data = {
++ .manual_mode = true,
++};
++
++static const struct soc_device_attribute k3_mdio_socinfo[] = {
++ { .family = "AM62X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++ { .family = "AM64X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++ { .family = "AM64X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++ { .family = "AM65X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++ { .family = "AM65X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++ { .family = "J7200", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++ { .family = "J7200", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++ { .family = "J721E", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++ { .family = "J721E", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++ { .family = "J721S2", .revision = "SR1.0", .data = &am65_mdio_soc_data},
++ { /* sentinel */ },
++};
++
+ #if IS_ENABLED(CONFIG_OF)
+ static const struct davinci_mdio_of_param of_cpsw_mdio_data = {
+ .autosuspend_delay_ms = 100,
+@@ -331,6 +504,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {
+ MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
+ #endif
+
++static const struct mdiobb_ops davinci_mdiobb_ops = {
++ .owner = THIS_MODULE,
++ .set_mdc = davinci_set_mdc,
++ .set_mdio_dir = davinci_set_mdio_dir,
++ .set_mdio_data = davinci_set_mdio_data,
++ .get_mdio_data = davinci_get_mdio_data,
++};
++
+ static int davinci_mdio_probe(struct platform_device *pdev)
+ {
+ struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+@@ -345,7 +526,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)
+ if (!data)
+ return -ENOMEM;
+
+- data->bus = devm_mdiobus_alloc(dev);
++ data->manual_mode = false;
++ data->bb_ctrl.ops = &davinci_mdiobb_ops;
++
++ if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
++ const struct soc_device_attribute *soc_match_data;
++
++ soc_match_data = soc_device_match(k3_mdio_socinfo);
++ if (soc_match_data && soc_match_data->data) {
++ const struct k3_mdio_soc_data *socdata =
++ soc_match_data->data;
++
++ data->manual_mode = socdata->manual_mode;
++ }
++ }
++
++ if (data->manual_mode)
++ data->bus = alloc_mdio_bitbang(&data->bb_ctrl);
++ else
++ data->bus = devm_mdiobus_alloc(dev);
++
+ if (!data->bus) {
+ dev_err(dev, "failed to alloc mii bus\n");
+ return -ENOMEM;
+@@ -371,11 +571,20 @@ static int davinci_mdio_probe(struct platform_device *pdev)
+ }
+
+ data->bus->name = dev_name(dev);
+- data->bus->read = davinci_mdio_read;
+- data->bus->write = davinci_mdio_write;
+- data->bus->reset = davinci_mdio_reset;
++
++ if (data->manual_mode) {
++ data->bus->read = davinci_mdiobb_read;
++ data->bus->write = davinci_mdiobb_write;
++ data->bus->reset = davinci_mdiobb_reset;
++
++ dev_info(dev, "Configuring MDIO in manual mode\n");
++ } else {
++ data->bus->read = davinci_mdio_read;
++ data->bus->write = davinci_mdio_write;
++ data->bus->reset = davinci_mdio_reset;
++ data->bus->priv = data;
++ }
+ data->bus->parent = dev;
+- data->bus->priv = data;
+
+ data->clk = devm_clk_get(dev, "fck");
+ if (IS_ERR(data->clk)) {
+@@ -433,9 +642,13 @@ static int davinci_mdio_remove(struct platform_device *pdev)
+ {
+ struct davinci_mdio_data *data = platform_get_drvdata(pdev);
+
+- if (data->bus)
++ if (data->bus) {
+ mdiobus_unregister(data->bus);
+
++ if (data->manual_mode)
++ free_mdio_bitbang(data->bus);
++ }
++
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+@@ -452,7 +665,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev)
+ ctrl = readl(&data->regs->control);
+ ctrl &= ~CONTROL_ENABLE;
+ writel(ctrl, &data->regs->control);
+- wait_for_idle(data);
++
++ if (!data->manual_mode)
++ wait_for_idle(data);
+
+ return 0;
+ }
+@@ -461,7 +676,12 @@ static int davinci_mdio_runtime_resume(struct device *dev)
+ {
+ struct davinci_mdio_data *data = dev_get_drvdata(dev);
+
+- davinci_mdio_enable(data);
++ if (data->manual_mode) {
++ davinci_mdio_disable(data);
++ davinci_mdio_enable_manual_mode(data);
++ } else {
++ davinci_mdio_enable(data);
++ }
+ return 0;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index f2e2261b4b7d9..8ff4333de2ad9 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -402,6 +402,9 @@ struct axidma_bd {
+ * @rx_bd_num: Size of RX buffer descriptor ring
+ * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being
+ * accessed currently.
++ * @rx_packets: RX packet count for statistics
++ * @rx_bytes: RX byte count for statistics
++ * @rx_stat_sync: Synchronization object for RX stats
+ * @napi_tx: NAPI TX control structure
+ * @tx_dma_cr: Nominal content of TX DMA control register
+ * @tx_bd_v: Virtual address of the TX buffer descriptor ring
+@@ -411,6 +414,9 @@ struct axidma_bd {
+ * complete. Only updated at runtime by TX NAPI poll.
+ * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring
+ * to be populated.
++ * @tx_packets: TX packet count for statistics
++ * @tx_bytes: TX byte count for statistics
++ * @tx_stat_sync: Synchronization object for TX stats
+ * @dma_err_task: Work structure to process Axi DMA errors
+ * @tx_irq: Axidma TX IRQ number
+ * @rx_irq: Axidma RX IRQ number
+@@ -458,6 +464,9 @@ struct axienet_local {
+ dma_addr_t rx_bd_p;
+ u32 rx_bd_num;
+ u32 rx_bd_ci;
++ u64_stats_t rx_packets;
++ u64_stats_t rx_bytes;
++ struct u64_stats_sync rx_stat_sync;
+
+ struct napi_struct napi_tx;
+ u32 tx_dma_cr;
+@@ -466,6 +475,9 @@ struct axienet_local {
+ u32 tx_bd_num;
+ u32 tx_bd_ci;
+ u32 tx_bd_tail;
++ u64_stats_t tx_packets;
++ u64_stats_t tx_bytes;
++ struct u64_stats_sync tx_stat_sync;
+
+ struct work_struct dma_err_task;
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 1760930ec0c49..9262988d26a32 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -752,8 +752,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)
+ if (lp->tx_bd_ci >= lp->tx_bd_num)
+ lp->tx_bd_ci %= lp->tx_bd_num;
+
+- ndev->stats.tx_packets += packets;
+- ndev->stats.tx_bytes += size;
++ u64_stats_update_begin(&lp->tx_stat_sync);
++ u64_stats_add(&lp->tx_packets, packets);
++ u64_stats_add(&lp->tx_bytes, size);
++ u64_stats_update_end(&lp->tx_stat_sync);
+
+ /* Matches barrier in axienet_start_xmit */
+ smp_mb();
+@@ -984,8 +986,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget)
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ }
+
+- lp->ndev->stats.rx_packets += packets;
+- lp->ndev->stats.rx_bytes += size;
++ u64_stats_update_begin(&lp->rx_stat_sync);
++ u64_stats_add(&lp->rx_packets, packets);
++ u64_stats_add(&lp->rx_bytes, size);
++ u64_stats_update_end(&lp->rx_stat_sync);
+
+ if (tail_p)
+ axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
+@@ -1292,10 +1296,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ return phylink_mii_ioctl(lp->phylink, rq, cmd);
+ }
+
++static void
++axienet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
++{
++ struct axienet_local *lp = netdev_priv(dev);
++ unsigned int start;
++
++ netdev_stats_to_stats64(stats, &dev->stats);
++
++ do {
++ start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync);
++ stats->rx_packets = u64_stats_read(&lp->rx_packets);
++ stats->rx_bytes = u64_stats_read(&lp->rx_bytes);
++ } while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start));
++
++ do {
++ start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync);
++ stats->tx_packets = u64_stats_read(&lp->tx_packets);
++ stats->tx_bytes = u64_stats_read(&lp->tx_bytes);
++ } while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start));
++}
++
+ static const struct net_device_ops axienet_netdev_ops = {
+ .ndo_open = axienet_open,
+ .ndo_stop = axienet_stop,
+ .ndo_start_xmit = axienet_start_xmit,
++ .ndo_get_stats64 = axienet_get_stats64,
+ .ndo_change_mtu = axienet_change_mtu,
+ .ndo_set_mac_address = netdev_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+@@ -1850,6 +1876,9 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->rx_bd_num = RX_BD_NUM_DEFAULT;
+ lp->tx_bd_num = TX_BD_NUM_DEFAULT;
+
++ u64_stats_init(&lp->rx_stat_sync);
++ u64_stats_init(&lp->tx_stat_sync);
++
+ netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll, NAPI_POLL_WEIGHT);
+ netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll, NAPI_POLL_WEIGHT);
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+index 25b38a374e3c3..dd5919ec408bf 100644
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -1051,7 +1051,8 @@ struct net_device_context {
+ u32 vf_alloc;
+ /* Serial number of the VF to team with */
+ u32 vf_serial;
+-
++ /* completion variable to confirm vf association */
++ struct completion vf_add;
+ /* Is the current data path through the VF NIC? */
+ bool data_path_is_vf;
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 6e42cb03e226a..456db7c28a34c 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1580,6 +1580,10 @@ static void netvsc_send_vf(struct net_device *ndev,
+
+ net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
+ net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
++
++ if (net_device_ctx->vf_alloc)
++ complete(&net_device_ctx->vf_add);
++
+ netdev_info(ndev, "VF slot %u %s\n",
+ net_device_ctx->vf_serial,
+ net_device_ctx->vf_alloc ? "added" : "removed");
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 15ebd54266049..8113ac17ab70a 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -2313,6 +2313,18 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
+
+ }
+
++ /* Fallback path to check synthetic vf with
++ * help of mac addr
++ */
++ list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
++ ndev = hv_get_drvdata(ndev_ctx->device_ctx);
++ if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) {
++ netdev_notice(vf_netdev,
++ "falling back to mac addr based matching\n");
++ return ndev;
++ }
++ }
++
+ netdev_notice(vf_netdev,
+ "no netdev found for vf serial:%u\n", serial);
+ return NULL;
+@@ -2409,6 +2421,11 @@ static int netvsc_vf_changed(struct net_device *vf_netdev, unsigned long event)
+ if (net_device_ctx->data_path_is_vf == vf_is_up)
+ return NOTIFY_OK;
+
++ if (vf_is_up && !net_device_ctx->vf_alloc) {
++ netdev_info(ndev, "Waiting for the VF association from host\n");
++ wait_for_completion(&net_device_ctx->vf_add);
++ }
++
+ ret = netvsc_switch_datapath(ndev, vf_is_up);
+
+ if (ret) {
+@@ -2440,6 +2457,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
+
+ netvsc_vf_setxdp(vf_netdev, NULL);
+
++ reinit_completion(&net_device_ctx->vf_add);
+ netdev_rx_handler_unregister(vf_netdev);
+ netdev_upper_dev_unlink(vf_netdev, ndev);
+ RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL);
+@@ -2479,6 +2497,7 @@ static int netvsc_probe(struct hv_device *dev,
+
+ INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
+
++ init_completion(&net_device_ctx->vf_add);
+ spin_lock_init(&net_device_ctx->lock);
+ INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
+ INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index ff5d0e98a0881..ab3f045629802 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -612,18 +612,13 @@ static void tbnet_connected_work(struct work_struct *work)
+ return;
+ }
+
+- /* Both logins successful so enable the high-speed DMA paths and
+- * start the network device queue.
++ /* Both logins successful so enable the rings, high-speed DMA
++ * paths and start the network device queue.
++ *
++ * Note we enable the DMA paths last to make sure we have primed
++ * the Rx ring before any incoming packets are allowed to
++ * arrive.
+ */
+- ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path,
+- net->rx_ring.ring->hop,
+- net->remote_transmit_path,
+- net->tx_ring.ring->hop);
+- if (ret) {
+- netdev_err(net->dev, "failed to enable DMA paths\n");
+- return;
+- }
+-
+ tb_ring_start(net->tx_ring.ring);
+ tb_ring_start(net->rx_ring.ring);
+
+@@ -635,10 +630,21 @@ static void tbnet_connected_work(struct work_struct *work)
+ if (ret)
+ goto err_free_rx_buffers;
+
++ ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path,
++ net->rx_ring.ring->hop,
++ net->remote_transmit_path,
++ net->tx_ring.ring->hop);
++ if (ret) {
++ netdev_err(net->dev, "failed to enable DMA paths\n");
++ goto err_free_tx_buffers;
++ }
++
+ netif_carrier_on(net->dev);
+ netif_start_queue(net->dev);
+ return;
+
++err_free_tx_buffers:
++ tbnet_free_buffers(&net->tx_ring);
+ err_free_rx_buffers:
+ tbnet_free_buffers(&net->rx_ring);
+ err_stop_rings:
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 688905ea0a6d3..e7b0b59e2bc8c 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -1874,7 +1874,9 @@ static void intr_callback(struct urb *urb)
+ "Stop submitting intr, status %d\n", status);
+ return;
+ case -EOVERFLOW:
+- netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n");
++ if (net_ratelimit())
++ netif_info(tp, intr, tp->netdev,
++ "intr status -EOVERFLOW\n");
+ goto resubmit;
+ /* -EPIPE: should clear the halt */
+ default:
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 276954b70d630..d1ac64026cb31 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -98,6 +98,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = true,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA988X_HW_2_0_VERSION,
+@@ -136,6 +137,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = true,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9887_HW_1_0_VERSION,
+@@ -175,6 +177,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA6174_HW_3_2_VERSION,
+@@ -209,6 +212,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .supports_peer_stats_info = true,
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -247,6 +251,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -285,6 +290,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA6174_HW_3_0_VERSION,
+@@ -323,6 +329,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA6174_HW_3_2_VERSION,
+@@ -365,6 +372,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .supports_peer_stats_info = true,
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -409,6 +417,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9984_HW_1_0_DEV_VERSION,
+@@ -460,6 +469,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9888_HW_2_0_DEV_VERSION,
+@@ -508,6 +518,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -546,6 +557,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -586,6 +598,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -617,6 +630,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .credit_size_workaround = true,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = QCA4019_HW_1_0_DEV_VERSION,
+@@ -662,6 +676,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
++ .use_fw_tx_credits = true,
+ },
+ {
+ .id = WCN3990_HW_1_0_DEV_VERSION,
+@@ -693,6 +708,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .tx_stats_over_pktlog = false,
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = true,
++ .use_fw_tx_credits = false,
+ },
+ };
+
+diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
+index fab398046a3f2..6d1784f74bea4 100644
+--- a/drivers/net/wireless/ath/ath10k/htc.c
++++ b/drivers/net/wireless/ath/ath10k/htc.c
+@@ -947,13 +947,18 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
+ return -ECOMM;
+ }
+
+- htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
++ if (ar->hw_params.use_fw_tx_credits)
++ htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
++ else
++ htc->total_transmit_credits = 1;
++
+ htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
+
+ ath10k_dbg(ar, ATH10K_DBG_HTC,
+- "Target ready! transmit resources: %d size:%d\n",
++ "Target ready! transmit resources: %d size:%d actual credits:%d\n",
+ htc->total_transmit_credits,
+- htc->target_credit_size);
++ htc->target_credit_size,
++ msg->ready.credit_count);
+
+ if ((htc->total_transmit_credits == 0) ||
+ (htc->target_credit_size == 0)) {
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
+index 93acf0dd580a6..1b99f3a39a113 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -635,6 +635,8 @@ struct ath10k_hw_params {
+ bool dynamic_sar_support;
+
+ bool hw_restart_disconnect;
++
++ bool use_fw_tx_credits;
+ };
+
+ struct htt_resp;
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 9dd3b8fba4b0e..23381a9db6aeb 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+ return 0;
+ }
+
++static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer)
++{
++ int peer_id, i;
++
++ lockdep_assert_held(&ar->conf_mutex);
++
++ for_each_set_bit(peer_id, peer->peer_ids,
++ ATH10K_MAX_NUM_PEER_IDS) {
++ ar->peer_map[peer_id] = NULL;
++ }
++
++ /* Double check that peer is properly un-referenced from
++ * the peer_map
++ */
++ for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
++ if (ar->peer_map[i] == peer) {
++ ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
++ peer->addr, peer, i);
++ ar->peer_map[i] = NULL;
++ }
++ }
++
++ list_del(&peer->list);
++ kfree(peer);
++ ar->num_peers--;
++}
++
+ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
+ {
+ struct ath10k_peer *peer, *tmp;
+- int peer_id;
+- int i;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+@@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
+ ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
+ peer->addr, vdev_id);
+
+- for_each_set_bit(peer_id, peer->peer_ids,
+- ATH10K_MAX_NUM_PEER_IDS) {
+- ar->peer_map[peer_id] = NULL;
+- }
+-
+- /* Double check that peer is properly un-referenced from
+- * the peer_map
+- */
+- for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
+- if (ar->peer_map[i] == peer) {
+- ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
+- peer->addr, peer, i);
+- ar->peer_map[i] = NULL;
+- }
+- }
+-
+- list_del(&peer->list);
+- kfree(peer);
+- ar->num_peers--;
++ ath10k_peer_map_cleanup(ar, peer);
+ }
+ spin_unlock_bh(&ar->data_lock);
+ }
+@@ -7621,10 +7628,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
+ /* Clean up the peer object as well since we
+ * must have failed to do this above.
+ */
+- list_del(&peer->list);
+- ar->peer_map[i] = NULL;
+- kfree(peer);
+- ar->num_peers--;
++ ath10k_peer_map_cleanup(ar, peer);
+ }
+ }
+ spin_unlock_bh(&ar->data_lock);
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
+index c474147101382..911eee9646a45 100644
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -1088,20 +1088,10 @@ err_core_free:
+ return ret;
+ }
+
+-static int ath11k_ahb_remove(struct platform_device *pdev)
++static void ath11k_ahb_remove_prepare(struct ath11k_base *ab)
+ {
+- struct ath11k_base *ab = platform_get_drvdata(pdev);
+ unsigned long left;
+
+- if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+- ath11k_ahb_power_down(ab);
+- ath11k_debugfs_soc_destroy(ab);
+- ath11k_qmi_deinit_service(ab);
+- goto qmi_fail;
+- }
+-
+- reinit_completion(&ab->driver_recovery);
+-
+ if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
+ left = wait_for_completion_timeout(&ab->driver_recovery,
+ ATH11K_AHB_RECOVERY_TIMEOUT);
+@@ -1111,19 +1101,60 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
+
+ set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
+ cancel_work_sync(&ab->restart_work);
++ cancel_work_sync(&ab->qmi.event_work);
++}
++
++static void ath11k_ahb_free_resources(struct ath11k_base *ab)
++{
++ struct platform_device *pdev = ab->pdev;
+
+- ath11k_core_deinit(ab);
+-qmi_fail:
+ ath11k_ahb_free_irq(ab);
+ ath11k_hal_srng_deinit(ab);
+ ath11k_ahb_fw_resource_deinit(ab);
+ ath11k_ce_free_pipes(ab);
+ ath11k_core_free(ab);
+ platform_set_drvdata(pdev, NULL);
++}
++
++static int ath11k_ahb_remove(struct platform_device *pdev)
++{
++ struct ath11k_base *ab = platform_get_drvdata(pdev);
++
++ if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
++ ath11k_ahb_power_down(ab);
++ ath11k_debugfs_soc_destroy(ab);
++ ath11k_qmi_deinit_service(ab);
++ goto qmi_fail;
++ }
++
++ ath11k_ahb_remove_prepare(ab);
++ ath11k_core_deinit(ab);
++
++qmi_fail:
++ ath11k_ahb_free_resources(ab);
+
+ return 0;
+ }
+
++static void ath11k_ahb_shutdown(struct platform_device *pdev)
++{
++ struct ath11k_base *ab = platform_get_drvdata(pdev);
++
++ /* platform shutdown() & remove() are mutually exclusive.
++ * remove() is invoked during rmmod & shutdown() during
++ * system reboot/shutdown.
++ */
++ ath11k_ahb_remove_prepare(ab);
++
++ if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)))
++ goto free_resources;
++
++ ath11k_core_deinit(ab);
++
++free_resources:
++ ath11k_ahb_free_resources(ab);
++}
++
+ static struct platform_driver ath11k_ahb_driver = {
+ .driver = {
+ .name = "ath11k",
+@@ -1131,6 +1162,7 @@ static struct platform_driver ath11k_ahb_driver = {
+ },
+ .probe = ath11k_ahb_probe,
+ .remove = ath11k_ahb_remove,
++ .shutdown = ath11k_ahb_shutdown,
+ };
+
+ static int ath11k_ahb_init(void)
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index c3e9e4f7bc24e..9df6aaae8a443 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -1563,6 +1563,8 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
+
+ wake_up(&ab->wmi_ab.tx_credits_wq);
+ wake_up(&ab->peer_mapping_wq);
++
++ reinit_completion(&ab->driver_recovery);
+ }
+
+ static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 2148acf37071e..e9c56ad1ec9d3 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -5197,7 +5197,8 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
+ if (log_type != ATH11K_PKTLOG_TYPE_INVALID)
+ trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
+
+- memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));
++ memset(ppdu_info, 0, sizeof(*ppdu_info));
++ ppdu_info->peer_id = HAL_INVALID_PEERID;
+ hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb);
+
+ if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 7e91e347c9ff2..7f6521314b2d4 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -4954,6 +4954,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)
+ if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) {
+ nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+ nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++ if (nsts > (ar->num_rx_chains - 1))
++ nsts = ar->num_rx_chains - 1;
+ value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
+ }
+
+@@ -4994,7 +4996,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)
+ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ {
+ bool subfer, subfee;
+- int sound_dim = 0;
++ int sound_dim = 0, nsts = 0;
+
+ subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE));
+ subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE));
+@@ -5004,6 +5006,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ subfer = false;
+ }
+
++ if (ar->num_rx_chains < 2) {
++ *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
++ subfee = false;
++ }
++
+ /* If SU Beaformer is not set, then disable MU Beamformer Capability */
+ if (!subfer)
+ *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
+@@ -5016,7 +5023,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+ *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
+
+- /* TODO: Need to check invalid STS and Sound_dim values set by FW? */
++ nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
++ nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++ *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+
+ /* Enable Sounding Dimension Field only if SU BF is enabled */
+ if (subfer) {
+@@ -5028,9 +5037,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ *vht_cap |= sound_dim;
+ }
+
+- /* Use the STS advertised by FW unless SU Beamformee is not supported*/
+- if (!subfee)
+- *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
++ /* Enable Beamformee STS Field only if SU BF is enabled */
++ if (subfee) {
++ if (nsts > (ar->num_rx_chains - 1))
++ nsts = ar->num_rx_chains - 1;
++
++ nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++ nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
++ *vht_cap |= nsts;
++ }
+ }
+
+ static struct ieee80211_sta_vht_cap
+diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
+index c44df17719f64..86995e8dc9135 100644
+--- a/drivers/net/wireless/ath/ath11k/mhi.c
++++ b/drivers/net/wireless/ath/ath11k/mhi.c
+@@ -402,8 +402,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ ret = ath11k_mhi_get_msi(ab_pci);
+ if (ret) {
+ ath11k_err(ab, "failed to get msi for mhi\n");
+- mhi_free_controller(mhi_ctrl);
+- return ret;
++ goto free_controller;
+ }
+
+ if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
+@@ -412,7 +411,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ if (test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
+ ret = ath11k_mhi_read_addr_from_dt(mhi_ctrl);
+ if (ret < 0)
+- return ret;
++ goto free_controller;
+ } else {
+ mhi_ctrl->iova_start = 0;
+ mhi_ctrl->iova_stop = 0xFFFFFFFF;
+@@ -440,18 +439,22 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ default:
+ ath11k_err(ab, "failed assign mhi_config for unknown hw rev %d\n",
+ ab->hw_rev);
+- mhi_free_controller(mhi_ctrl);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto free_controller;
+ }
+
+ ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config);
+ if (ret) {
+ ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
+- mhi_free_controller(mhi_ctrl);
+- return ret;
++ goto free_controller;
+ }
+
+ return 0;
++
++free_controller:
++ mhi_free_controller(mhi_ctrl);
++ ab_pci->mhi_ctrl = NULL;
++ return ret;
+ }
+
+ void ath11k_mhi_unregister(struct ath11k_pci *ab_pci)
+diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
+index 9e22aaf34b88c..1ae7af02c364e 100644
+--- a/drivers/net/wireless/ath/ath11k/peer.c
++++ b/drivers/net/wireless/ath/ath11k/peer.c
+@@ -302,6 +302,21 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
+ spin_lock_bh(&ab->base_lock);
+
+ peer = ath11k_peer_find_by_addr(ab, addr);
++ /* Check if the found peer is what we want to remove.
++ * While the sta is transitioning to another band we may
++ * have 2 peer with the same addr assigned to different
++ * vdev_id. Make sure we are deleting the correct peer.
++ */
++ if (peer && peer->vdev_id == vdev_id)
++ ath11k_peer_rhash_delete(ab, peer);
++
++ /* Fallback to peer list search if the correct peer can't be found.
++ * Skip the deletion of the peer from the rhash since it has already
++ * been deleted in peer add.
++ */
++ if (!peer)
++ peer = ath11k_peer_find(ab, vdev_id, addr);
++
+ if (!peer) {
+ spin_unlock_bh(&ab->base_lock);
+ mutex_unlock(&ab->tbl_mtx_lock);
+@@ -312,8 +327,6 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
+ return -EINVAL;
+ }
+
+- ath11k_peer_rhash_delete(ab, peer);
+-
+ spin_unlock_bh(&ab->base_lock);
+ mutex_unlock(&ab->tbl_mtx_lock);
+
+@@ -372,8 +385,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
+ if (peer) {
+- spin_unlock_bh(&ar->ab->base_lock);
+- return -EINVAL;
++ if (peer->vdev_id == param->vdev_id) {
++ spin_unlock_bh(&ar->ab->base_lock);
++ return -EINVAL;
++ }
++
++ /* Assume sta is transitioning to another band.
++ * Remove here the peer from rhash.
++ */
++ mutex_lock(&ar->ab->tbl_mtx_lock);
++ ath11k_peer_rhash_delete(ar->ab, peer);
++ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
+
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index 00136601cb7db..e6ced8597e1d6 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -1696,6 +1696,13 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
+ },
+ };
+
++static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = {
++ {
++ .data_type = QMI_EOTI,
++ .array_type = NO_ARRAY,
++ },
++};
++
+ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
+ {
+ struct qmi_wlanfw_host_cap_req_msg_v01 req;
+@@ -3006,6 +3013,10 @@ static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
+ struct ath11k_base *ab = qmi->ab;
+
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
++
++ ab->qmi.cal_done = 1;
++ wake_up(&ab->qmi.cold_boot_waitq);
++
+ ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
+ }
+
+@@ -3018,11 +3029,22 @@ static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,
+ struct ath11k_qmi, handle);
+ struct ath11k_base *ab = qmi->ab;
+
+- ab->qmi.cal_done = 1;
+- wake_up(&ab->qmi.cold_boot_waitq);
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n");
+ }
+
++static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl,
++ struct sockaddr_qrtr *sq,
++ struct qmi_txn *txn,
++ const void *decoded)
++{
++ struct ath11k_qmi *qmi = container_of(qmi_hdl,
++ struct ath11k_qmi, handle);
++ struct ath11k_base *ab = qmi->ab;
++
++ ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL);
++ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware init done\n");
++}
++
+ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ {
+ .type = QMI_INDICATION,
+@@ -3053,6 +3075,14 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
+ .fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
+ },
++ {
++ .type = QMI_INDICATION,
++ .msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,
++ .ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei,
++ .decoded_size =
++ sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),
++ .fn = ath11k_qmi_msg_fw_init_done_cb,
++ },
+ };
+
+ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
+@@ -3145,7 +3175,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
+ }
+
+ break;
+- case ATH11K_QMI_EVENT_FW_READY:
++ case ATH11K_QMI_EVENT_FW_INIT_DONE:
+ clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
+ if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
+ ath11k_hal_dump_srng_stats(ab);
+@@ -3168,6 +3198,8 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
+ set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+ }
+
++ break;
++ case ATH11K_QMI_EVENT_FW_READY:
+ break;
+ case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
+ break;
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
+index c83cf822be81a..2ec56a34fa810 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -31,8 +31,9 @@
+
+ #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
+ #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037
+-#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x0021
+-#define QMI_WLFW_FW_READY_IND_V01 0x0038
++#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x003E
++#define QMI_WLFW_FW_READY_IND_V01 0x0021
++#define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038
+
+ #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144
+ #define ATH11K_FIRMWARE_MODE_OFF 4
+@@ -69,6 +70,7 @@ enum ath11k_qmi_event_type {
+ ATH11K_QMI_EVENT_FORCE_FW_ASSERT,
+ ATH11K_QMI_EVENT_POWER_UP,
+ ATH11K_QMI_EVENT_POWER_DOWN,
++ ATH11K_QMI_EVENT_FW_INIT_DONE,
+ ATH11K_QMI_EVENT_MAX,
+ };
+
+@@ -291,6 +293,10 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 {
+ char placeholder;
+ };
+
++struct qmi_wlfw_fw_init_done_ind_msg_v01 {
++ char placeholder;
++};
++
+ #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0
+ #define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235
+ #define QMI_WLANFW_CAP_REQ_V01 0x0024
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 88ee4f9d19da5..b658ea60dcf7d 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -8962,12 +8962,13 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar,
+ cmd->interval = arg->interval;
+ cmd->method = arg->method;
+
++ arp = (struct wmi_sta_keepalive_arp_resp *)(cmd + 1);
++ arp->tlv_header = FIELD_PREP(WMI_TLV_TAG,
++ WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE) |
++ FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
++
+ if (arg->method == WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE ||
+ arg->method == WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST) {
+- arp = (struct wmi_sta_keepalive_arp_resp *)(cmd + 1);
+- arp->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+- WMI_TAG_STA_KEEPALVE_ARP_RESPONSE) |
+- FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
+ arp->src_ip4_addr = arg->src_ip4_addr;
+ arp->dest_ip4_addr = arg->dest_ip4_addr;
+ ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
+index 4da248ffa3186..ba5343a3411fa 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.h
++++ b/drivers/net/wireless/ath/ath11k/wmi.h
+@@ -1214,7 +1214,7 @@ enum wmi_tlv_tag {
+ WMI_TAG_NS_OFFLOAD_TUPLE,
+ WMI_TAG_FTM_INTG_CMD,
+ WMI_TAG_STA_KEEPALIVE_CMD,
+- WMI_TAG_STA_KEEPALVE_ARP_RESPONSE,
++ WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE,
+ WMI_TAG_P2P_SET_VENDOR_IE_DATA_CMD,
+ WMI_TAG_AP_PS_PEER_CMD,
+ WMI_TAG_PEER_RATE_RETRY_SCHED_CMD,
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index 994ec48b2f669..ca05b07a45e67 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -364,33 +364,27 @@ ret:
+ }
+
+ static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
+- struct sk_buff *skb)
++ struct sk_buff *skb, u32 len)
+ {
+ uint32_t *pattern = (uint32_t *)skb->data;
+
+- switch (*pattern) {
+- case 0x33221199:
+- {
++ if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) {
+ struct htc_panic_bad_vaddr *htc_panic;
+ htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
+ dev_err(htc_handle->dev, "ath: firmware panic! "
+ "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
+ htc_panic->exccause, htc_panic->pc,
+ htc_panic->badvaddr);
+- break;
+- }
+- case 0x33221299:
+- {
++ return;
++ }
++ if (*pattern == 0x33221299) {
+ struct htc_panic_bad_epid *htc_panic;
+ htc_panic = (struct htc_panic_bad_epid *) skb->data;
+ dev_err(htc_handle->dev, "ath: firmware panic! "
+ "bad epid: 0x%08x\n", htc_panic->epid);
+- break;
+- }
+- default:
+- dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
+- break;
++ return;
+ }
++ dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
+ }
+
+ /*
+@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+ if (!htc_handle || !skb)
+ return;
+
++ /* A valid message requires len >= 8.
++ *
++ * sizeof(struct htc_frame_hdr) == 8
++ * sizeof(struct htc_ready_msg) == 8
++ * sizeof(struct htc_panic_bad_vaddr) == 16
++ * sizeof(struct htc_panic_bad_epid) == 8
++ */
++ if (unlikely(len < sizeof(struct htc_frame_hdr)))
++ goto invalid;
+ htc_hdr = (struct htc_frame_hdr *) skb->data;
+ epid = htc_hdr->endpoint_id;
+
+ if (epid == 0x99) {
+- ath9k_htc_fw_panic_report(htc_handle, skb);
++ ath9k_htc_fw_panic_report(htc_handle, skb, len);
+ kfree_skb(skb);
+ return;
+ }
+
+ if (epid < 0 || epid >= ENDPOINT_MAX) {
++invalid:
+ if (pipe_id != USB_REG_IN_PIPE)
+ dev_kfree_skb_any(skb);
+ else
+@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+
+ /* Handle trailer */
+ if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
+- if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
++ if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) {
+ /* Move past the Watchdog pattern */
+ htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
++ len -= 4;
++ }
+ }
+
+ /* Get the message ID */
++ if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16)))
++ goto invalid;
+ msg_id = (__be16 *) ((void *) htc_hdr +
+ sizeof(struct htc_frame_hdr));
+
+ /* Now process HTC messages */
+ switch (be16_to_cpu(*msg_id)) {
+ case HTC_MSG_READY_ID:
++ if (unlikely(len < sizeof(struct htc_ready_msg)))
++ goto invalid;
+ htc_process_target_rdy(htc_handle, htc_hdr);
+ break;
+ case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
++ if (unlikely(len < sizeof(struct htc_frame_hdr) +
++ sizeof(struct htc_conn_svc_rspmsg)))
++ goto invalid;
+ htc_process_conn_rsp(htc_handle, htc_hdr);
+ break;
+ default:
+diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
+index cb5414265a9b5..58c0ab01771b0 100644
+--- a/drivers/net/wireless/ath/ath9k/rng.c
++++ b/drivers/net/wireless/ath/ath9k/rng.c
+@@ -83,7 +83,8 @@ static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+ if (!wait || !max || likely(bytes_read) || fail_stats > 110)
+ break;
+
+- msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
++ if (hwrng_msleep(rng, ath9k_rng_delay_get(++fail_stats)))
++ break;
+ }
+
+ if (wait && !bytes_read && max)
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+index bd164a0821f9f..ca95b02962eff 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -292,6 +292,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct ethhdr *eh;
+ int head_delta;
++ unsigned int tx_bytes = skb->len;
+
+ brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
+
+@@ -366,7 +367,7 @@ done:
+ ndev->stats.tx_dropped++;
+ } else {
+ ndev->stats.tx_packets++;
+- ndev->stats.tx_bytes += skb->len;
++ ndev->stats.tx_bytes += tx_bytes;
+ }
+
+ /* Return ok: we always eat the packet */
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+index fabfbb0b40b0c..d0a7465be586d 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
+ struct brcmf_pno_macaddr_le pfn_mac;
+ u8 *mac_addr = NULL;
+ u8 *mac_mask = NULL;
+- int err, i;
++ int err, i, ri;
+
+- for (i = 0; i < pi->n_reqs; i++)
+- if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+- mac_addr = pi->reqs[i]->mac_addr;
+- mac_mask = pi->reqs[i]->mac_addr_mask;
++ for (ri = 0; ri < pi->n_reqs; ri++)
++ if (pi->reqs[ri]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
++ mac_addr = pi->reqs[ri]->mac_addr;
++ mac_mask = pi->reqs[ri]->mac_addr_mask;
+ break;
+ }
+
+@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
+ pfn_mac.mac[0] |= 0x02;
+
+ brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n",
+- pi->reqs[i]->reqid, pfn_mac.mac);
++ pi->reqs[ri]->reqid, pfn_mac.mac);
+ err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
+ sizeof(pfn_mac));
+ if (err)
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index ee34814bd12b5..a074552bcec3d 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2995,10 +2995,15 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
+ u16 old_links, u16 new_links,
+ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
+ {
+- unsigned long rem = old_links & ~new_links ?: BIT(0);
++ unsigned long rem = old_links & ~new_links;
+ unsigned long add = new_links & ~old_links;
+ int i;
+
++ if (!old_links)
++ rem |= BIT(0);
++ if (!new_links)
++ add |= BIT(0);
++
+ for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS)
+ mac80211_hwsim_config_mac_nl(hw, old[i]->addr, false);
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
+index fc77489cc5119..7dddb4b5dea1d 100644
+--- a/drivers/net/wireless/marvell/mwifiex/init.c
++++ b/drivers/net/wireless/marvell/mwifiex/init.c
+@@ -51,9 +51,10 @@ static void wakeup_timer_fn(struct timer_list *t)
+ adapter->if_ops.card_reset(adapter);
+ }
+
+-static void fw_dump_timer_fn(struct timer_list *t)
++static void fw_dump_work(struct work_struct *work)
+ {
+- struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
++ struct mwifiex_adapter *adapter =
++ container_of(work, struct mwifiex_adapter, devdump_work.work);
+
+ mwifiex_upload_device_dump(adapter);
+ }
+@@ -309,7 +310,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+ adapter->active_scan_triggered = false;
+ timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
+ adapter->devdump_len = 0;
+- timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
++ INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work);
+ }
+
+ /*
+@@ -388,7 +389,7 @@ static void
+ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
+ {
+ del_timer(&adapter->wakeup_timer);
+- del_timer_sync(&adapter->devdump_timer);
++ cancel_delayed_work_sync(&adapter->devdump_work);
+ mwifiex_cancel_all_pending_cmd(adapter);
+ wake_up_interruptible(&adapter->cmd_wait_q.wait);
+ wake_up_interruptible(&adapter->hs_activate_wait_q);
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
+index 87729d251fedc..63f861e6b28af 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -37,6 +37,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/of_irq.h>
++#include <linux/workqueue.h>
+
+ #include "decl.h"
+ #include "ioctl.h"
+@@ -1043,7 +1044,7 @@ struct mwifiex_adapter {
+ /* Device dump data/length */
+ void *devdump_data;
+ int devdump_len;
+- struct timer_list devdump_timer;
++ struct delayed_work devdump_work;
+
+ bool ignore_btcoex_events;
+ };
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index b95e90a7d124a..e80e372cce8c4 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -611,8 +611,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ * transmission event get lost, in this cornel case,
+ * user would still get partial of the dump.
+ */
+- mod_timer(&adapter->devdump_timer,
+- jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
++ schedule_delayed_work(&adapter->devdump_work,
++ msecs_to_jiffies(MWIFIEX_TIMER_10S));
+ }
+
+ /* Overflow check */
+@@ -631,7 +631,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ return;
+
+ upload_dump:
+- del_timer_sync(&adapter->devdump_timer);
++ cancel_delayed_work_sync(&adapter->devdump_work);
+ mwifiex_upload_device_dump(adapter);
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+index 9bf8545c8c17c..8d4733f87cda9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+@@ -1195,12 +1195,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
+
++ mt7615_mutex_acquire(dev);
++
+ if (enabled)
+ set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+ else
+ clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+
+ mt7615_mcu_set_sta_decap_offload(dev, vif, sta);
++
++ mt7615_mutex_release(dev);
+ }
+
+ #ifdef CONFIG_PM
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+index 9b17bd97ec094..7cac7b126e590 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+@@ -260,8 +260,10 @@ mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
+ ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
+ ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
+
+- if (sta_hdr)
+- le16_add_cpu(&sta_hdr->len, len);
++ if (sta_hdr) {
++ len += le16_to_cpu(sta_hdr->len);
++ sta_hdr->len = cpu_to_le16(len);
++ }
+
+ return ptlv;
+ }
+@@ -2886,6 +2888,10 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+ goto out;
+ }
+
++ snprintf(dev->hw->wiphy->fw_version,
++ sizeof(dev->hw->wiphy->fw_version),
++ "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
++
+ release_firmware(fw);
+
+ if (!fw_wa)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+index fd76db8f5269c..6ef3431cad648 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+@@ -23,9 +23,9 @@ mt7915_implicit_txbf_set(void *data, u64 val)
+ {
+ struct mt7915_dev *dev = data;
+
+- if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
+- return -EBUSY;
+-
++ /* The existing connected stations shall reconnect to apply
++ * new implicit txbf configuration.
++ */
+ dev->ibf = !!val;
+
+ return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 60ae834d95a6d..49aa5c056063e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -232,7 +232,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
+ bool unicast, insert_ccmp_hdr = false;
+ u8 remove_pad, amsdu_info;
+ u8 mode = 0, qos_ctl = 0;
+- struct mt7915_sta *msta;
++ struct mt7915_sta *msta = NULL;
+ bool hdr_trans;
+ u16 hdr_gap;
+ u16 seq_ctrl = 0;
+@@ -2071,8 +2071,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw,
+ }
+
+ flowid = ffs(~msta->twt.flowid_mask) - 1;
+- le16p_replace_bits(&twt_agrt->req_type, flowid,
+- IEEE80211_TWT_REQTYPE_FLOWID);
++ twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_FLOWID);
++ twt_agrt->req_type |= le16_encode_bits(flowid,
++ IEEE80211_TWT_REQTYPE_FLOWID);
+
+ table_id = ffs(~dev->twt.table_mask) - 1;
+ exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, req_type);
+@@ -2122,8 +2123,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw,
+ unlock:
+ mutex_unlock(&dev->mt76.mutex);
+ out:
+- le16p_replace_bits(&twt_agrt->req_type, setup_cmd,
+- IEEE80211_TWT_REQTYPE_SETUP_CMD);
++ twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_SETUP_CMD);
++ twt_agrt->req_type |=
++ le16_encode_bits(setup_cmd, IEEE80211_TWT_REQTYPE_SETUP_CMD);
+ twt->control = (twt->control & IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT) |
+ (twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index f830679619451..e99fdacc11ce1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -1360,7 +1360,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ struct sta_phy phy = {};
+ int ret, nrates = 0;
+
+-#define __sta_phy_bitrate_mask_check(_mcs, _gi, _he) \
++#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he) \
+ do { \
+ u8 i, gi = mask->control[band]._gi; \
+ gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
+@@ -1373,15 +1373,17 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ continue; \
+ nrates += hweight16(mask->control[band]._mcs[i]); \
+ phy.mcs = ffs(mask->control[band]._mcs[i]) - 1; \
++ if (_ht) \
++ phy.mcs += 8 * i; \
+ } \
+ } while (0)
+
+ if (sta->deflink.he_cap.has_he) {
+- __sta_phy_bitrate_mask_check(he_mcs, he_gi, 1);
++ __sta_phy_bitrate_mask_check(he_mcs, he_gi, 0, 1);
+ } else if (sta->deflink.vht_cap.vht_supported) {
+- __sta_phy_bitrate_mask_check(vht_mcs, gi, 0);
++ __sta_phy_bitrate_mask_check(vht_mcs, gi, 0, 0);
+ } else if (sta->deflink.ht_cap.ht_supported) {
+- __sta_phy_bitrate_mask_check(ht_mcs, gi, 0);
++ __sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
+ } else {
+ nrates = hweight32(mask->control[band].legacy);
+ phy.mcs = ffs(mask->control[band].legacy) - 1;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
+index be4f07ad3af91..47e034a9b0037 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
+@@ -13,6 +13,7 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len)
+ acpi_handle root, handle;
+ acpi_status status;
+ u32 i = 0;
++ int ret;
+
+ root = ACPI_HANDLE(mdev->dev);
+ if (!root)
+@@ -52,9 +53,11 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len)
+ *(*tbl + i) = (u8)sar_unit->integer.value;
+ }
+ free:
++ ret = (i == sar_root->package.count) ? 0 : -EINVAL;
++
+ kfree(sar_root);
+
+- return (i == sar_root->package.count) ? 0 : -EINVAL;
++ return ret;
+ }
+
+ /* MTCL : Country List Table for 6G band */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 47f0aa81ab028..e8a7a58317822 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -235,7 +235,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ u32 rxd2 = le32_to_cpu(rxd[2]);
+ u32 rxd3 = le32_to_cpu(rxd[3]);
+ u32 rxd4 = le32_to_cpu(rxd[4]);
+- struct mt7921_sta *msta;
++ struct mt7921_sta *msta = NULL;
+ u16 seq_ctrl = 0;
+ __le16 fc = 0;
+ u8 mode = 0;
+@@ -780,6 +780,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+ void mt7921_reset(struct mt76_dev *mdev)
+ {
+ struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
++ struct mt76_connac_pm *pm = &dev->pm;
+
+ if (!dev->hw_init_done)
+ return;
+@@ -787,8 +788,12 @@ void mt7921_reset(struct mt76_dev *mdev)
+ if (dev->hw_full_reset)
+ return;
+
++ if (pm->suspended)
++ return;
++
+ queue_work(dev->mt76.wq, &dev->reset_work);
+ }
++EXPORT_SYMBOL_GPL(mt7921_reset);
+
+ void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
+ {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 1438a9f8d1fd9..c9e9a533289f0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -752,6 +752,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+
+ mt7921_mac_wtbl_update(dev, msta->wcid.idx,
+ MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
++ memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac));
+
+ mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC);
+
+@@ -1404,6 +1405,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,
+ struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+
++ mt7921_mutex_acquire(dev);
++
+ if (enabled)
+ set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+ else
+@@ -1411,6 +1414,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,
+
+ mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76, vif, &msta->wcid,
+ MCU_UNI_CMD(STA_REC_UPDATE));
++
++ mt7921_mutex_release(dev);
+ }
+
+ #if IS_ENABLED(CONFIG_IPV6)
+@@ -1526,17 +1531,23 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ int err;
+
++ mt7921_mutex_acquire(dev);
++
+ err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
+ true);
+ if (err)
+- return err;
++ goto out;
+
+ err = mt7921_mcu_set_bss_pm(dev, vif, true);
+ if (err)
+- return err;
++ goto out;
++
++ err = mt7921_mcu_sta_update(dev, NULL, vif, true,
++ MT76_STA_INFO_STATE_NONE);
++out:
++ mt7921_mutex_release(dev);
+
+- return mt7921_mcu_sta_update(dev, NULL, vif, true,
+- MT76_STA_INFO_STATE_NONE);
++ return err;
+ }
+
+ static void
+@@ -1548,11 +1559,16 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ int err;
+
++ mt7921_mutex_acquire(dev);
++
+ err = mt7921_mcu_set_bss_pm(dev, vif, false);
+ if (err)
+- return;
++ goto out;
+
+ mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false);
++
++out:
++ mt7921_mutex_release(dev);
+ }
+
+ const struct ieee80211_ops mt7921_ops = {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index ea3069d18c35f..e5b1f6249763a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -288,6 +288,8 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ goto err_free_pci_vec;
+ }
+
++ pci_set_drvdata(pdev, mdev);
++
+ dev = container_of(mdev, struct mt7921_dev, mt76);
+ dev->hif_ops = &mt7921_pcie_ops;
+
+@@ -367,6 +369,7 @@ static int mt7921_pci_suspend(struct device *device)
+ int i, err;
+
+ pm->suspended = true;
++ flush_work(&dev->reset_work);
+ cancel_delayed_work_sync(&pm->ps_work);
+ cancel_work_sync(&pm->wake_work);
+
+@@ -428,6 +431,9 @@ restore_napi:
+ restore_suspend:
+ pm->suspended = false;
+
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
++
+ return err;
+ }
+
+@@ -441,7 +447,7 @@ static int mt7921_pci_resume(struct device *device)
+
+ err = mt7921_mcu_drv_pmctrl(dev);
+ if (err < 0)
+- return err;
++ goto failed;
+
+ mt7921_wpdma_reinit_cond(dev);
+
+@@ -471,11 +477,12 @@ static int mt7921_pci_resume(struct device *device)
+ mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
+
+ err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+- if (err)
+- return err;
+-
++failed:
+ pm->suspended = false;
+
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
++
+ return err;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+index 487acd6e2be8f..2face849fb4fb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+@@ -206,6 +206,7 @@ static int mt7921s_suspend(struct device *__dev)
+ pm->suspended = true;
+ set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
+
++ flush_work(&dev->reset_work);
+ cancel_delayed_work_sync(&pm->ps_work);
+ cancel_work_sync(&pm->wake_work);
+
+@@ -261,6 +262,9 @@ restore_suspend:
+ clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
+ pm->suspended = false;
+
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
++
+ return err;
+ }
+
+@@ -276,7 +280,7 @@ static int mt7921s_resume(struct device *__dev)
+
+ err = mt7921_mcu_drv_pmctrl(dev);
+ if (err < 0)
+- return err;
++ goto failed;
+
+ mt76_worker_enable(&mdev->tx_worker);
+ mt76_worker_enable(&mdev->sdio.txrx_worker);
+@@ -288,11 +292,12 @@ static int mt7921s_resume(struct device *__dev)
+ mt76_connac_mcu_set_deep_sleep(mdev, false);
+
+ err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+- if (err)
+- return err;
+-
++failed:
+ pm->suspended = false;
+
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
++
+ return err;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+index dd3b8884e1620..613d5cefffc73 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+@@ -300,11 +300,15 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf)
+ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
+ {
+ struct mt7921_dev *dev = usb_get_intfdata(intf);
++ struct mt76_connac_pm *pm = &dev->pm;
+ int err;
+
++ pm->suspended = true;
++ flush_work(&dev->reset_work);
++
+ err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
+ if (err)
+- return err;
++ goto failed;
+
+ mt76u_stop_rx(&dev->mt76);
+ mt76u_stop_tx(&dev->mt76);
+@@ -312,11 +316,20 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
+ set_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
+
+ return 0;
++
++failed:
++ pm->suspended = false;
++
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
++
++ return err;
+ }
+
+ static int mt7921u_resume(struct usb_interface *intf)
+ {
+ struct mt7921_dev *dev = usb_get_intfdata(intf);
++ struct mt76_connac_pm *pm = &dev->pm;
+ bool reinit = true;
+ int err, i;
+
+@@ -338,16 +351,23 @@ static int mt7921u_resume(struct usb_interface *intf)
+ if (reinit || mt7921_dma_need_reinit(dev)) {
+ err = mt7921u_dma_init(dev, true);
+ if (err)
+- return err;
++ goto failed;
+ }
+
+ clear_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
+
+ err = mt76u_resume_rx(&dev->mt76);
+ if (err < 0)
+- return err;
++ goto failed;
++
++ err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
++failed:
++ pm->suspended = false;
++
++ if (err < 0)
++ mt7921_reset(&dev->mt76);
+
+- return mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
++ return err;
+ }
+ #endif /* CONFIG_PM */
+
+diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
+index aba2a98658214..0ec308f99af5a 100644
+--- a/drivers/net/wireless/mediatek/mt76/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/sdio.c
+@@ -478,14 +478,14 @@ static void mt76s_status_worker(struct mt76_worker *w)
+ if (ndata_frames > 0)
+ resched = true;
+
+- if (dev->drv->tx_status_data &&
++ if (dev->drv->tx_status_data && ndata_frames > 0 &&
+ !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) &&
+ !test_bit(MT76_STATE_SUSPEND, &dev->phy.state))
+- queue_work(dev->wq, &dev->sdio.stat_work);
++ ieee80211_queue_work(dev->hw, &dev->sdio.stat_work);
+ } while (nframes > 0);
+
+ if (resched)
+- mt76_worker_schedule(&dev->sdio.txrx_worker);
++ mt76_worker_schedule(&dev->tx_worker);
+ }
+
+ static void mt76s_tx_status_data(struct work_struct *work)
+@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work)
+ }
+
+ if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
+- queue_work(dev->wq, &sdio->stat_work);
++ ieee80211_queue_work(dev->hw, &sdio->stat_work);
+ else
+ clear_bit(MT76_READING_STATS, &dev->phy.state);
+ }
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 18102fbe36d6c..1a9e27a6d6369 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4164,7 +4164,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+- rt2800_bbp_write(rt2x00dev, 86, 0);
++ if (rt2x00_rt(rt2x00dev, RT6352))
++ rt2800_bbp_write(rt2x00dev, 86, 0x38);
++ else
++ rt2800_bbp_write(rt2x00dev, 86, 0);
+ }
+
+ if (rf->channel <= 14) {
+@@ -4365,7 +4368,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+- rt2800_iq_calibrate(rt2x00dev, rf->channel);
++ if (rt2x00_rt(rt2x00dev, RT5592))
++ rt2800_iq_calibrate(rt2x00dev, rf->channel);
+ }
+
+ bbp = rt2800_bbp_read(rt2x00dev, 4);
+@@ -5644,7 +5648,8 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
+ if (qual->vgc_level != vgc_level) {
+ if (rt2x00_rt(rt2x00dev, RT3572) ||
+ rt2x00_rt(rt2x00dev, RT3593) ||
+- rt2x00_rt(rt2x00dev, RT3883)) {
++ rt2x00_rt(rt2x00dev, RT3883) ||
++ rt2x00_rt(rt2x00dev, RT6352)) {
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
+ vgc_level);
+ } else if (rt2x00_rt(rt2x00dev, RT5592)) {
+@@ -5867,7 +5872,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ } else if (rt2x00_rt(rt2x00dev, RT6352)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
+- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
+@@ -6129,6 +6134,27 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
+ rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125);
+ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
++ } else if (rt2x00_is_soc(rt2x00dev)) {
++ struct clk *clk = clk_get_sys("bus", NULL);
++ int rate;
++
++ if (IS_ERR(clk)) {
++ clk = clk_get_sys("cpu", NULL);
++
++ if (IS_ERR(clk)) {
++ rate = 125;
++ } else {
++ rate = clk_get_rate(clk) / 3000000;
++ clk_put(clk);
++ }
++ } else {
++ rate = clk_get_rate(clk) / 1000000;
++ clk_put(clk);
++ }
++
++ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
++ rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, rate);
++ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
+ }
+
+ reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index 7ddce3c3f0c48..782b089a2e1ba 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -1425,7 +1425,7 @@ struct rtl8xxxu_fileops {
+ void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
+ bool ht40);
+ void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
+- u32 ramask, u8 rateid, int sgi);
++ u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ void (*report_connect) (struct rtl8xxxu_priv *priv,
+ u8 macid, bool connect);
+ void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+@@ -1511,9 +1511,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
+ void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
+ void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv);
+ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+- u32 ramask, u8 rateid, int sgi);
++ u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+- u32 ramask, u8 rateid, int sgi);
++ u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
+ u8 macid, bool connect);
+ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index c66f0726b2535..08f9d17dce12e 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1878,13 +1878,6 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
+
+ /* We have 8 bits to indicate validity */
+ map_addr = offset * 8;
+- if (map_addr >= EFUSE_MAP_LEN) {
+- dev_warn(dev, "%s: Illegal map_addr (%04x), "
+- "efuse corrupt!\n",
+- __func__, map_addr);
+- ret = -EINVAL;
+- goto exit;
+- }
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (word_mask & BIT(i)) {
+@@ -1895,6 +1888,13 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
+ ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8);
+ if (ret)
+ goto exit;
++ if (map_addr >= EFUSE_MAP_LEN - 1) {
++ dev_warn(dev, "%s: Illegal map_addr (%04x), "
++ "efuse corrupt!\n",
++ __func__, map_addr);
++ ret = -EINVAL;
++ goto exit;
++ }
+ priv->efuse_wifi.raw[map_addr++] = val8;
+
+ ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8);
+@@ -2929,12 +2929,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
+ }
+
+ if (!(simubitmap & 0x30) && priv->tx_paths > 1) {
+- /* path B RX OK */
++ /* path B TX OK */
+ for (i = 4; i < 6; i++)
+ result[3][i] = result[c1][i];
+ }
+
+- if (!(simubitmap & 0x30) && priv->tx_paths > 1) {
++ if (!(simubitmap & 0xc0) && priv->tx_paths > 1) {
+ /* path B RX OK */
+ for (i = 6; i < 8; i++)
+ result[3][i] = result[c1][i];
+@@ -4320,7 +4320,7 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
+ }
+
+ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+- u32 ramask, u8 rateid, int sgi)
++ u32 ramask, u8 rateid, int sgi, int txbw_40mhz)
+ {
+ struct h2c_cmd h2c;
+
+@@ -4340,10 +4340,15 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+ }
+
+ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+- u32 ramask, u8 rateid, int sgi)
++ u32 ramask, u8 rateid, int sgi, int txbw_40mhz)
+ {
+ struct h2c_cmd h2c;
+- u8 bw = RTL8XXXU_CHANNEL_WIDTH_20;
++ u8 bw;
++
++ if (txbw_40mhz)
++ bw = RTL8XXXU_CHANNEL_WIDTH_40;
++ else
++ bw = RTL8XXXU_CHANNEL_WIDTH_20;
+
+ memset(&h2c, 0, sizeof(struct h2c_cmd));
+
+@@ -4353,15 +4358,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+ h2c.b_macid_cfg.ramask2 = (ramask >> 16) & 0xff;
+ h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff;
+
+- h2c.ramask.arg = 0x80;
+ h2c.b_macid_cfg.data1 = rateid;
+ if (sgi)
+ h2c.b_macid_cfg.data1 |= BIT(7);
+
+ h2c.b_macid_cfg.data2 = bw;
+
+- dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x, size %zi\n",
+- __func__, ramask, h2c.ramask.arg, sizeof(h2c.b_macid_cfg));
++ dev_dbg(&priv->udev->dev, "%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n",
++ __func__, ramask, rateid, sgi, sizeof(h2c.b_macid_cfg));
+ rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_macid_cfg));
+ }
+
+@@ -4556,6 +4560,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)
+ return network_type;
+ }
+
++static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time)
++{
++ u32 reg_edca_param[IEEE80211_NUM_ACS] = {
++ [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM,
++ [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM,
++ [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM,
++ [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM,
++ };
++ u32 val32;
++ u16 wireless_mode = 0;
++ u8 aifs, aifsn, sifs;
++ int i;
++
++ if (priv->vif) {
++ struct ieee80211_sta *sta;
++
++ rcu_read_lock();
++ sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid);
++ if (sta)
++ wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta);
++ rcu_read_unlock();
++ }
++
++ if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ ||
++ (wireless_mode & WIRELESS_MODE_N_24G))
++ sifs = 16;
++ else
++ sifs = 10;
++
++ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
++ val32 = rtl8xxxu_read32(priv, reg_edca_param[i]);
++
++ /* It was set in conf_tx. */
++ aifsn = val32 & 0xff;
++
++ /* aifsn not set yet or already fixed */
++ if (aifsn < 2 || aifsn > 15)
++ continue;
++
++ aifs = aifsn * slot_time + sifs;
++
++ val32 &= ~0xff;
++ val32 |= aifs;
++ rtl8xxxu_write32(priv, reg_edca_param[i], val32);
++ }
++}
++
+ static void
+ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf, u64 changed)
+@@ -4622,7 +4673,11 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ RATE_INFO_FLAGS_SHORT_GI;
+ }
+
+- rarpt->txrate.bw |= RATE_INFO_BW_20;
++ if (rtl8xxxu_ht40_2g &&
++ (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
++ rarpt->txrate.bw = RATE_INFO_BW_40;
++ else
++ rarpt->txrate.bw = RATE_INFO_BW_20;
+ }
+ bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ rarpt->bit_rate = bit_rate;
+@@ -4631,7 +4686,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ priv->vif = vif;
+ priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
+
+- priv->fops->update_rate_mask(priv, ramask, 0, sgi);
++ priv->fops->update_rate_mask(priv, ramask, 0, sgi, rarpt->txrate.bw == RATE_INFO_BW_40);
+
+ rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
+
+@@ -4671,6 +4726,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ else
+ val8 = 20;
+ rtl8xxxu_write8(priv, REG_SLOT, val8);
++
++ rtl8xxxu_set_aifs(priv, val8);
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+@@ -5062,6 +5119,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
+ if (control && control->sta)
+ sta = control->sta;
+
++ queue = rtl8xxxu_queue_select(hw, skb);
++
+ tx_desc = skb_push(skb, tx_desc_size);
+
+ memset(tx_desc, 0, tx_desc_size);
+@@ -5074,7 +5133,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
+ is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
+
+- queue = rtl8xxxu_queue_select(hw, skb);
+ tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
+
+ if (tx_info->control.hw_key) {
+@@ -6344,7 +6402,7 @@ static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv,
+ }
+
+ priv->rssi_level = rssi_level;
+- priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi);
++ priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz);
+ }
+ }
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+index 15e6a6aded319..d18c092b61426 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+@@ -2386,11 +2386,10 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
+ rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
+ "Just Read IQK Matrix reg for channel:%d....\n",
+ channel);
+- _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
+- rtlphy->iqk_matrix[
+- indexforchannel].value, 0,
+- (rtlphy->iqk_matrix[
+- indexforchannel].value[0][2] == 0));
++ if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0)
++ _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
++ rtlphy->iqk_matrix[indexforchannel].value, 0,
++ rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0);
+ if (IS_92D_SINGLEPHY(rtlhal->version)) {
+ if ((rtlphy->iqk_matrix[
+ indexforchannel].value[0][4] != 0)
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 76dc9da88f6c2..3d31c0517a129 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -2045,7 +2045,7 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+ ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW);
+ if (ret) {
+ rtw_warn(rtwdev, "no firmware loaded\n");
+- return ret;
++ goto out;
+ }
+
+ if (chip->wow_fw_name) {
+@@ -2055,11 +2055,15 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+ wait_for_completion(&rtwdev->fw.completion);
+ if (rtwdev->fw.firmware)
+ release_firmware(rtwdev->fw.firmware);
+- return ret;
++ goto out;
+ }
+ }
+
+ return 0;
++
++out:
++ destroy_workqueue(rtwdev->tx_wq);
++ return ret;
+ }
+ EXPORT_SYMBOL(rtw_core_init);
+
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index a5880a54812e7..8b338e5ce364e 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -872,6 +872,7 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "ignore h2c due to power is off with firmware state=%d\n",
+ test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags));
++ dev_kfree_skb(skb);
+ return 0;
+ }
+
+diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
+index 6473015a6b2a1..c993fe9cf6b4a 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -2289,6 +2289,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ {
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct cfg80211_scan_request *req = &scan_req->req;
++ u32 rx_fltr = rtwdev->hal.rx_fltr;
+ u8 mac_addr[ETH_ALEN];
+
+ rtwdev->scan_info.scanning_vif = vif;
+@@ -2303,13 +2304,13 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ ether_addr_copy(mac_addr, vif->addr);
+ rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
+
+- rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
+- rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
+- rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
++ rx_fltr &= ~B_AX_A_BCN_CHK_EN;
++ rx_fltr &= ~B_AX_A_BC;
++ rx_fltr &= ~B_AX_A_A1_MATCH;
+ rtw89_write32_mask(rtwdev,
+ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ B_AX_RX_FLTR_CFG_MASK,
+- rtwdev->hal.rx_fltr);
++ rx_fltr);
+ }
+
+ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+@@ -2323,9 +2324,6 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ if (!vif)
+ return;
+
+- rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
+- rtwdev->hal.rx_fltr |= B_AX_A_BC;
+- rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
+ rtw89_write32_mask(rtwdev,
+ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ B_AX_RX_FLTR_CFG_MASK,
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index c68fec9eb5a64..7bb1b494c5d15 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -760,7 +760,8 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev)
+
+ enable_intr:
+ spin_lock_irqsave(&rtwpci->irq_lock, flags);
+- rtw89_chip_enable_intr(rtwdev, rtwpci);
++ if (likely(rtwpci->running))
++ rtw89_chip_enable_intr(rtwdev, rtwpci);
+ spin_unlock_irqrestore(&rtwpci->irq_lock, flags);
+ return IRQ_HANDLED;
+ }
+@@ -925,10 +926,12 @@ u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev,
+ {
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch];
++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring;
+ u32 cnt;
+
+ spin_lock_bh(&rtwpci->trx_lock);
+ cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
++ cnt = min(cnt, wd_ring->curr_num);
+ spin_unlock_bh(&rtwpci->trx_lock);
+
+ return cnt;
+diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
+index 726223f25dc69..7240364e8f7df 100644
+--- a/drivers/net/wireless/realtek/rtw89/ser.c
++++ b/drivers/net/wireless/realtek/rtw89/ser.c
+@@ -152,7 +152,10 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)
+ rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
+ ser_st_name(ser), ser_ev_name(ser, evt));
+
++ mutex_lock(&rtwdev->mutex);
+ rtw89_leave_lps(rtwdev);
++ mutex_unlock(&rtwdev->mutex);
++
+ ser->st_tbl[ser->state].st_func(ser, evt);
+ }
+
+diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c
+index e015bfb8d221f..84d82ddded567 100644
+--- a/drivers/net/wireless/silabs/wfx/main.c
++++ b/drivers/net/wireless/silabs/wfx/main.c
+@@ -181,7 +181,7 @@ int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len)
+ while (len > 0) {
+ chunk_type = get_unaligned_le16(buf + 0);
+ chunk_len = get_unaligned_le16(buf + 2);
+- if (chunk_len > len) {
++ if (chunk_len < 4 || chunk_len > len) {
+ dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num);
+ return -EINVAL;
+ }
+diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c
+index e06da4b3b0d46..805a3c1bf8fe2 100644
+--- a/drivers/net/wireless/st/cw1200/queue.c
++++ b/drivers/net/wireless/st/cw1200/queue.c
+@@ -91,23 +91,25 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue,
+ bool unlock)
+ {
+ struct cw1200_queue_stats *stats = queue->stats;
+- struct cw1200_queue_item *item = NULL, *tmp;
++ struct cw1200_queue_item *item = NULL, *iter, *tmp;
+ bool wakeup_stats = false;
+
+- list_for_each_entry_safe(item, tmp, &queue->queue, head) {
+- if (time_is_after_jiffies(item->queue_timestamp + queue->ttl))
++ list_for_each_entry_safe(iter, tmp, &queue->queue, head) {
++ if (time_is_after_jiffies(iter->queue_timestamp + queue->ttl)) {
++ item = iter;
+ break;
++ }
+ --queue->num_queued;
+- --queue->link_map_cache[item->txpriv.link_id];
++ --queue->link_map_cache[iter->txpriv.link_id];
+ spin_lock_bh(&stats->lock);
+ --stats->num_queued;
+- if (!--stats->link_map_cache[item->txpriv.link_id])
++ if (!--stats->link_map_cache[iter->txpriv.link_id])
+ wakeup_stats = true;
+ spin_unlock_bh(&stats->lock);
+ cw1200_debug_tx_ttl(stats->priv);
+- cw1200_queue_register_post_gc(head, item);
+- item->skb = NULL;
+- list_move_tail(&item->head, &queue->free_pool);
++ cw1200_queue_register_post_gc(head, iter);
++ iter->skb = NULL;
++ list_move_tail(&iter->head, &queue->free_pool);
+ }
+
+ if (wakeup_stats)
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+index 27151148c782c..4712f01a7e33e 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+@@ -323,15 +323,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev)
+ ipc_wwan->dev = dev;
+ ipc_wwan->ipc_imem = ipc_imem;
+
++ mutex_init(&ipc_wwan->if_mutex);
++
+ /* WWAN core will create a netdev for the default IP MUX channel */
+ if (wwan_register_ops(ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan,
+ IP_MUX_SESSION_DEFAULT)) {
++ mutex_destroy(&ipc_wwan->if_mutex);
+ kfree(ipc_wwan);
+ return NULL;
+ }
+
+- mutex_init(&ipc_wwan->if_mutex);
+-
+ return ipc_wwan;
+ }
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 8d5a7ae198440..59e4b188fc71c 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1111,8 +1111,8 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+ return effects;
+ }
+
+-static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
+- struct nvme_command *cmd, int status)
++void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
++ struct nvme_command *cmd, int status)
+ {
+ if (effects & NVME_CMD_EFFECTS_CSE_MASK) {
+ nvme_unfreeze(ctrl);
+@@ -1148,21 +1148,16 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
+ break;
+ }
+ }
++EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU);
+
+-int nvme_execute_passthru_rq(struct request *rq)
++int nvme_execute_passthru_rq(struct request *rq, u32 *effects)
+ {
+ struct nvme_command *cmd = nvme_req(rq)->cmd;
+ struct nvme_ctrl *ctrl = nvme_req(rq)->ctrl;
+ struct nvme_ns *ns = rq->q->queuedata;
+- u32 effects;
+- int ret;
+
+- effects = nvme_passthru_start(ctrl, ns, cmd->common.opcode);
+- ret = nvme_execute_rq(rq, false);
+- if (effects) /* nothing to be done for zero cmd effects */
+- nvme_passthru_end(ctrl, effects, cmd, ret);
+-
+- return ret;
++ *effects = nvme_passthru_start(ctrl, ns, cmd->common.opcode);
++ return nvme_execute_rq(rq, false);
+ }
+ EXPORT_SYMBOL_NS_GPL(nvme_execute_passthru_rq, NVME_TARGET_PASSTHRU);
+
+@@ -2894,7 +2889,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ nvme_init_subnqn(subsys, ctrl, id);
+ memcpy(subsys->serial, id->sn, sizeof(subsys->serial));
+ memcpy(subsys->model, id->mn, sizeof(subsys->model));
+- memcpy(subsys->firmware_rev, id->fr, sizeof(subsys->firmware_rev));
+ subsys->vendor_id = le16_to_cpu(id->vid);
+ subsys->cmic = id->cmic;
+
+@@ -3113,6 +3107,8 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ ctrl->quirks |= core_quirks[i].quirks;
+ }
+ }
++ memcpy(ctrl->subsys->firmware_rev, id->fr,
++ sizeof(ctrl->subsys->firmware_rev));
+
+ if (force_apst && (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS)) {
+ dev_warn(ctrl->device, "forcibly allowing all power states due to nvme_core.force_apst -- use at your own risk\n");
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index 27614bee73806..d3281f87cd6e4 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -136,9 +136,11 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
+ u32 meta_seed, u64 *result, unsigned timeout, bool vec)
+ {
++ struct nvme_ctrl *ctrl;
+ struct request *req;
+ void *meta = NULL;
+ struct bio *bio;
++ u32 effects;
+ int ret;
+
+ req = nvme_alloc_user_request(q, cmd, ubuffer, bufflen, meta_buffer,
+@@ -147,8 +149,9 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ return PTR_ERR(req);
+
+ bio = req->bio;
++ ctrl = nvme_req(req)->ctrl;
+
+- ret = nvme_execute_passthru_rq(req);
++ ret = nvme_execute_passthru_rq(req, &effects);
+
+ if (result)
+ *result = le64_to_cpu(nvme_req(req)->result.u64);
+@@ -158,6 +161,10 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ if (bio)
+ blk_rq_unmap_user(bio);
+ blk_mq_free_request(req);
++
++ if (effects)
++ nvme_passthru_end(ctrl, effects, cmd, ret);
++
+ return ret;
+ }
+
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index 6ef497c75a165..b9cf17cbbbd5d 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -182,6 +182,7 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
+
+ for_each_node(node)
+ rcu_assign_pointer(head->current_path[node], NULL);
++ kblockd_schedule_work(&head->requeue_work);
+ }
+
+ static bool nvme_path_is_disabled(struct nvme_ns *ns)
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 1bdf714dcd9e4..a0bf9560cf678 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -1023,7 +1023,9 @@ static inline void nvme_auth_free(struct nvme_ctrl *ctrl) {};
+
+ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+ u8 opcode);
+-int nvme_execute_passthru_rq(struct request *rq);
++int nvme_execute_passthru_rq(struct request *rq, u32 *effects);
++void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
++ struct nvme_command *cmd, int status);
+ struct nvme_ctrl *nvme_ctrl_from_file(struct file *file);
+ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);
+ void nvme_put_ns(struct nvme_ns *ns);
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 7f4083cf953a6..14677145bbba0 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -832,6 +832,7 @@ int nvmet_sq_init(struct nvmet_sq *sq)
+ }
+ init_completion(&sq->free_done);
+ init_completion(&sq->confirm_done);
++ nvmet_auth_sq_init(sq);
+
+ return 0;
+ }
+diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c
+index ebdf9aa810419..0c078b6b1447e 100644
+--- a/drivers/nvme/target/fabrics-cmd-auth.c
++++ b/drivers/nvme/target/fabrics-cmd-auth.c
+@@ -23,17 +23,12 @@ static void nvmet_auth_expired_work(struct work_struct *work)
+ sq->dhchap_tid = -1;
+ }
+
+-void nvmet_init_auth(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
++void nvmet_auth_sq_init(struct nvmet_sq *sq)
+ {
+- u32 result = le32_to_cpu(req->cqe->result.u32);
+-
+ /* Initialize in-band authentication */
+- INIT_DELAYED_WORK(&req->sq->auth_expired_work,
+- nvmet_auth_expired_work);
+- req->sq->authenticated = false;
+- req->sq->dhchap_step = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE;
+- result |= (u32)NVME_CONNECT_AUTHREQ_ATR << 16;
+- req->cqe->result.u32 = cpu_to_le32(result);
++ INIT_DELAYED_WORK(&sq->auth_expired_work, nvmet_auth_expired_work);
++ sq->authenticated = false;
++ sq->dhchap_step = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE;
+ }
+
+ static u16 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
+diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
+index f91a56180d3dd..bd739d8b6991b 100644
+--- a/drivers/nvme/target/fabrics-cmd.c
++++ b/drivers/nvme/target/fabrics-cmd.c
+@@ -272,7 +272,8 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
+ req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid);
+
+ if (nvmet_has_auth(ctrl))
+- nvmet_init_auth(ctrl, req);
++ req->cqe->result.u32 |=
++ cpu_to_le32((u32)NVME_CONNECT_AUTHREQ_ATR << 16);
+ out:
+ kfree(d);
+ complete:
+@@ -334,7 +335,8 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
+ pr_debug("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid);
+ req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid);
+ if (nvmet_has_auth(ctrl))
+- nvmet_init_auth(ctrl, req);
++ req->cqe->result.u32 |=
++ cpu_to_le32((u32)NVME_CONNECT_AUTHREQ_ATR << 16);
+
+ out:
+ kfree(d);
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index 6ffeeb0a1c49e..dfe3894205aa7 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -704,7 +704,7 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
+ bool set_ctrl);
+ int nvmet_auth_set_host_hash(struct nvmet_host *host, const char *hash);
+ int nvmet_setup_auth(struct nvmet_ctrl *ctrl);
+-void nvmet_init_auth(struct nvmet_ctrl *ctrl, struct nvmet_req *req);
++void nvmet_auth_sq_init(struct nvmet_sq *sq);
+ void nvmet_destroy_auth(struct nvmet_ctrl *ctrl);
+ void nvmet_auth_sq_free(struct nvmet_sq *sq);
+ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id);
+@@ -726,8 +726,9 @@ static inline int nvmet_setup_auth(struct nvmet_ctrl *ctrl)
+ {
+ return 0;
+ }
+-static inline void nvmet_init_auth(struct nvmet_ctrl *ctrl,
+- struct nvmet_req *req) {};
++static inline void nvmet_auth_sq_init(struct nvmet_sq *sq)
++{
++}
+ static inline void nvmet_destroy_auth(struct nvmet_ctrl *ctrl) {};
+ static inline void nvmet_auth_sq_free(struct nvmet_sq *sq) {};
+ static inline bool nvmet_check_auth_status(struct nvmet_req *req)
+diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
+index 6f39a29828b12..94d3153bae54d 100644
+--- a/drivers/nvme/target/passthru.c
++++ b/drivers/nvme/target/passthru.c
+@@ -215,9 +215,11 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
+ {
+ struct nvmet_req *req = container_of(w, struct nvmet_req, p.work);
+ struct request *rq = req->p.rq;
++ struct nvme_ctrl *ctrl = nvme_req(rq)->ctrl;
++ u32 effects;
+ int status;
+
+- status = nvme_execute_passthru_rq(rq);
++ status = nvme_execute_passthru_rq(rq, &effects);
+
+ if (status == NVME_SC_SUCCESS &&
+ req->cmd->common.opcode == nvme_admin_identify) {
+@@ -238,6 +240,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
+ req->cqe->result = nvme_req(rq)->result;
+ nvmet_req_complete(req, status);
+ blk_mq_free_request(rq);
++
++ if (effects)
++ nvme_passthru_end(ctrl, effects, req->cmd, status);
+ }
+
+ static void nvmet_passthru_req_done(struct request *rq,
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index a3694a32f6d52..7dcf88cde1893 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -935,10 +935,17 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+ struct nvmet_tcp_cmd *cmd;
+
+- if (likely(queue->nr_cmds))
++ if (likely(queue->nr_cmds)) {
++ if (unlikely(data->ttag >= queue->nr_cmds)) {
++ pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n",
++ queue->idx, data->ttag, queue->nr_cmds);
++ nvmet_tcp_fatal_error(queue);
++ return -EPROTO;
++ }
+ cmd = &queue->cmds[data->ttag];
+- else
++ } else {
+ cmd = &queue->connect;
++ }
+
+ if (le32_to_cpu(data->data_offset) != cmd->rbytes_done) {
+ pr_err("ttag %u unexpected data offset %u (expected %u)\n",
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index 1e3c754efd0d8..2164efd12ba9b 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -829,21 +829,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
+ nvmem->dev.groups = nvmem_dev_groups;
+ #endif
+
+- if (nvmem->nkeepout) {
+- rval = nvmem_validate_keepouts(nvmem);
+- if (rval) {
+- ida_free(&nvmem_ida, nvmem->id);
+- kfree(nvmem);
+- return ERR_PTR(rval);
+- }
+- }
+-
+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
+
+ rval = device_register(&nvmem->dev);
+ if (rval)
+ goto err_put_device;
+
++ if (nvmem->nkeepout) {
++ rval = nvmem_validate_keepouts(nvmem);
++ if (rval)
++ goto err_device_del;
++ }
++
+ if (config->compat) {
+ rval = nvmem_sysfs_setup_compat(nvmem, config);
+ if (rval)
+diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
+index 439ac5f5907a6..b492e67c3d871 100644
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
+
+ root = pci_find_parent_resource(dev, res);
+ if (!root) {
++ /*
++ * If dev is behind a bridge, accesses will only reach it
++ * if res is inside the relevant bridge window.
++ */
++ if (pci_upstream_bridge(dev))
++ return -ENXIO;
++
++ /*
++ * On the root bus, assume the host bridge will forward
++ * everything.
++ */
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ else
+diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
+index 8de4ca2fef210..8e6f217bfb635 100644
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -645,8 +645,11 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
+ struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node);
+ struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
+
+- /* Enable the access for TIME csr only from the user mode now */
+- csr_write(CSR_SCOUNTEREN, 0x2);
++ /*
++ * Enable the access for CYCLE, TIME, and INSTRET CSRs from userspace,
++ * as is necessary to maintain uABI compatibility.
++ */
++ csr_write(CSR_SCOUNTEREN, 0x7);
+
+ /* Stop all the counters so that they can be enabled from perf */
+ pmu_sbi_stop_all(pmu);
+diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
+index 1027ece6ca123..a3e1108b736d6 100644
+--- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
++++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
+@@ -197,7 +197,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
+ struct phy_provider *phy;
+ struct device *dev = &pdev->dev;
+ struct phy_axg_mipi_pcie_analog_priv *priv;
+- struct device_node *np = dev->of_node;
++ struct device_node *np = dev->of_node, *parent_np;
+ struct regmap *map;
+ int ret;
+
+@@ -206,7 +206,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ /* Get the hhi system controller node */
+- map = syscon_node_to_regmap(of_get_parent(dev->of_node));
++ parent_np = of_get_parent(dev->of_node);
++ map = syscon_node_to_regmap(parent_np);
++ of_node_put(parent_np);
+ if (IS_ERR(map)) {
+ dev_err(dev,
+ "failed to get HHI regmap\n");
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 8ee7682b8e93e..bdffc21858f6b 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -906,7 +906,7 @@ static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+ static int phy_type_set(struct mtk_phy_instance *instance)
+ {
+ int type;
+- u32 mask;
++ u32 offset;
+
+ if (!instance->type_sw)
+ return 0;
+@@ -929,8 +929,9 @@ static int phy_type_set(struct mtk_phy_instance *instance)
+ return 0;
+ }
+
+- mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+- regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
++ offset = instance->type_sw_index * BITS_PER_BYTE;
++ regmap_update_bits(instance->type_sw, instance->type_sw_reg,
++ RG_PHY_SW_TYPE << offset, type << offset);
+
+ return 0;
+ }
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+index 1d270356a97f6..1eb4ec576361d 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+@@ -2704,7 +2704,9 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ pm_runtime_set_active(dev);
+- pm_runtime_enable(dev);
++ ret = devm_pm_runtime_enable(dev);
++ if (ret)
++ return ret;
+ /*
+ * Prevent runtime pm from being ON by default. Users can enable
+ * it using power/control in sysfs.
+@@ -2738,13 +2740,10 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (!IS_ERR(phy_provider))
+ dev_info(dev, "Registered Qcom-QMP phy\n");
+- else
+- pm_runtime_disable(dev);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+
+ err_node_put:
+- pm_runtime_disable(dev);
+ of_node_put(child);
+ return ret;
+ }
+diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+index 716a77748ed83..20f6dd37c7c10 100644
+--- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
++++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+@@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+
+ /* Configure pins for HSIC functionality */
+ pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+- if (IS_ERR(pins_default))
+- return PTR_ERR(pins_default);
++ if (IS_ERR(pins_default)) {
++ ret = PTR_ERR(pins_default);
++ goto err_ulpi;
++ }
+
+ ret = pinctrl_select_state(uphy->pctl, pins_default);
+ if (ret)
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+index 0b1e9337ee8e2..e6ededc515239 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -1124,7 +1124,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ struct rockchip_usb2phy_port *rport,
+ struct device_node *child_np)
+ {
+- int ret;
++ int ret, id;
+
+ rport->port_id = USB2PHY_PORT_OTG;
+ rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
+@@ -1162,13 +1162,15 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+
+ ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
+ EXTCON_USB_HOST, &rport->event_nb);
+- if (ret)
++ if (ret) {
+ dev_err(rphy->dev, "register USB HOST notifier failed\n");
++ goto out;
++ }
+
+ if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
+ /* do initial sync of usb state */
+- ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
+- extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret);
++ id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
++ extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
+ }
+ }
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 32e41395fc768..c84bd0e1ce5a6 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -2393,11 +2393,24 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
+ return 0;
+ }
+
++static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
++ struct pinctrl_gpio_range *range,
++ unsigned offset,
++ bool input)
++{
++ struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
++ struct rockchip_pin_bank *bank;
++
++ bank = pin_to_bank(info, offset);
++ return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO);
++}
++
+ static const struct pinmux_ops rockchip_pmx_ops = {
+ .get_functions_count = rockchip_pmx_get_funcs_count,
+ .get_function_name = rockchip_pmx_get_func_name,
+ .get_function_groups = rockchip_pmx_get_groups,
+ .set_mux = rockchip_pmx_set,
++ .gpio_set_direction = rockchip_pmx_gpio_set_direction,
+ };
+
+ /*
+diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
+index 4e14b4d6635d7..a2cdbfbaeae6b 100644
+--- a/drivers/platform/chrome/chromeos_laptop.c
++++ b/drivers/platform/chrome/chromeos_laptop.c
+@@ -740,6 +740,7 @@ static int __init
+ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ const struct chromeos_laptop *src)
+ {
++ struct i2c_peripheral *i2c_peripherals;
+ struct i2c_peripheral *i2c_dev;
+ struct i2c_board_info *info;
+ int i;
+@@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ if (!src->num_i2c_peripherals)
+ return 0;
+
+- cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals,
+- src->num_i2c_peripherals *
+- sizeof(*src->i2c_peripherals),
+- GFP_KERNEL);
+- if (!cros_laptop->i2c_peripherals)
++ i2c_peripherals = kmemdup(src->i2c_peripherals,
++ src->num_i2c_peripherals *
++ sizeof(*src->i2c_peripherals),
++ GFP_KERNEL);
++ if (!i2c_peripherals)
+ return -ENOMEM;
+
+- cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
+-
+- for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) {
+- i2c_dev = &cros_laptop->i2c_peripherals[i];
++ for (i = 0; i < src->num_i2c_peripherals; i++) {
++ i2c_dev = &i2c_peripherals[i];
+ info = &i2c_dev->board_info;
+
+ error = chromeos_laptop_setup_irq(i2c_dev);
+@@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ }
+ }
+
++ cros_laptop->i2c_peripherals = i2c_peripherals;
++ cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
++
+ return 0;
+
+ err_out:
+ while (--i >= 0) {
+- i2c_dev = &cros_laptop->i2c_peripherals[i];
++ i2c_dev = &i2c_peripherals[i];
+ info = &i2c_dev->board_info;
+ if (!IS_ERR_OR_NULL(info->fwnode))
+ fwnode_remove_software_node(info->fwnode);
+ }
+- kfree(cros_laptop->i2c_peripherals);
++ kfree(i2c_peripherals);
+ return error;
+ }
+
+diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c
+index 8aace50d446d6..110df0fd4b003 100644
+--- a/drivers/platform/chrome/cros_ec.c
++++ b/drivers/platform/chrome/cros_ec.c
+@@ -349,10 +349,16 @@ EXPORT_SYMBOL(cros_ec_suspend);
+
+ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)
+ {
++ bool wake_event;
++
+ while (ec_dev->mkbp_event_supported &&
+- cros_ec_get_next_event(ec_dev, NULL, NULL) > 0)
++ cros_ec_get_next_event(ec_dev, &wake_event, NULL) > 0) {
+ blocking_notifier_call_chain(&ec_dev->event_notifier,
+ 1, ec_dev);
++
++ if (wake_event && device_may_wakeup(ec_dev->dev))
++ pm_wakeup_event(ec_dev->dev, 0);
++ }
+ }
+
+ /**
+diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c
+index fd33de546aee0..0de7c255254e0 100644
+--- a/drivers/platform/chrome/cros_ec_chardev.c
++++ b/drivers/platform/chrome/cros_ec_chardev.c
+@@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,
+ if (copy_from_user(&s_mem, arg, sizeof(s_mem)))
+ return -EFAULT;
+
++ if (s_mem.bytes > sizeof(s_mem.buffer))
++ return -EINVAL;
++
+ num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes,
+ s_mem.buffer);
+ if (num <= 0)
+diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
+index 05d2e8765a66b..475a6dd72db6b 100644
+--- a/drivers/platform/chrome/cros_ec_proto.c
++++ b/drivers/platform/chrome/cros_ec_proto.c
+@@ -773,6 +773,7 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
+ u8 event_type;
+ u32 host_event;
+ int ret;
++ u32 ver_mask;
+
+ /*
+ * Default value for wake_event.
+@@ -794,6 +795,37 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
+ return get_keyboard_state_event(ec_dev);
+
+ ret = get_next_event(ec_dev);
++ /*
++ * -ENOPROTOOPT is returned when EC returns EC_RES_INVALID_VERSION.
++ * This can occur when EC based device (e.g. Fingerprint MCU) jumps to
++ * the RO image which doesn't support newer version of the command. In
++ * this case we will attempt to update maximum supported version of the
++ * EC_CMD_GET_NEXT_EVENT.
++ */
++ if (ret == -ENOPROTOOPT) {
++ dev_dbg(ec_dev->dev,
++ "GET_NEXT_EVENT returned invalid version error.\n");
++ ret = cros_ec_get_host_command_version_mask(ec_dev,
++ EC_CMD_GET_NEXT_EVENT,
++ &ver_mask);
++ if (ret < 0 || ver_mask == 0)
++ /*
++ * Do not change the MKBP supported version if we can't
++ * obtain supported version correctly. Please note that
++ * calling EC_CMD_GET_NEXT_EVENT returned
++ * EC_RES_INVALID_VERSION which means that the command
++ * is present.
++ */
++ return -ENOPROTOOPT;
++
++ ec_dev->mkbp_event_supported = fls(ver_mask);
++ dev_dbg(ec_dev->dev, "MKBP support version changed to %u\n",
++ ec_dev->mkbp_event_supported - 1);
++
++ /* Try to get next event with new MKBP support version set. */
++ ret = get_next_event(ec_dev);
++ }
++
+ if (ret <= 0)
+ return ret;
+
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index de6ee0f926a66..dc5722db20661 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -25,7 +25,8 @@
+
+ #define DRV_NAME "cros-ec-typec"
+
+-#define DP_PORT_VDO (BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
++#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
++ DP_CAP_DFP_D)
+
+ /* Supported alt modes. */
+ enum {
+@@ -697,7 +698,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_
+ for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
+ memset(&desc, 0, sizeof(desc));
+ desc.svid = sop_disc->svids[i].svid;
+- desc.mode = j;
++ desc.mode = j + 1;
+ desc.vdo = sop_disc->svids[i].mode_vdo[j];
+
+ if (is_partner)
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index bc7020e9df9e8..fc8dbbd6fc7c2 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -177,7 +177,8 @@ enum hp_thermal_profile_omen_v1 {
+ enum hp_thermal_profile {
+ HP_THERMAL_PROFILE_PERFORMANCE = 0x00,
+ HP_THERMAL_PROFILE_DEFAULT = 0x01,
+- HP_THERMAL_PROFILE_COOL = 0x02
++ HP_THERMAL_PROFILE_COOL = 0x02,
++ HP_THERMAL_PROFILE_QUIET = 0x03,
+ };
+
+ #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
+@@ -1194,6 +1195,9 @@ static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof,
+ case HP_THERMAL_PROFILE_COOL:
+ *profile = PLATFORM_PROFILE_COOL;
+ break;
++ case HP_THERMAL_PROFILE_QUIET:
++ *profile = PLATFORM_PROFILE_QUIET;
++ break;
+ default:
+ return -EINVAL;
+ }
+@@ -1216,6 +1220,9 @@ static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof,
+ case PLATFORM_PROFILE_COOL:
+ tp = HP_THERMAL_PROFILE_COOL;
+ break;
++ case PLATFORM_PROFILE_QUIET:
++ tp = HP_THERMAL_PROFILE_QUIET;
++ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+@@ -1263,6 +1270,8 @@ static int thermal_profile_setup(void)
+
+ platform_profile_handler.profile_get = hp_wmi_platform_profile_get;
+ platform_profile_handler.profile_set = hp_wmi_platform_profile_set;
++
++ set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
+ }
+
+ set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
+diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
+index 24ffc8e2d2d1e..0e804b6c2d242 100644
+--- a/drivers/platform/x86/msi-laptop.c
++++ b/drivers/platform/x86/msi-laptop.c
+@@ -596,11 +596,10 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = {
+ {
+ .ident = "MSI S270",
+ .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
++ DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+- DMI_MATCH(DMI_CHASSIS_VENDOR,
+- "MICRO-STAR INT'L CO.,LTD")
++ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
+ },
+ .driver_data = &quirk_old_ec_model,
+ .callback = dmi_check_cb
+@@ -633,8 +632,7 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = {
+ DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+- DMI_MATCH(DMI_CHASSIS_VENDOR,
+- "MICRO-STAR INT'L CO.,LTD")
++ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
+ },
+ .driver_data = &quirk_old_ec_model,
+ .callback = dmi_check_cb
+@@ -1048,8 +1046,7 @@ static int __init msi_init(void)
+ return -EINVAL;
+
+ /* Register backlight stuff */
+-
+- if (quirks->old_ec_model ||
++ if (quirks->old_ec_model &&
+ acpi_video_get_backlight_type() == acpi_backlight_vendor) {
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+@@ -1117,6 +1114,8 @@ fail_create_attr:
+ fail_create_group:
+ if (quirks->load_scm_model) {
+ i8042_remove_filter(msi_laptop_i8042_filter);
++ cancel_delayed_work_sync(&msi_touchpad_dwork);
++ input_unregister_device(msi_laptop_input_dev);
+ cancel_delayed_work_sync(&msi_rfkill_dwork);
+ cancel_work_sync(&msi_rfkill_work);
+ rfkill_cleanup();
+@@ -1137,6 +1136,7 @@ static void __exit msi_cleanup(void)
+ {
+ if (quirks->load_scm_model) {
+ i8042_remove_filter(msi_laptop_i8042_filter);
++ cancel_delayed_work_sync(&msi_touchpad_dwork);
+ input_unregister_device(msi_laptop_input_dev);
+ cancel_delayed_work_sync(&msi_rfkill_dwork);
+ cancel_work_sync(&msi_rfkill_work);
+diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
+index 5c757c7f64dee..f4046572a9fe5 100644
+--- a/drivers/platform/x86/pmc_atom.c
++++ b/drivers/platform/x86/pmc_atom.c
+@@ -354,7 +354,7 @@ static bool pmc_clk_is_critical = true;
+
+ static int dmi_callback(const struct dmi_system_id *d)
+ {
+- pr_info("%s critclks quirk enabled\n", d->ident);
++ pr_info("%s: PMC critical clocks quirk enabled\n", d->ident);
+
+ return 1;
+ }
+diff --git a/drivers/power/supply/adp5061.c b/drivers/power/supply/adp5061.c
+index 003557043ab3a..daee1161c3059 100644
+--- a/drivers/power/supply/adp5061.c
++++ b/drivers/power/supply/adp5061.c
+@@ -427,11 +427,11 @@ static int adp5061_get_chg_type(struct adp5061_state *st,
+ if (ret < 0)
+ return ret;
+
+- chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)];
+- if (chg_type > ADP5061_CHG_FAST_CV)
++ chg_type = ADP5061_CHG_STATUS_1_CHG_STATUS(status1);
++ if (chg_type >= ARRAY_SIZE(adp5061_chg_type))
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ else
+- val->intval = chg_type;
++ val->intval = adp5061_chg_type[chg_type];
+
+ return ret;
+ }
+diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
+index 21d624f9f5fb2..33a3ca35cda07 100644
+--- a/drivers/powercap/intel_rapl_common.c
++++ b/drivers/powercap/intel_rapl_common.c
+@@ -994,6 +994,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
+ y = value & 0x1f;
+ value = (1 << y) * (4 + f) * rp->time_unit / 4;
+ } else {
++ if (value < rp->time_unit)
++ return 0;
++
+ do_div(value, rp->time_unit);
+ y = ilog2(value);
+ f = div64_u64(4 * (value - (1 << y)), 1 << y);
+@@ -1035,7 +1038,6 @@ static const struct rapl_defaults rapl_defaults_spr_server = {
+ .check_unit = rapl_check_unit_core,
+ .set_floor_freq = set_floor_freq_default,
+ .compute_time_window = rapl_compute_time_window_core,
+- .dram_domain_energy_unit = 15300,
+ .psys_domain_energy_unit = 1000000000,
+ .spr_psys_bits = true,
+ };
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index d3e8dc32832dd..c3871565fd7d2 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -2681,7 +2681,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
+ * return -ETIMEDOUT.
+ */
+ if (rdev->desc->poll_enabled_time) {
+- unsigned int time_remaining = delay;
++ int time_remaining = delay;
+
+ while (time_remaining > 0) {
+ _regulator_delay_helper(rdev->desc->poll_enabled_time);
+diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
+index 7f9d66ac37ff8..3c41b71a1f529 100644
+--- a/drivers/regulator/qcom_rpm-regulator.c
++++ b/drivers/regulator/qcom_rpm-regulator.c
+@@ -802,6 +802,12 @@ static const struct rpm_regulator_data rpm_pm8018_regulators[] = {
+ };
+
+ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
++ { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" },
++ { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" },
++ { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" },
++ { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" },
++ { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" },
++
+ { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" },
+ { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" },
+ { "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" },
+@@ -829,12 +835,6 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
+ { "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" },
+ { "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" },
+
+- { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" },
+- { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" },
+- { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" },
+- { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" },
+- { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" },
+-
+ { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
+ { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
+
+@@ -843,6 +843,12 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
+ };
+
+ static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
++ { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
++ { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
++ { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
++ { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
++ { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
++
+ { "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
+ { "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
+ { "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
+@@ -851,12 +857,6 @@ static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
+ { "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
+ { "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
+
+- { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
+- { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
+- { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
+- { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
+- { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
+-
+ { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
+ { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
+ { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index e5279ed9a8d7c..4fc5ce2187ac8 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -520,12 +520,13 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
+ struct fw_rsc_vdev *rsc = ptr;
+ struct device *dev = &rproc->dev;
+ struct rproc_vdev *rvdev;
++ size_t rsc_size;
+ int i, ret;
+ char name[16];
+
+ /* make sure resource isn't truncated */
+- if (struct_size(rsc, vring, rsc->num_of_vrings) + rsc->config_len >
+- avail) {
++ rsc_size = struct_size(rsc, vring, rsc->num_of_vrings);
++ if (size_add(rsc_size, rsc->config_len) > avail) {
+ dev_err(dev, "vdev rsc is truncated\n");
+ return -EINVAL;
+ }
+diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
+index 4f2189111494a..0408ce58183c1 100644
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -76,7 +76,9 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
+
+ mutex_lock(&eptdev->ept_lock);
+ if (eptdev->ept) {
+- rpmsg_destroy_ept(eptdev->ept);
++ /* The default endpoint is released by the rpmsg core */
++ if (!eptdev->default_ept)
++ rpmsg_destroy_ept(eptdev->ept);
+ eptdev->ept = NULL;
+ }
+ mutex_unlock(&eptdev->ept_lock);
+diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
+index cd823ff5deab2..6cb9cca9565b9 100644
+--- a/drivers/scsi/3w-9xxx.c
++++ b/drivers/scsi/3w-9xxx.c
+@@ -2006,7 +2006,7 @@ static int twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
+- goto out_disable_device;
++ return -ENODEV;
+ }
+
+ pci_set_master(pdev);
+diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
+index 29b1bd755afec..5fb1f364e8155 100644
+--- a/drivers/scsi/iscsi_tcp.c
++++ b/drivers/scsi/iscsi_tcp.c
+@@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
+ INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work);
+ tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q;
+
++ mutex_init(&tcp_sw_conn->sock_lock);
++
+ tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm))
+ goto free_conn;
+@@ -629,11 +631,15 @@ free_conn:
+
+ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
+ {
+- struct iscsi_session *session = conn->session;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+ struct socket *sock = tcp_sw_conn->sock;
+
++ /*
++ * The iscsi transport class will make sure we are not called in
++ * parallel with start, stop, bind and destroys. However, this can be
++ * called twice if userspace does a stop then a destroy.
++ */
+ if (!sock)
+ return;
+
+@@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
+
+ iscsi_suspend_rx(conn);
+
+- spin_lock_bh(&session->frwd_lock);
++ mutex_lock(&tcp_sw_conn->sock_lock);
+ tcp_sw_conn->sock = NULL;
+- spin_unlock_bh(&session->frwd_lock);
++ mutex_unlock(&tcp_sw_conn->sock_lock);
+ sockfd_put(sock);
+ }
+
+@@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
+ struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
+ int is_leading)
+ {
+- struct iscsi_session *session = cls_session->dd_data;
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+@@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
+ if (err)
+ goto free_socket;
+
+- spin_lock_bh(&session->frwd_lock);
++ mutex_lock(&tcp_sw_conn->sock_lock);
+ /* bind iSCSI connection and socket */
+ tcp_sw_conn->sock = sock;
+- spin_unlock_bh(&session->frwd_lock);
++ mutex_unlock(&tcp_sw_conn->sock_lock);
+
+ /* setup Socket parameters */
+ sk = sock->sk;
+@@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
+ break;
+ case ISCSI_PARAM_DATADGST_EN:
+ iscsi_set_param(cls_conn, param, buf, buflen);
++
++ mutex_lock(&tcp_sw_conn->sock_lock);
++ if (!tcp_sw_conn->sock) {
++ mutex_unlock(&tcp_sw_conn->sock_lock);
++ return -ENOTCONN;
++ }
+ tcp_sw_conn->sendpage = conn->datadgst_en ?
+ sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
++ mutex_unlock(&tcp_sw_conn->sock_lock);
+ break;
+ case ISCSI_PARAM_MAX_R2T:
+ return iscsi_tcp_set_max_r2t(conn, buf);
+@@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
+ enum iscsi_param param, char *buf)
+ {
+ struct iscsi_conn *conn = cls_conn->dd_data;
+- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+- struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
++ struct iscsi_sw_tcp_conn *tcp_sw_conn;
++ struct iscsi_tcp_conn *tcp_conn;
+ struct sockaddr_in6 addr;
+ struct socket *sock;
+ int rc;
+@@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
+ case ISCSI_PARAM_CONN_ADDRESS:
+ case ISCSI_PARAM_LOCAL_PORT:
+ spin_lock_bh(&conn->session->frwd_lock);
+- if (!tcp_sw_conn || !tcp_sw_conn->sock) {
++ if (!conn->session->leadconn) {
+ spin_unlock_bh(&conn->session->frwd_lock);
+ return -ENOTCONN;
+ }
+- sock = tcp_sw_conn->sock;
+- sock_hold(sock->sk);
++ /*
++ * The conn has been setup and bound, so just grab a ref
++ * incase a destroy runs while we are in the net layer.
++ */
++ iscsi_get_conn(conn->cls_conn);
+ spin_unlock_bh(&conn->session->frwd_lock);
+
++ tcp_conn = conn->dd_data;
++ tcp_sw_conn = tcp_conn->dd_data;
++
++ mutex_lock(&tcp_sw_conn->sock_lock);
++ sock = tcp_sw_conn->sock;
++ if (!sock) {
++ rc = -ENOTCONN;
++ goto sock_unlock;
++ }
++
+ if (param == ISCSI_PARAM_LOCAL_PORT)
+ rc = kernel_getsockname(sock,
+ (struct sockaddr *)&addr);
+ else
+ rc = kernel_getpeername(sock,
+ (struct sockaddr *)&addr);
+- sock_put(sock->sk);
++sock_unlock:
++ mutex_unlock(&tcp_sw_conn->sock_lock);
++ iscsi_put_conn(conn->cls_conn);
+ if (rc < 0)
+ return rc;
+
+@@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
+ }
+ tcp_conn = conn->dd_data;
+ tcp_sw_conn = tcp_conn->dd_data;
+- sock = tcp_sw_conn->sock;
+- if (!sock) {
+- spin_unlock_bh(&session->frwd_lock);
+- return -ENOTCONN;
+- }
+- sock_hold(sock->sk);
++ /*
++ * The conn has been setup and bound, so just grab a ref
++ * incase a destroy runs while we are in the net layer.
++ */
++ iscsi_get_conn(conn->cls_conn);
+ spin_unlock_bh(&session->frwd_lock);
+
+- rc = kernel_getsockname(sock,
+- (struct sockaddr *)&addr);
+- sock_put(sock->sk);
++ mutex_lock(&tcp_sw_conn->sock_lock);
++ sock = tcp_sw_conn->sock;
++ if (!sock)
++ rc = -ENOTCONN;
++ else
++ rc = kernel_getsockname(sock, (struct sockaddr *)&addr);
++ mutex_unlock(&tcp_sw_conn->sock_lock);
++ iscsi_put_conn(conn->cls_conn);
+ if (rc < 0)
+ return rc;
+
+diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
+index 850a018aefb9b..68e14a344904f 100644
+--- a/drivers/scsi/iscsi_tcp.h
++++ b/drivers/scsi/iscsi_tcp.h
+@@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send {
+
+ struct iscsi_sw_tcp_conn {
+ struct socket *sock;
++ /* Taken when accessing the sock from the netlink/sysfs interface */
++ struct mutex sock_lock;
++
+ struct work_struct recvwork;
+ bool queue_recv;
+
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index fa2209080cc26..5ce2518301040 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -67,7 +67,7 @@ static int smp_execute_task_sg(struct domain_device *dev,
+ res = i->dft->lldd_execute_task(task, GFP_KERNEL);
+
+ if (res) {
+- del_timer(&task->slow_task->timer);
++ del_timer_sync(&task->slow_task->timer);
+ pr_notice("executing SMP task failed:%d\n", res);
+ break;
+ }
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index e6a083d098a1a..11a05f2c88c44 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -1570,10 +1570,7 @@ struct lpfc_hba {
+ u32 cgn_acqe_cnt;
+
+ /* RX monitor handling for CMF */
+- struct rxtable_entry *rxtable; /* RX_monitor information */
+- atomic_t rxtable_idx_head;
+-#define LPFC_RXMONITOR_TABLE_IN_USE (LPFC_MAX_RXMONITOR_ENTRY + 73)
+- atomic_t rxtable_idx_tail;
++ struct lpfc_rx_info_monitor *rx_monitor;
+ atomic_t rx_max_read_cnt; /* Maximum read bytes */
+ uint64_t rx_block_cnt;
+
+@@ -1622,7 +1619,7 @@ struct lpfc_hba {
+
+ #define LPFC_MAX_RXMONITOR_ENTRY 800
+ #define LPFC_MAX_RXMONITOR_DUMP 32
+-struct rxtable_entry {
++struct rx_info_entry {
+ uint64_t cmf_bytes; /* Total no of read bytes for CMF_SYNC_WQE */
+ uint64_t total_bytes; /* Total no of read bytes requested */
+ uint64_t rcv_bytes; /* Total no of read bytes completed */
+@@ -1637,6 +1634,13 @@ struct rxtable_entry {
+ uint32_t timer_interval;
+ };
+
++struct lpfc_rx_info_monitor {
++ struct rx_info_entry *ring; /* info organized in a circular buffer */
++ u32 head_idx, tail_idx; /* index to head/tail of ring */
++ spinlock_t lock; /* spinlock for ring */
++ u32 entries; /* storing number entries/size of ring */
++};
++
+ static inline struct Scsi_Host *
+ lpfc_shost_from_vport(struct lpfc_vport *vport)
+ {
+diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
+index bcad912043282..c8cac90240b9b 100644
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -92,6 +92,14 @@ void lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba);
+ void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag);
+ void lpfc_unblock_requests(struct lpfc_hba *phba);
+ void lpfc_block_requests(struct lpfc_hba *phba);
++int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
++ u32 entries);
++void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor);
++void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
++ struct rx_info_entry *entry);
++u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
++ struct lpfc_rx_info_monitor *rx_monitor, char *buf,
++ u32 buf_len, u32 max_read_entries);
+
+ void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
+ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
+index 13dfe285493d1..b555ccb5ae345 100644
+--- a/drivers/scsi/lpfc/lpfc_ct.c
++++ b/drivers/scsi/lpfc/lpfc_ct.c
+@@ -1509,7 +1509,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ struct lpfc_sli_ct_request *CTrsp;
+ int did;
+ struct lpfc_nodelist *ndlp = NULL;
+- struct lpfc_nodelist *ns_ndlp = NULL;
++ struct lpfc_nodelist *ns_ndlp = cmdiocb->ndlp;
+ uint32_t fc4_data_0, fc4_data_1;
+ u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+ u32 ulp_word4 = get_job_word4(phba, rspiocb);
+@@ -1522,15 +1522,12 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ ulp_status, ulp_word4, did);
+
+ /* Ignore response if link flipped after this request was made */
+- if ((uint32_t) cmdiocb->event_tag != phba->fc_eventTag) {
++ if ((uint32_t)cmdiocb->event_tag != phba->fc_eventTag) {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "9046 Event tag mismatch. Ignoring NS rsp\n");
+ goto out;
+ }
+
+- /* Preserve the nameserver node to release the reference. */
+- ns_ndlp = cmdiocb->ndlp;
+-
+ if (ulp_status == IOSTAT_SUCCESS) {
+ /* Good status, continue checking */
+ CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index 5037ea09a8104..f5252e45a48a2 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -5156,7 +5156,7 @@ error_out:
+ static int
+ lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
+ {
+- uint16_t ext_cnt, ext_size;
++ uint16_t ext_cnt = 0, ext_size = 0;
+
+ len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
+ "\nAvailable Extents Information:\n");
+@@ -5531,7 +5531,7 @@ lpfc_rx_monitor_open(struct inode *inode, struct file *file)
+ if (!debug)
+ goto out;
+
+- debug->buffer = vmalloc(MAX_DEBUGFS_RX_TABLE_SIZE);
++ debug->buffer = vmalloc(MAX_DEBUGFS_RX_INFO_SIZE);
+ if (!debug->buffer) {
+ kfree(debug);
+ goto out;
+@@ -5552,57 +5552,18 @@ lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes,
+ struct lpfc_rx_monitor_debug *debug = file->private_data;
+ struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
+ char *buffer = debug->buffer;
+- struct rxtable_entry *entry;
+- int i, len = 0, head, tail, last, start;
+-
+- head = atomic_read(&phba->rxtable_idx_head);
+- while (head == LPFC_RXMONITOR_TABLE_IN_USE) {
+- /* Table is getting updated */
+- msleep(20);
+- head = atomic_read(&phba->rxtable_idx_head);
+- }
+
+- tail = atomic_xchg(&phba->rxtable_idx_tail, head);
+- if (!phba->rxtable || head == tail) {
+- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+- "Rxtable is empty\n");
+- goto out;
+- }
+- last = (head > tail) ? head : LPFC_MAX_RXMONITOR_ENTRY;
+- start = tail;
+-
+- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+- " MaxBPI Tot_Data_CMF Tot_Data_Cmd "
+- "Tot_Data_Cmpl Lat(us) Avg_IO Max_IO "
+- "Bsy IO_cnt Info BWutil(ms)\n");
+-get_table:
+- for (i = start; i < last; i++) {
+- entry = &phba->rxtable[i];
+- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+- "%3d:%12lld %12lld %12lld %12lld "
+- "%7lldus %8lld %7lld "
+- "%2d %4d %2d %2d(%2d)\n",
+- i, entry->max_bytes_per_interval,
+- entry->cmf_bytes,
+- entry->total_bytes,
+- entry->rcv_bytes,
+- entry->avg_io_latency,
+- entry->avg_io_size,
+- entry->max_read_cnt,
+- entry->cmf_busy,
+- entry->io_cnt,
+- entry->cmf_info,
+- entry->timer_utilization,
+- entry->timer_interval);
++ if (!phba->rx_monitor) {
++ scnprintf(buffer, MAX_DEBUGFS_RX_INFO_SIZE,
++ "Rx Monitor Info is empty.\n");
++ } else {
++ lpfc_rx_monitor_report(phba, phba->rx_monitor, buffer,
++ MAX_DEBUGFS_RX_INFO_SIZE,
++ LPFC_MAX_RXMONITOR_ENTRY);
+ }
+
+- if (head != last) {
+- start = 0;
+- last = head;
+- goto get_table;
+- }
+-out:
+- return simple_read_from_buffer(buf, nbytes, ppos, buffer, len);
++ return simple_read_from_buffer(buf, nbytes, ppos, buffer,
++ strlen(buffer));
+ }
+
+ static int
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
+index 6dd361c1fd318..f71e5b6311ac0 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.h
++++ b/drivers/scsi/lpfc/lpfc_debugfs.h
+@@ -282,7 +282,7 @@ struct lpfc_idiag {
+ void *ptr_private;
+ };
+
+-#define MAX_DEBUGFS_RX_TABLE_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY)
++#define MAX_DEBUGFS_RX_INFO_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY)
+ struct lpfc_rx_monitor_debug {
+ char *i_private;
+ char *buffer;
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
+index 2645def612e6d..a488d00894aee 100644
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -2964,7 +2964,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+ uint32_t boot_flag, addr_mode;
+ uint16_t next_fcf_index, fcf_index;
+ uint16_t current_fcf_index;
+- uint16_t vlan_id;
++ uint16_t vlan_id = LPFC_FCOE_NULL_VID;
+ int rc;
+
+ /* If link state is not up, stop the roundrobin failover process */
+@@ -3069,7 +3069,7 @@ lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+ struct fcf_record *new_fcf_record;
+ uint32_t boot_flag, addr_mode;
+ uint16_t fcf_index, next_fcf_index;
+- uint16_t vlan_id;
++ uint16_t vlan_id = LPFC_FCOE_NULL_VID;
+ int rc;
+
+ /* If link state is not up, no need to proceed */
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 55a1ad6eed034..1a02134438fcc 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -325,8 +325,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+ prog_id_word = pmboxq->u.mb.un.varWords[7];
+
+ /* Decode the Option rom version word to a readable string */
+- if (prg->dist < 4)
+- dist = dist_char[prg->dist];
++ dist = dist_char[prg->dist];
+
+ if ((prg->dist == 3) && (prg->num == 0))
+ snprintf(phba->OptionROMVersion, 32, "%d.%d%d",
+@@ -2258,6 +2257,101 @@ lpfc_handle_latt_err_exit:
+ return;
+ }
+
++static void
++lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex)
++{
++ int i, j;
++
++ while (length > 0) {
++ /* Look for Serial Number */
++ if ((vpd[*pindex] == 'S') && (vpd[*pindex + 1] == 'N')) {
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ j = 0;
++ length -= (3+i);
++ while (i--) {
++ phba->SerialNumber[j++] = vpd[(*pindex)++];
++ if (j == 31)
++ break;
++ }
++ phba->SerialNumber[j] = 0;
++ continue;
++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '1')) {
++ phba->vpd_flag |= VPD_MODEL_DESC;
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ j = 0;
++ length -= (3+i);
++ while (i--) {
++ phba->ModelDesc[j++] = vpd[(*pindex)++];
++ if (j == 255)
++ break;
++ }
++ phba->ModelDesc[j] = 0;
++ continue;
++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '2')) {
++ phba->vpd_flag |= VPD_MODEL_NAME;
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ j = 0;
++ length -= (3+i);
++ while (i--) {
++ phba->ModelName[j++] = vpd[(*pindex)++];
++ if (j == 79)
++ break;
++ }
++ phba->ModelName[j] = 0;
++ continue;
++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '3')) {
++ phba->vpd_flag |= VPD_PROGRAM_TYPE;
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ j = 0;
++ length -= (3+i);
++ while (i--) {
++ phba->ProgramType[j++] = vpd[(*pindex)++];
++ if (j == 255)
++ break;
++ }
++ phba->ProgramType[j] = 0;
++ continue;
++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '4')) {
++ phba->vpd_flag |= VPD_PORT;
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ j = 0;
++ length -= (3 + i);
++ while (i--) {
++ if ((phba->sli_rev == LPFC_SLI_REV4) &&
++ (phba->sli4_hba.pport_name_sta ==
++ LPFC_SLI4_PPNAME_GET)) {
++ j++;
++ (*pindex)++;
++ } else
++ phba->Port[j++] = vpd[(*pindex)++];
++ if (j == 19)
++ break;
++ }
++ if ((phba->sli_rev != LPFC_SLI_REV4) ||
++ (phba->sli4_hba.pport_name_sta ==
++ LPFC_SLI4_PPNAME_NON))
++ phba->Port[j] = 0;
++ continue;
++ } else {
++ *pindex += 2;
++ i = vpd[*pindex];
++ *pindex += 1;
++ *pindex += i;
++ length -= (3 + i);
++ }
++ }
++}
++
+ /**
+ * lpfc_parse_vpd - Parse VPD (Vital Product Data)
+ * @phba: pointer to lpfc hba data structure.
+@@ -2277,7 +2371,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
+ {
+ uint8_t lenlo, lenhi;
+ int Length;
+- int i, j;
++ int i;
+ int finished = 0;
+ int index = 0;
+
+@@ -2310,101 +2404,10 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
+ Length = ((((unsigned short)lenhi) << 8) + lenlo);
+ if (Length > len - index)
+ Length = len - index;
+- while (Length > 0) {
+- /* Look for Serial Number */
+- if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- j = 0;
+- Length -= (3+i);
+- while(i--) {
+- phba->SerialNumber[j++] = vpd[index++];
+- if (j == 31)
+- break;
+- }
+- phba->SerialNumber[j] = 0;
+- continue;
+- }
+- else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) {
+- phba->vpd_flag |= VPD_MODEL_DESC;
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- j = 0;
+- Length -= (3+i);
+- while(i--) {
+- phba->ModelDesc[j++] = vpd[index++];
+- if (j == 255)
+- break;
+- }
+- phba->ModelDesc[j] = 0;
+- continue;
+- }
+- else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) {
+- phba->vpd_flag |= VPD_MODEL_NAME;
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- j = 0;
+- Length -= (3+i);
+- while(i--) {
+- phba->ModelName[j++] = vpd[index++];
+- if (j == 79)
+- break;
+- }
+- phba->ModelName[j] = 0;
+- continue;
+- }
+- else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) {
+- phba->vpd_flag |= VPD_PROGRAM_TYPE;
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- j = 0;
+- Length -= (3+i);
+- while(i--) {
+- phba->ProgramType[j++] = vpd[index++];
+- if (j == 255)
+- break;
+- }
+- phba->ProgramType[j] = 0;
+- continue;
+- }
+- else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) {
+- phba->vpd_flag |= VPD_PORT;
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- j = 0;
+- Length -= (3+i);
+- while(i--) {
+- if ((phba->sli_rev == LPFC_SLI_REV4) &&
+- (phba->sli4_hba.pport_name_sta ==
+- LPFC_SLI4_PPNAME_GET)) {
+- j++;
+- index++;
+- } else
+- phba->Port[j++] = vpd[index++];
+- if (j == 19)
+- break;
+- }
+- if ((phba->sli_rev != LPFC_SLI_REV4) ||
+- (phba->sli4_hba.pport_name_sta ==
+- LPFC_SLI4_PPNAME_NON))
+- phba->Port[j] = 0;
+- continue;
+- }
+- else {
+- index += 2;
+- i = vpd[index];
+- index += 1;
+- index += i;
+- Length -= (3 + i);
+- }
+- }
+- finished = 0;
+- break;
++
++ lpfc_fill_vpd(phba, vpd, Length, &index);
++ finished = 0;
++ break;
+ case 0x78:
+ finished = 1;
+ break;
+@@ -5569,38 +5572,12 @@ lpfc_async_link_speed_to_read_top(struct lpfc_hba *phba, uint8_t speed_code)
+ void
+ lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba)
+ {
+- struct rxtable_entry *entry;
+- int cnt = 0, head, tail, last, start;
+-
+- head = atomic_read(&phba->rxtable_idx_head);
+- tail = atomic_read(&phba->rxtable_idx_tail);
+- if (!phba->rxtable || head == tail) {
+- lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
+- "4411 Rxtable is empty\n");
+- return;
+- }
+- last = tail;
+- start = head;
+-
+- /* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */
+- while (start != last) {
+- if (start)
+- start--;
+- else
+- start = LPFC_MAX_RXMONITOR_ENTRY - 1;
+- entry = &phba->rxtable[start];
++ if (!phba->rx_monitor) {
+ lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
+- "4410 %02d: MBPI %lld Xmit %lld Cmpl %lld "
+- "Lat %lld ASz %lld Info %02d BWUtil %d "
+- "Int %d slot %d\n",
+- cnt, entry->max_bytes_per_interval,
+- entry->total_bytes, entry->rcv_bytes,
+- entry->avg_io_latency, entry->avg_io_size,
+- entry->cmf_info, entry->timer_utilization,
+- entry->timer_interval, start);
+- cnt++;
+- if (cnt >= LPFC_MAX_RXMONITOR_DUMP)
+- return;
++ "4411 Rx Monitor Info is empty.\n");
++ } else {
++ lpfc_rx_monitor_report(phba, phba->rx_monitor, NULL, 0,
++ LPFC_MAX_RXMONITOR_DUMP);
+ }
+ }
+
+@@ -6007,9 +5984,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
+ {
+ struct lpfc_hba *phba = container_of(timer, struct lpfc_hba,
+ cmf_timer);
+- struct rxtable_entry *entry;
++ struct rx_info_entry entry;
+ uint32_t io_cnt;
+- uint32_t head, tail;
+ uint32_t busy, max_read;
+ uint64_t total, rcv, lat, mbpi, extra, cnt;
+ int timer_interval = LPFC_CMF_INTERVAL;
+@@ -6129,40 +6105,30 @@ lpfc_cmf_timer(struct hrtimer *timer)
+ }
+
+ /* Save rxmonitor information for debug */
+- if (phba->rxtable) {
+- head = atomic_xchg(&phba->rxtable_idx_head,
+- LPFC_RXMONITOR_TABLE_IN_USE);
+- entry = &phba->rxtable[head];
+- entry->total_bytes = total;
+- entry->cmf_bytes = total + extra;
+- entry->rcv_bytes = rcv;
+- entry->cmf_busy = busy;
+- entry->cmf_info = phba->cmf_active_info;
++ if (phba->rx_monitor) {
++ entry.total_bytes = total;
++ entry.cmf_bytes = total + extra;
++ entry.rcv_bytes = rcv;
++ entry.cmf_busy = busy;
++ entry.cmf_info = phba->cmf_active_info;
+ if (io_cnt) {
+- entry->avg_io_latency = div_u64(lat, io_cnt);
+- entry->avg_io_size = div_u64(rcv, io_cnt);
++ entry.avg_io_latency = div_u64(lat, io_cnt);
++ entry.avg_io_size = div_u64(rcv, io_cnt);
+ } else {
+- entry->avg_io_latency = 0;
+- entry->avg_io_size = 0;
++ entry.avg_io_latency = 0;
++ entry.avg_io_size = 0;
+ }
+- entry->max_read_cnt = max_read;
+- entry->io_cnt = io_cnt;
+- entry->max_bytes_per_interval = mbpi;
++ entry.max_read_cnt = max_read;
++ entry.io_cnt = io_cnt;
++ entry.max_bytes_per_interval = mbpi;
+ if (phba->cmf_active_mode == LPFC_CFG_MANAGED)
+- entry->timer_utilization = phba->cmf_last_ts;
++ entry.timer_utilization = phba->cmf_last_ts;
+ else
+- entry->timer_utilization = ms;
+- entry->timer_interval = ms;
++ entry.timer_utilization = ms;
++ entry.timer_interval = ms;
+ phba->cmf_last_ts = 0;
+
+- /* Increment rxtable index */
+- head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY;
+- tail = atomic_read(&phba->rxtable_idx_tail);
+- if (head == tail) {
+- tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY;
+- atomic_set(&phba->rxtable_idx_tail, tail);
+- }
+- atomic_set(&phba->rxtable_idx_head, head);
++ lpfc_rx_monitor_record(phba->rx_monitor, &entry);
+ }
+
+ if (phba->cmf_active_mode == LPFC_CFG_MONITOR) {
+@@ -8315,8 +8281,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ &phba->pcidev->dev,
+ phba->cfg_sg_dma_buf_size,
+ i, 0);
+- if (!phba->lpfc_sg_dma_buf_pool)
++ if (!phba->lpfc_sg_dma_buf_pool) {
++ rc = -ENOMEM;
+ goto out_free_bsmbx;
++ }
+
+ phba->lpfc_cmd_rsp_buf_pool =
+ dma_pool_create("lpfc_cmd_rsp_buf_pool",
+@@ -8324,8 +8292,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ sizeof(struct fcp_cmnd) +
+ sizeof(struct fcp_rsp),
+ i, 0);
+- if (!phba->lpfc_cmd_rsp_buf_pool)
++ if (!phba->lpfc_cmd_rsp_buf_pool) {
++ rc = -ENOMEM;
+ goto out_free_sg_dma_buf;
++ }
+
+ mempool_free(mboxq, phba->mbox_mem_pool);
+
+@@ -12416,7 +12386,7 @@ lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba)
+
+ for (i = 0; i < phba->cfg_irq_chann; i++) {
+ eqhdl = lpfc_get_eq_hdl(i);
+- eqhdl->irq = LPFC_VECTOR_MAP_EMPTY;
++ eqhdl->irq = LPFC_IRQ_EMPTY;
+ eqhdl->phba = phba;
+ }
+ }
+@@ -12789,7 +12759,7 @@ static void __lpfc_cpuhp_remove(struct lpfc_hba *phba)
+
+ static void lpfc_cpuhp_remove(struct lpfc_hba *phba)
+ {
+- if (phba->pport->fc_flag & FC_OFFLINE_MODE)
++ if (phba->pport && (phba->pport->fc_flag & FC_OFFLINE_MODE))
+ return;
+
+ __lpfc_cpuhp_remove(phba);
+@@ -13053,9 +13023,17 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
+ LPFC_DRIVER_HANDLER_NAME"%d", index);
+
+ eqhdl->idx = index;
+- rc = request_irq(pci_irq_vector(phba->pcidev, index),
+- &lpfc_sli4_hba_intr_handler, 0,
+- name, eqhdl);
++ rc = pci_irq_vector(phba->pcidev, index);
++ if (rc < 0) {
++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++ "0489 MSI-X fast-path (%d) "
++ "pci_irq_vec failed (%d)\n", index, rc);
++ goto cfg_fail_out;
++ }
++ eqhdl->irq = rc;
++
++ rc = request_irq(eqhdl->irq, &lpfc_sli4_hba_intr_handler, 0,
++ name, eqhdl);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+ "0486 MSI-X fast-path (%d) "
+@@ -13063,8 +13041,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
+ goto cfg_fail_out;
+ }
+
+- eqhdl->irq = pci_irq_vector(phba->pcidev, index);
+-
+ if (aff_mask) {
+ /* If found a neighboring online cpu, set affinity */
+ if (cpu_select < nr_cpu_ids)
+@@ -13181,7 +13157,14 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
+ }
+
+ eqhdl = lpfc_get_eq_hdl(0);
+- eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
++ rc = pci_irq_vector(phba->pcidev, 0);
++ if (rc < 0) {
++ pci_free_irq_vectors(phba->pcidev);
++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++ "0496 MSI pci_irq_vec failed (%d)\n", rc);
++ return rc;
++ }
++ eqhdl->irq = rc;
+
+ cpu = cpumask_first(cpu_present_mask);
+ lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu);
+@@ -13208,8 +13191,8 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
+ * MSI-X -> MSI -> IRQ.
+ *
+ * Return codes
+- * 0 - successful
+- * other values - error
++ * Interrupt mode (2, 1, 0) - successful
++ * LPFC_INTR_ERROR - error
+ **/
+ static uint32_t
+ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
+@@ -13254,7 +13237,14 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
+ intr_mode = 0;
+
+ eqhdl = lpfc_get_eq_hdl(0);
+- eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
++ retval = pci_irq_vector(phba->pcidev, 0);
++ if (retval < 0) {
++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++ "0502 INTR pci_irq_vec failed (%d)\n",
++ retval);
++ return LPFC_INTR_ERROR;
++ }
++ eqhdl->irq = retval;
+
+ cpu = cpumask_first(cpu_present_mask);
+ lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ,
+diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
+index 870e53b8f81dd..5d36b35148646 100644
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -344,9 +344,12 @@ lpfc_mem_free_all(struct lpfc_hba *phba)
+ phba->cgn_i = NULL;
+ }
+
+- /* Free RX table */
+- kfree(phba->rxtable);
+- phba->rxtable = NULL;
++ /* Free RX Monitor */
++ if (phba->rx_monitor) {
++ lpfc_rx_monitor_destroy_ring(phba->rx_monitor);
++ kfree(phba->rx_monitor);
++ phba->rx_monitor = NULL;
++ }
+
+ /* Free the iocb lookup array */
+ kfree(psli->iocbq_lookup);
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 608016725db99..03c21167fc854 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -6202,6 +6202,9 @@ lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type,
+ struct lpfc_mbx_get_rsrc_extent_info *rsrc_info;
+ LPFC_MBOXQ_t *mbox;
+
++ *extnt_count = 0;
++ *extnt_size = 0;
++
+ mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mbox)
+ return -ENOMEM;
+@@ -7959,6 +7962,172 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
+ }
+ }
+
++/**
++ * lpfc_rx_monitor_create_ring - Initialize ring buffer for rx_monitor
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @entries: Number of rx_info_entry objects to allocate in ring
++ *
++ * Return:
++ * 0 - Success
++ * ENOMEM - Failure to kmalloc
++ **/
++int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
++ u32 entries)
++{
++ rx_monitor->ring = kmalloc_array(entries, sizeof(struct rx_info_entry),
++ GFP_KERNEL);
++ if (!rx_monitor->ring)
++ return -ENOMEM;
++
++ rx_monitor->head_idx = 0;
++ rx_monitor->tail_idx = 0;
++ spin_lock_init(&rx_monitor->lock);
++ rx_monitor->entries = entries;
++
++ return 0;
++}
++
++/**
++ * lpfc_rx_monitor_destroy_ring - Free ring buffer for rx_monitor
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ **/
++void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor)
++{
++ spin_lock(&rx_monitor->lock);
++ kfree(rx_monitor->ring);
++ rx_monitor->ring = NULL;
++ rx_monitor->entries = 0;
++ rx_monitor->head_idx = 0;
++ rx_monitor->tail_idx = 0;
++ spin_unlock(&rx_monitor->lock);
++}
++
++/**
++ * lpfc_rx_monitor_record - Insert an entry into rx_monitor's ring
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @entry: Pointer to rx_info_entry
++ *
++ * Used to insert an rx_info_entry into rx_monitor's ring. Note that this is a
++ * deep copy of rx_info_entry not a shallow copy of the rx_info_entry ptr.
++ *
++ * This is called from lpfc_cmf_timer, which is in timer/softirq context.
++ *
++ * In cases of old data overflow, we do a best effort of FIFO order.
++ **/
++void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
++ struct rx_info_entry *entry)
++{
++ struct rx_info_entry *ring = rx_monitor->ring;
++ u32 *head_idx = &rx_monitor->head_idx;
++ u32 *tail_idx = &rx_monitor->tail_idx;
++ spinlock_t *ring_lock = &rx_monitor->lock;
++ u32 ring_size = rx_monitor->entries;
++
++ spin_lock(ring_lock);
++ memcpy(&ring[*tail_idx], entry, sizeof(*entry));
++ *tail_idx = (*tail_idx + 1) % ring_size;
++
++ /* Best effort of FIFO saved data */
++ if (*tail_idx == *head_idx)
++ *head_idx = (*head_idx + 1) % ring_size;
++
++ spin_unlock(ring_lock);
++}
++
++/**
++ * lpfc_rx_monitor_report - Read out rx_monitor's ring
++ * @phba: Pointer to lpfc_hba object
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @buf: Pointer to char buffer that will contain rx monitor info data
++ * @buf_len: Length buf including null char
++ * @max_read_entries: Maximum number of entries to read out of ring
++ *
++ * Used to dump/read what's in rx_monitor's ring buffer.
++ *
++ * If buf is NULL || buf_len == 0, then it is implied that we want to log the
++ * information to kmsg instead of filling out buf.
++ *
++ * Return:
++ * Number of entries read out of the ring
++ **/
++u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
++ struct lpfc_rx_info_monitor *rx_monitor, char *buf,
++ u32 buf_len, u32 max_read_entries)
++{
++ struct rx_info_entry *ring = rx_monitor->ring;
++ struct rx_info_entry *entry;
++ u32 *head_idx = &rx_monitor->head_idx;
++ u32 *tail_idx = &rx_monitor->tail_idx;
++ spinlock_t *ring_lock = &rx_monitor->lock;
++ u32 ring_size = rx_monitor->entries;
++ u32 cnt = 0;
++ char tmp[DBG_LOG_STR_SZ] = {0};
++ bool log_to_kmsg = (!buf || !buf_len) ? true : false;
++
++ if (!log_to_kmsg) {
++ /* clear the buffer to be sure */
++ memset(buf, 0, buf_len);
++
++ scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s"
++ "%-8s%-8s%-8s%-16s\n",
++ "MaxBPI", "Tot_Data_CMF",
++ "Tot_Data_Cmd", "Tot_Data_Cmpl",
++ "Lat(us)", "Avg_IO", "Max_IO", "Bsy",
++ "IO_cnt", "Info", "BWutil(ms)");
++ }
++
++ /* Needs to be _bh because record is called from timer interrupt
++ * context
++ */
++ spin_lock_bh(ring_lock);
++ while (*head_idx != *tail_idx) {
++ entry = &ring[*head_idx];
++
++ /* Read out this entry's data. */
++ if (!log_to_kmsg) {
++ /* If !log_to_kmsg, then store to buf. */
++ scnprintf(tmp, sizeof(tmp),
++ "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu"
++ "%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
++ *head_idx, entry->max_bytes_per_interval,
++ entry->cmf_bytes, entry->total_bytes,
++ entry->rcv_bytes, entry->avg_io_latency,
++ entry->avg_io_size, entry->max_read_cnt,
++ entry->cmf_busy, entry->io_cnt,
++ entry->cmf_info, entry->timer_utilization,
++ entry->timer_interval);
++
++ /* Check for buffer overflow */
++ if ((strlen(buf) + strlen(tmp)) >= buf_len)
++ break;
++
++ /* Append entry's data to buffer */
++ strlcat(buf, tmp, buf_len);
++ } else {
++ lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
++ "4410 %02u: MBPI %llu Xmit %llu "
++ "Cmpl %llu Lat %llu ASz %llu Info %02u "
++ "BWUtil %u Int %u slot %u\n",
++ cnt, entry->max_bytes_per_interval,
++ entry->total_bytes, entry->rcv_bytes,
++ entry->avg_io_latency,
++ entry->avg_io_size, entry->cmf_info,
++ entry->timer_utilization,
++ entry->timer_interval, *head_idx);
++ }
++
++ *head_idx = (*head_idx + 1) % ring_size;
++
++ /* Don't feed more than max_read_entries */
++ cnt++;
++ if (cnt >= max_read_entries)
++ break;
++ }
++ spin_unlock_bh(ring_lock);
++
++ return cnt;
++}
++
+ /**
+ * lpfc_cmf_setup - Initialize idle_stat tracking
+ * @phba: Pointer to HBA context object.
+@@ -8133,19 +8302,29 @@ no_cmf:
+ phba->cmf_interval_rate = LPFC_CMF_INTERVAL;
+
+ /* Allocate RX Monitor Buffer */
+- if (!phba->rxtable) {
+- phba->rxtable = kmalloc_array(LPFC_MAX_RXMONITOR_ENTRY,
+- sizeof(struct rxtable_entry),
+- GFP_KERNEL);
+- if (!phba->rxtable) {
++ if (!phba->rx_monitor) {
++ phba->rx_monitor = kzalloc(sizeof(*phba->rx_monitor),
++ GFP_KERNEL);
++
++ if (!phba->rx_monitor) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2644 Failed to alloc memory "
+ "for RX Monitor Buffer\n");
+ return -ENOMEM;
+ }
++
++ /* Instruct the rx_monitor object to instantiate its ring */
++ if (lpfc_rx_monitor_create_ring(phba->rx_monitor,
++ LPFC_MAX_RXMONITOR_ENTRY)) {
++ kfree(phba->rx_monitor);
++ phba->rx_monitor = NULL;
++ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
++ "2645 Failed to alloc memory "
++ "for RX Monitor's Ring\n");
++ return -ENOMEM;
++ }
+ }
+- atomic_set(&phba->rxtable_idx_head, 0);
+- atomic_set(&phba->rxtable_idx_tail, 0);
++
+ return 0;
+ }
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
+index 1ddad5b170a60..cbb1aa1cf025b 100644
+--- a/drivers/scsi/lpfc/lpfc_sli4.h
++++ b/drivers/scsi/lpfc/lpfc_sli4.h
+@@ -489,7 +489,7 @@ struct lpfc_hba;
+ #define LPFC_SLI4_HANDLER_NAME_SZ 16
+ struct lpfc_hba_eq_hdl {
+ uint32_t idx;
+- uint16_t irq;
++ int irq;
+ char handler_name[LPFC_SLI4_HANDLER_NAME_SZ];
+ struct lpfc_hba *phba;
+ struct lpfc_queue *eq;
+@@ -611,6 +611,8 @@ struct lpfc_vector_map_info {
+ };
+ #define LPFC_VECTOR_MAP_EMPTY 0xffff
+
++#define LPFC_IRQ_EMPTY 0xffffffff
++
+ /* Multi-XRI pool */
+ #define XRI_BATCH 8
+
+diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c
+index f64ced04b9125..ed1d7f7b88a38 100644
+--- a/drivers/scsi/lpfc/lpfc_vmid.c
++++ b/drivers/scsi/lpfc/lpfc_vmid.c
+@@ -245,9 +245,7 @@ int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid,
+ /* allocate the per cpu variable for holding */
+ /* the last access time stamp only if VMID is enabled */
+ if (!vmp->last_io_time)
+- vmp->last_io_time = __alloc_percpu(sizeof(u64),
+- __alignof__(struct
+- lpfc_vmid));
++ vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC);
+ if (!vmp->last_io_time) {
+ hash_del(&vmp->hnode);
+ vmp->flag = LPFC_VMID_SLOT_FREE;
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index 91d78d0a38fe5..628b08ba6770b 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -3612,6 +3612,10 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+ pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n");
+ return -1;
+ }
++
++ if (t->task_proto == SAS_PROTOCOL_INTERNAL_ABORT)
++ atomic_dec(&pm8001_dev->running_req);
++
+ ts = &t->task_status;
+ if (status != 0)
+ pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index bbc4d5890ae6a..e045c6e250902 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -1921,6 +1921,27 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled)
+ fc_vport_setlink(vn_port);
+ }
+
++ /* Set symbolic node name */
++ if (base_qedf->pdev->device == QL45xxx)
++ snprintf(fc_host_symbolic_name(vn_port->host), 256,
++ "Marvell FastLinQ 45xxx FCoE v%s", QEDF_VERSION);
++
++ if (base_qedf->pdev->device == QL41xxx)
++ snprintf(fc_host_symbolic_name(vn_port->host), 256,
++ "Marvell FastLinQ 41xxx FCoE v%s", QEDF_VERSION);
++
++ /* Set supported speed */
++ fc_host_supported_speeds(vn_port->host) = n_port->link_supported_speeds;
++
++ /* Set speed */
++ vn_port->link_speed = n_port->link_speed;
++
++ /* Set port type */
++ fc_host_port_type(vn_port->host) = FC_PORTTYPE_NPIV;
++
++ /* Set maxframe size */
++ fc_host_maxframe_size(vn_port->host) = n_port->mfs;
++
+ QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_NPIV, "vn_port=%p.\n",
+ vn_port);
+
+diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
+index 0aa8408464add..d29a1a9cf12fa 100644
+--- a/drivers/slimbus/qcom-ngd-ctrl.c
++++ b/drivers/slimbus/qcom-ngd-ctrl.c
+@@ -1470,7 +1470,13 @@ static int of_qcom_slim_ngd_register(struct device *parent,
+ ngd->pdev->dev.of_node = node;
+ ctrl->ngd = ngd;
+
+- platform_device_add(ngd->pdev);
++ ret = platform_device_add(ngd->pdev);
++ if (ret) {
++ platform_device_put(ngd->pdev);
++ kfree(ngd);
++ of_node_put(node);
++ return ret;
++ }
+ ngd->base = ctrl->base + ngd->id * data->offset +
+ (ngd->id - 1) * data->size;
+
+@@ -1576,17 +1582,27 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
+ ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl);
+ if (IS_ERR(ctrl->pdr)) {
+ dev_err(dev, "Failed to init PDR handle\n");
+- return PTR_ERR(ctrl->pdr);
++ ret = PTR_ERR(ctrl->pdr);
++ goto err_pdr_alloc;
+ }
+
+ pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd");
+ if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
++ ret = PTR_ERR(pds);
+ dev_err(dev, "pdr add lookup failed: %d\n", ret);
+- return PTR_ERR(pds);
++ goto err_pdr_lookup;
+ }
+
+ platform_driver_register(&qcom_slim_ngd_driver);
+ return of_qcom_slim_ngd_register(dev, ctrl);
++
++err_pdr_alloc:
++ qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
++
++err_pdr_lookup:
++ pdr_handle_release(ctrl->pdr);
++
++ return ret;
+ }
+
+ static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev)
+diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c
+index 31faf4aa868e6..e848cc9a3cf80 100644
+--- a/drivers/soc/qcom/smem_state.c
++++ b/drivers/soc/qcom/smem_state.c
+@@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref)
+ struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount);
+
+ list_del(&state->list);
++ of_node_put(state->of_node);
+ kfree(state);
+ }
+
+@@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node,
+
+ kref_init(&state->refcount);
+
+- state->of_node = of_node;
++ state->of_node = of_node_get(of_node);
+ state->ops = *ops;
+ state->priv = priv;
+
+diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
+index 9df9bba242f3e..3e8994d6110e6 100644
+--- a/drivers/soc/qcom/smsm.c
++++ b/drivers/soc/qcom/smsm.c
+@@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ for (id = 0; id < smsm->num_hosts; id++) {
+ ret = smsm_parse_ipc(smsm, id);
+ if (ret < 0)
+- return ret;
++ goto out_put;
+ }
+
+ /* Acquire the main SMSM state vector */
+@@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ smsm->num_entries * sizeof(u32));
+ if (ret < 0 && ret != -EEXIST) {
+ dev_err(&pdev->dev, "unable to allocate shared state entry\n");
+- return ret;
++ goto out_put;
+ }
+
+ states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL);
+ if (IS_ERR(states)) {
+ dev_err(&pdev->dev, "Unable to acquire shared state entry\n");
+- return PTR_ERR(states);
++ ret = PTR_ERR(states);
++ goto out_put;
+ }
+
+ /* Acquire the list of interrupt mask vectors */
+@@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size);
+ if (ret < 0 && ret != -EEXIST) {
+ dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n");
+- return ret;
++ goto out_put;
+ }
+
+ intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL);
+ if (IS_ERR(intr_mask)) {
+ dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n");
+- return PTR_ERR(intr_mask);
++ ret = PTR_ERR(intr_mask);
++ goto out_put;
+ }
+
+ /* Setup the reference to the local state bits */
+@@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm);
+ if (IS_ERR(smsm->state)) {
+ dev_err(smsm->dev, "failed to register qcom_smem_state\n");
+- return PTR_ERR(smsm->state);
++ ret = PTR_ERR(smsm->state);
++ goto out_put;
+ }
+
+ /* Register handlers for remote processor entries of interest. */
+@@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ }
+
+ platform_set_drvdata(pdev, smsm);
++ of_node_put(local_node);
+
+ return 0;
+
+ unwind_interfaces:
++ of_node_put(node);
+ for (id = 0; id < smsm->num_entries; id++)
+ if (smsm->entries[id].domain)
+ irq_domain_remove(smsm->entries[id].domain);
+
+ qcom_smem_state_unregister(smsm->state);
+-
++out_put:
++ of_node_put(local_node);
+ return ret;
+ }
+
+diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
+index 5725c8ef0406a..6f601227da3cb 100644
+--- a/drivers/soc/tegra/Kconfig
++++ b/drivers/soc/tegra/Kconfig
+@@ -136,7 +136,6 @@ config SOC_TEGRA_FUSE
+ def_bool y
+ depends on ARCH_TEGRA
+ select SOC_BUS
+- select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC
+
+ config SOC_TEGRA_FLOWCTRL
+ bool
+diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
+index b0a8405dbdb19..6542267a224d2 100644
+--- a/drivers/soc/tegra/fuse/fuse-tegra.c
++++ b/drivers/soc/tegra/fuse/fuse-tegra.c
+@@ -568,6 +568,7 @@ static int __init tegra_init_fuse(void)
+ np = of_find_matching_node(NULL, car_match);
+ if (np) {
+ void __iomem *base = of_iomap(np, 0);
++ of_node_put(np);
+ if (base) {
+ tegra_enable_fuse_clk(base);
+ iounmap(base);
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index 4fbb19557f5ed..42c5fae80efbf 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -544,9 +544,12 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns,
+ return SDW_CMD_IGNORED;
+ }
+
+- /* fill response */
+- for (i = 0; i < count; i++)
+- msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
++ if (msg->flags == SDW_MSG_FLAG_READ) {
++ /* fill response */
++ for (i = 0; i < count; i++)
++ msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA,
++ cdns->response_buf[i]);
++ }
+
+ return SDW_CMD_OK;
+ }
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index 89d1d0d021fc7..af6c1a93372d9 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -1429,7 +1429,6 @@ int intel_link_startup(struct auxiliary_device *auxdev)
+ ret = intel_register_dai(sdw);
+ if (ret) {
+ dev_err(dev, "DAI registration failed: %d\n", ret);
+- snd_soc_unregister_component(dev);
+ goto err_interrupt;
+ }
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index e12ab5b43f341..4472305479452 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1645,7 +1645,7 @@ static int cqspi_probe(struct platform_device *pdev)
+ pm_runtime_enable(dev);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+- return ret;
++ goto probe_pm_failed;
+
+ ret = clk_prepare_enable(cqspi->clk);
+ if (ret) {
+@@ -1740,6 +1740,7 @@ probe_reset_failed:
+ clk_disable_unprepare(cqspi->clk);
+ probe_clk_failed:
+ pm_runtime_put_sync(dev);
++probe_pm_failed:
+ pm_runtime_disable(dev);
+ return ret;
+ }
+diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c
+index c065534161237..3fb89dee595e7 100644
+--- a/drivers/spi/spi-dw-bt1.c
++++ b/drivers/spi/spi-dw-bt1.c
+@@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+
+ ret = dw_spi_add_host(&pdev->dev, dws);
+- if (ret)
++ if (ret) {
++ pm_runtime_disable(&pdev->dev);
+ goto err_disable_clk;
++ }
+
+ platform_set_drvdata(pdev, dwsbt1);
+
+diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
+index e4cb52e1fe261..6974a1c947aad 100644
+--- a/drivers/spi/spi-meson-spicc.c
++++ b/drivers/spi/spi-meson-spicc.c
+@@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+- if (!spicc->master->cur_msg || !spicc->master->busy)
++ if (!spicc->master->cur_msg)
+ return 0;
+
+ return clk_divider_ops.recalc_rate(hw, parent_rate);
+@@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+- if (!spicc->master->cur_msg || !spicc->master->busy)
++ if (!spicc->master->cur_msg)
+ return -EINVAL;
+
+ return clk_divider_ops.determine_rate(hw, req);
+@@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+- if (!spicc->master->cur_msg || !spicc->master->busy)
++ if (!spicc->master->cur_msg)
+ return -EINVAL;
+
+ return clk_divider_ops.set_rate(hw, rate, parent_rate);
+diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c
+index b4b9b7309b5e9..351b0ef52bbc8 100644
+--- a/drivers/spi/spi-mt7621.c
++++ b/drivers/spi/spi-mt7621.c
+@@ -340,11 +340,9 @@ static int mt7621_spi_probe(struct platform_device *pdev)
+ return PTR_ERR(base);
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+- if (IS_ERR(clk)) {
+- dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
+- status);
+- return PTR_ERR(clk);
+- }
++ if (IS_ERR(clk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(clk),
++ "unable to get SYS clock\n");
+
+ status = clk_prepare_enable(clk);
+ if (status)
+diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
+index 20b0471729651..061f7394e5b9b 100644
+--- a/drivers/spi/spi-omap-100k.c
++++ b/drivers/spi/spi-omap-100k.c
+@@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
+ return status;
+
+ err_fck:
++ pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(spi100k->fck);
+ err_ick:
+ clk_disable_unprepare(spi100k->ick);
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 00d6084306b4a..7d89510dc3f00 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1198,8 +1198,10 @@ static int spi_qup_pm_resume_runtime(struct device *device)
+ return ret;
+
+ ret = clk_prepare_enable(controller->cclk);
+- if (ret)
++ if (ret) {
++ clk_disable_unprepare(controller->iclk);
+ return ret;
++ }
+
+ /* Disable clocks auto gaiting */
+ config = readl_relaxed(controller->base + QUP_CONFIG);
+@@ -1245,14 +1247,25 @@ static int spi_qup_resume(struct device *device)
+ return ret;
+
+ ret = clk_prepare_enable(controller->cclk);
+- if (ret)
++ if (ret) {
++ clk_disable_unprepare(controller->iclk);
+ return ret;
++ }
+
+ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+ if (ret)
+- return ret;
++ goto disable_clk;
+
+- return spi_master_resume(master);
++ ret = spi_master_resume(master);
++ if (ret)
++ goto disable_clk;
++
++ return 0;
++
++disable_clk:
++ clk_disable_unprepare(controller->cclk);
++ clk_disable_unprepare(controller->iclk);
++ return ret;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 7f346866614ab..7c22b5c410ce0 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -84,6 +84,7 @@
+ #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)
+
+ #define S3C64XX_SPI_PACKET_CNT_EN (1<<16)
++#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0)
+
+ #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)
+ #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
+@@ -711,6 +712,13 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master,
+ return 0;
+ }
+
++static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi)
++{
++ struct spi_controller *ctlr = spi->controller;
++
++ return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX;
++}
++
+ static int s3c64xx_spi_transfer_one(struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *xfer)
+@@ -1152,6 +1160,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
+ master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
+ master->prepare_message = s3c64xx_spi_prepare_message;
+ master->transfer_one = s3c64xx_spi_transfer_one;
++ master->max_transfer_size = s3c64xx_spi_max_transfer_size;
+ master->num_chipselect = sci->num_cs;
+ master->use_gpio_descriptors = true;
+ master->dma_alignment = 8;
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 32c01e684af3d..4b42f2302a8a8 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -1097,6 +1097,8 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev,
+ if (sgt->orig_nents) {
+ dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir);
+ sg_free_table(sgt);
++ sgt->orig_nents = 0;
++ sgt->nents = 0;
+ }
+ }
+
+diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
+index 2113be40b5a97..58f580e7aacc5 100644
+--- a/drivers/spmi/spmi-pmic-arb.c
++++ b/drivers/spmi/spmi-pmic-arb.c
+@@ -992,7 +992,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+ * version 5, there is more than one APID mapped to each PPID.
+ * The owner field for each of these mappings specifies the EE which is
+ * allowed to write to the APID. The owner of the last (highest) APID
+- * for a given PPID will receive interrupts from the PPID.
++ * which has the IRQ owner bit set for a given PPID will receive
++ * interrupts from the PPID.
+ */
+ for (i = 0; ; i++, apidd++) {
+ offset = pmic_arb->ver_ops->apid_map_offset(i);
+@@ -1015,16 +1016,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+ apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+ prev_apidd = &pmic_arb->apid_data[apid];
+
+- if (valid && is_irq_ee &&
+- prev_apidd->write_ee == pmic_arb->ee) {
++ if (!valid || apidd->write_ee == pmic_arb->ee) {
++ /* First PPID mapping or one for this EE */
++ pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
++ } else if (valid && is_irq_ee &&
++ prev_apidd->write_ee == pmic_arb->ee) {
+ /*
+ * Duplicate PPID mapping after the one for this EE;
+ * override the irq owner
+ */
+ prev_apidd->irq_ee = apidd->irq_ee;
+- } else if (!valid || is_irq_ee) {
+- /* First PPID mapping or duplicate for another EE */
+- pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+ }
+
+ apidd->ppid = ppid;
+diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c
+index 05e91e6bc2a08..223987616e074 100644
+--- a/drivers/staging/greybus/audio_helper.c
++++ b/drivers/staging/greybus/audio_helper.c
+@@ -3,7 +3,6 @@
+ * Greybus Audio Sound SoC helper APIs
+ */
+
+-#include <linux/debugfs.h>
+ #include <sound/core.h>
+ #include <sound/soc.h>
+ #include <sound/soc-dapm.h>
+@@ -116,10 +115,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
+ {
+ int i;
+ struct snd_soc_dapm_widget *w, *tmp_w;
+-#ifdef CONFIG_DEBUG_FS
+- struct dentry *parent = dapm->debugfs_dapm;
+- struct dentry *debugfs_w = NULL;
+-#endif
+
+ mutex_lock(&dapm->card->dapm_mutex);
+ for (i = 0; i < num; i++) {
+@@ -139,12 +134,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
+ continue;
+ }
+ widget++;
+-#ifdef CONFIG_DEBUG_FS
+- if (!parent)
+- debugfs_w = debugfs_lookup(w->name, parent);
+- debugfs_remove(debugfs_w);
+- debugfs_w = NULL;
+-#endif
+ gbaudio_dapm_free_widget(w);
+ }
+ mutex_unlock(&dapm->card->dapm_mutex);
+diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c
+index 9530e580e57a2..afced435c9070 100644
+--- a/drivers/staging/media/meson/vdec/vdec_hevc.c
++++ b/drivers/staging/media/meson/vdec/vdec_hevc.c
+@@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess)
+
+ clk_set_rate(core->vdec_hevc_clk, 666666666);
+ ret = clk_prepare_enable(core->vdec_hevc_clk);
+- if (ret)
++ if (ret) {
++ if (core->platform->revision == VDEC_REVISION_G12A ||
++ core->platform->revision == VDEC_REVISION_SM1)
++ clk_disable_unprepare(core->vdec_hevcf_clk);
+ return ret;
++ }
+
+ if (core->platform->revision == VDEC_REVISION_SM1)
+ regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
+index 960a0130cd620..55c54dfdc585c 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
+@@ -448,6 +448,8 @@ static int cedrus_probe(struct platform_device *pdev)
+ if (!dev)
+ return -ENOMEM;
+
++ platform_set_drvdata(pdev, dev);
++
+ dev->vfd = cedrus_video_device;
+ dev->dev = &pdev->dev;
+ dev->pdev = pdev;
+@@ -521,8 +523,6 @@ static int cedrus_probe(struct platform_device *pdev)
+ goto err_m2m_mc;
+ }
+
+- platform_set_drvdata(pdev, dev);
+-
+ return 0;
+
+ err_m2m_mc:
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+index 3b6aa78a2985f..e7f7602a5ab40 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+@@ -106,11 +106,11 @@ void cedrus_device_run(void *priv)
+
+ /* Trigger decoding if setup went well, bail out otherwise. */
+ if (!error) {
+- dev->dec_ops[ctx->current_codec]->trigger(ctx);
+-
+ /* Start the watchdog timer. */
+ schedule_delayed_work(&dev->watchdog_work,
+ msecs_to_jiffies(2000));
++
++ dev->dec_ops[ctx->current_codec]->trigger(ctx);
+ } else {
+ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
+ ctx->fh.m2m_ctx,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 687f87598f780..095b8464f37a0 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -234,8 +234,9 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
+ cedrus_write(dev, VE_DEC_H265_TRIGGER,
+ VE_DEC_H265_TRIGGER_FLUSH_BITS |
+ VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp));
+- while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY)
+- udelay(1);
++
++ if (cedrus_wait_for(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_VLD_BUSY))
++ dev_err_ratelimited(dev->dev, "timed out waiting to skip bits\n");
+
+ count += tmp;
+ }
+diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+index b4170f64d1186..03c2c66dbf665 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
++++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+@@ -161,8 +161,6 @@ static struct cmd_hdl wlancmds[] = {
+
+ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
+ {
+- int res = 0;
+-
+ init_completion(&pcmdpriv->cmd_queue_comp);
+ init_completion(&pcmdpriv->terminate_cmdthread_comp);
+
+@@ -175,18 +173,16 @@ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
+
+ pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
+
+- if (!pcmdpriv->cmd_allocated_buf) {
+- res = -ENOMEM;
+- goto exit;
+- }
++ if (!pcmdpriv->cmd_allocated_buf)
++ return -ENOMEM;
+
+ pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
+
+ pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
+
+ if (!pcmdpriv->rsp_allocated_buf) {
+- res = -ENOMEM;
+- goto exit;
++ kfree(pcmdpriv->cmd_allocated_buf);
++ return -ENOMEM;
+ }
+
+ pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3);
+@@ -196,8 +192,8 @@ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
+ pcmdpriv->rsp_cnt = 0;
+
+ mutex_init(&pcmdpriv->sctx_mutex);
+-exit:
+- return res;
++
++ return 0;
+ }
+
+ static void c2h_wk_callback(struct work_struct *work);
+diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+index 380d8c9e1239e..68bba3c0e757a 100644
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -664,51 +664,36 @@ void rtw_reset_drv_sw(struct adapter *padapter)
+
+ u8 rtw_init_drv_sw(struct adapter *padapter)
+ {
+- u8 ret8 = _SUCCESS;
+-
+ rtw_init_default_value(padapter);
+
+ rtw_init_hal_com_default_value(padapter);
+
+- if (rtw_init_cmd_priv(&padapter->cmdpriv)) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (rtw_init_cmd_priv(&padapter->cmdpriv))
++ return _FAIL;
+
+ padapter->cmdpriv.padapter = padapter;
+
+- if (rtw_init_evt_priv(&padapter->evtpriv)) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (rtw_init_evt_priv(&padapter->evtpriv))
++ goto free_cmd_priv;
+
+-
+- if (rtw_init_mlme_priv(padapter) == _FAIL) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (rtw_init_mlme_priv(padapter) == _FAIL)
++ goto free_evt_priv;
+
+ init_mlme_ext_priv(padapter);
+
+- if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL)
++ goto free_mlme_ext;
+
+- if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL)
++ goto free_xmit_priv;
+ /* add for CONFIG_IEEE80211W, none 11w also can use */
+ spin_lock_init(&padapter->security_key_mutex);
+
+ /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
+ /* memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); */
+
+- if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) {
+- ret8 = _FAIL;
+- goto exit;
+- }
++ if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL)
++ goto free_recv_priv;
+
+ padapter->stapriv.padapter = padapter;
+ padapter->setband = GHZ24_50;
+@@ -719,9 +704,26 @@ u8 rtw_init_drv_sw(struct adapter *padapter)
+
+ rtw_hal_dm_init(padapter);
+
+-exit:
++ return _SUCCESS;
++
++free_recv_priv:
++ _rtw_free_recv_priv(&padapter->recvpriv);
++
++free_xmit_priv:
++ _rtw_free_xmit_priv(&padapter->xmitpriv);
++
++free_mlme_ext:
++ free_mlme_ext_priv(&padapter->mlmeextpriv);
+
+- return ret8;
++ rtw_free_mlme_priv(&padapter->mlmepriv);
++
++free_evt_priv:
++ rtw_free_evt_priv(&padapter->evtpriv);
++
++free_cmd_priv:
++ rtw_free_cmd_priv(&padapter->cmdpriv);
++
++ return _FAIL;
+ }
+
+ void rtw_cancel_all_timer(struct adapter *padapter)
+diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
+index bab08a40fe669..ec7c991e745b7 100644
+--- a/drivers/staging/vt6655/device_main.c
++++ b/drivers/staging/vt6655/device_main.c
+@@ -583,7 +583,7 @@ err_free_rd:
+ kfree(desc->rd_info);
+
+ err_free_desc:
+- while (--i) {
++ while (i--) {
+ desc = &priv->aRD0Ring[i];
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+@@ -629,7 +629,7 @@ err_free_rd:
+ kfree(desc->rd_info);
+
+ err_free_desc:
+- while (--i) {
++ while (i--) {
+ desc = &priv->aRD1Ring[i];
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+@@ -694,7 +694,7 @@ static int device_init_td0_ring(struct vnt_private *priv)
+ return 0;
+
+ err_free_desc:
+- while (--i) {
++ while (i--) {
+ desc = &priv->apTD0Rings[i];
+ kfree(desc->td_info);
+ }
+@@ -734,7 +734,7 @@ static int device_init_td1_ring(struct vnt_private *priv)
+ return 0;
+
+ err_free_desc:
+- while (--i) {
++ while (i--) {
+ desc = &priv->apTD1Rings[i];
+ kfree(desc->td_info);
+ }
+diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
+index b76293cc989c4..7838b6e2dba5c 100644
+--- a/drivers/thermal/cpufreq_cooling.c
++++ b/drivers/thermal/cpufreq_cooling.c
+@@ -501,17 +501,17 @@ __cpufreq_cooling_register(struct device_node *np,
+ struct thermal_cooling_device_ops *cooling_ops;
+ char *name;
+
++ if (IS_ERR_OR_NULL(policy)) {
++ pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
++ return ERR_PTR(-EINVAL);
++ }
++
+ dev = get_cpu_device(policy->cpu);
+ if (unlikely(!dev)) {
+ pr_warn("No cpu device for cpu %d\n", policy->cpu);
+ return ERR_PTR(-ENODEV);
+ }
+
+- if (IS_ERR_OR_NULL(policy)) {
+- pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
+- return ERR_PTR(-EINVAL);
+- }
+-
+ i = cpufreq_table_count_valid_entries(policy);
+ if (!i) {
+ pr_debug("%s: CPUFreq table not found or has no valid entries\n",
+diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
+index c841ab37e7c6d..46cd799af148d 100644
+--- a/drivers/thermal/intel/intel_powerclamp.c
++++ b/drivers/thermal/intel/intel_powerclamp.c
+@@ -532,8 +532,10 @@ static int start_power_clamp(void)
+
+ /* prefer BSP */
+ control_cpu = 0;
+- if (!cpu_online(control_cpu))
+- control_cpu = smp_processor_id();
++ if (!cpu_online(control_cpu)) {
++ control_cpu = get_cpu();
++ put_cpu();
++ }
+
+ clamping = true;
+ schedule_delayed_work(&poll_pkg_cstate_work, 0);
+diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
+index f136cb3502384..327f37202c69f 100644
+--- a/drivers/thermal/qcom/tsens-v0_1.c
++++ b/drivers/thermal/qcom/tsens-v0_1.c
+@@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = {
+ struct tsens_plat_data data_8939 = {
+ .num_sensors = 10,
+ .ops = &ops_8939,
+- .hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 },
++ .hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 },
+
+ .feat = &tsens_v0_1_feat,
+ .fields = tsens_v0_1_regfields,
+diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
+index cb8c9c4ae93a2..b5cd9673e15d3 100644
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -28,7 +28,11 @@
+ #define RING_TYPE(ring) ((ring)->is_tx ? "TX ring" : "RX ring")
+
+ #define RING_FIRST_USABLE_HOPID 1
+-
++/*
++ * Used with QUIRK_E2E to specify an unused HopID the Rx credits are
++ * transferred.
++ */
++#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID
+ /*
+ * Minimal number of vectors when we use MSI-X. Two for control channel
+ * Rx/Tx and the rest four are for cross domain DMA paths.
+@@ -38,7 +42,9 @@
+
+ #define NHI_MAILBOX_TIMEOUT 500 /* ms */
+
++/* Host interface quirks */
+ #define QUIRK_AUTO_CLEAR_INT BIT(0)
++#define QUIRK_E2E BIT(1)
+
+ static int ring_interrupt_index(struct tb_ring *ring)
+ {
+@@ -458,8 +464,18 @@ static void ring_release_msix(struct tb_ring *ring)
+
+ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ {
++ unsigned int start_hop = RING_FIRST_USABLE_HOPID;
+ int ret = 0;
+
++ if (nhi->quirks & QUIRK_E2E) {
++ start_hop = RING_FIRST_USABLE_HOPID + 1;
++ if (ring->flags & RING_FLAG_E2E && !ring->is_tx) {
++ dev_dbg(&nhi->pdev->dev, "quirking E2E TX HopID %u -> %u\n",
++ ring->e2e_tx_hop, RING_E2E_RESERVED_HOPID);
++ ring->e2e_tx_hop = RING_E2E_RESERVED_HOPID;
++ }
++ }
++
+ spin_lock_irq(&nhi->lock);
+
+ if (ring->hop < 0) {
+@@ -469,7 +485,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ * Automatically allocate HopID from the non-reserved
+ * range 1 .. hop_count - 1.
+ */
+- for (i = RING_FIRST_USABLE_HOPID; i < nhi->hop_count; i++) {
++ for (i = start_hop; i < nhi->hop_count; i++) {
+ if (ring->is_tx) {
+ if (!nhi->tx_rings[i]) {
+ ring->hop = i;
+@@ -484,6 +500,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ }
+ }
+
++ if (ring->hop > 0 && ring->hop < start_hop) {
++ dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
++ ret = -EINVAL;
++ goto err_unlock;
++ }
+ if (ring->hop < 0 || ring->hop >= nhi->hop_count) {
+ dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
+ ret = -EINVAL;
+@@ -1097,12 +1118,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)
+
+ static void nhi_check_quirks(struct tb_nhi *nhi)
+ {
+- /*
+- * Intel hardware supports auto clear of the interrupt status
+- * reqister right after interrupt is being issued.
+- */
+- if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL)
++ if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) {
++ /*
++ * Intel hardware supports auto clear of the interrupt
++ * status register right after interrupt is being
++ * issued.
++ */
+ nhi->quirks |= QUIRK_AUTO_CLEAR_INT;
++
++ switch (nhi->pdev->device) {
++ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
++ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
++ /*
++ * Falcon Ridge controller needs the end-to-end
++ * flow control workaround to avoid losing Rx
++ * packets when RING_FLAG_E2E is set.
++ */
++ nhi->quirks |= QUIRK_E2E;
++ break;
++ }
++ }
+ }
+
+ static int nhi_check_iommu_pdev(struct pci_dev *pdev, void *data)
+diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
+index 77d7f07ca075f..e7851c9265382 100644
+--- a/drivers/thunderbolt/switch.c
++++ b/drivers/thunderbolt/switch.c
+@@ -2822,6 +2822,26 @@ static void tb_switch_credits_init(struct tb_switch *sw)
+ tb_sw_info(sw, "failed to determine preferred buffer allocation, using defaults\n");
+ }
+
++static int tb_switch_port_hotplug_enable(struct tb_switch *sw)
++{
++ struct tb_port *port;
++
++ if (tb_switch_is_icm(sw))
++ return 0;
++
++ tb_switch_for_each_port(sw, port) {
++ int res;
++
++ if (!port->cap_usb4)
++ continue;
++
++ res = usb4_port_hotplug_enable(port);
++ if (res)
++ return res;
++ }
++ return 0;
++}
++
+ /**
+ * tb_switch_add() - Add a switch to the domain
+ * @sw: Switch to add
+@@ -2891,6 +2911,10 @@ int tb_switch_add(struct tb_switch *sw)
+ return ret;
+ }
+
++ ret = tb_switch_port_hotplug_enable(sw);
++ if (ret)
++ return ret;
++
+ ret = device_add(&sw->dev);
+ if (ret) {
+ dev_err(&sw->dev, "failed to add device: %d\n", ret);
+diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
+index 5db76de40cc1c..332159f984fc5 100644
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -1174,6 +1174,7 @@ int usb4_switch_add_ports(struct tb_switch *sw);
+ void usb4_switch_remove_ports(struct tb_switch *sw);
+
+ int usb4_port_unlock(struct tb_port *port);
++int usb4_port_hotplug_enable(struct tb_port *port);
+ int usb4_port_configure(struct tb_port *port);
+ void usb4_port_unconfigure(struct tb_port *port);
+ int usb4_port_configure_xdomain(struct tb_port *port);
+diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
+index 1660541103883..bbe38b2d9057c 100644
+--- a/drivers/thunderbolt/tb_regs.h
++++ b/drivers/thunderbolt/tb_regs.h
+@@ -308,6 +308,7 @@ struct tb_regs_port_header {
+ #define ADP_CS_5 0x05
+ #define ADP_CS_5_LCA_MASK GENMASK(28, 22)
+ #define ADP_CS_5_LCA_SHIFT 22
++#define ADP_CS_5_DHP BIT(31)
+
+ /* TMU adapter registers */
+ #define TMU_ADP_CS_3 0x03
+diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
+index 3a2e7126db9dc..f0b5a8f1ed3a3 100644
+--- a/drivers/thunderbolt/usb4.c
++++ b/drivers/thunderbolt/usb4.c
+@@ -1046,6 +1046,26 @@ int usb4_port_unlock(struct tb_port *port)
+ return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1);
+ }
+
++/**
++ * usb4_port_hotplug_enable() - Enables hotplug for a port
++ * @port: USB4 port to operate on
++ *
++ * Enables hot plug events on a given port. This is only intended
++ * to be used on lane, DP-IN, and DP-OUT adapters.
++ */
++int usb4_port_hotplug_enable(struct tb_port *port)
++{
++ int ret;
++ u32 val;
++
++ ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
++ if (ret)
++ return ret;
++
++ val &= ~ADP_CS_5_DHP;
++ return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
++}
++
+ static int usb4_port_set_configured(struct tb_port *port, bool configured)
+ {
+ int ret;
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 2e83e7367441c..94fbf0add2ce2 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -298,10 +298,9 @@ static void serial8250_backup_timeout(struct timer_list *t)
+ jiffies + uart_poll_timeout(&up->port) + HZ / 5);
+ }
+
+-static int univ8250_setup_irq(struct uart_8250_port *up)
++static void univ8250_setup_timer(struct uart_8250_port *up)
+ {
+ struct uart_port *port = &up->port;
+- int retval = 0;
+
+ /*
+ * The above check will only give an accurate result the first time
+@@ -322,10 +321,16 @@ static int univ8250_setup_irq(struct uart_8250_port *up)
+ */
+ if (!port->irq)
+ mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
+- else
+- retval = serial_link_irq_chain(up);
++}
+
+- return retval;
++static int univ8250_setup_irq(struct uart_8250_port *up)
++{
++ struct uart_port *port = &up->port;
++
++ if (port->irq)
++ return serial_link_irq_chain(up);
++
++ return 0;
+ }
+
+ static void univ8250_release_irq(struct uart_8250_port *up)
+@@ -381,6 +386,7 @@ static struct uart_ops univ8250_port_ops;
+ static const struct uart_8250_ops univ8250_driver_ops = {
+ .setup_irq = univ8250_setup_irq,
+ .release_irq = univ8250_release_irq,
++ .setup_timer = univ8250_setup_timer,
+ };
+
+ static struct uart_8250_port serial8250_ports[UART_NR];
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index f7fbef83583c8..38ee3e42251af 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -342,6 +342,9 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ omap8250_update_mdr1(up, priv);
+
+ up->port.ops->set_mctrl(&up->port, up->port.mctrl);
++
++ if (up->port.rs485.flags & SER_RS485_ENABLED)
++ serial8250_em485_stop_tx(up);
+ }
+
+ /*
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 6f66dc2ebacc7..8e9f247590bd4 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1232,6 +1232,10 @@ static void pci_oxsemi_tornado_set_mctrl(struct uart_port *port,
+ serial8250_do_set_mctrl(port, mctrl);
+ }
+
++/*
++ * We require EFR features for clock programming, so set UPF_FULL_PROBE
++ * for full probing regardless of CONFIG_SERIAL_8250_16550A_VARIANTS setting.
++ */
+ static int pci_oxsemi_tornado_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *up, int idx)
+@@ -1239,6 +1243,7 @@ static int pci_oxsemi_tornado_setup(struct serial_private *priv,
+ struct pci_dev *dev = priv->dev;
+
+ if (pci_oxsemi_tornado_p(dev)) {
++ up->port.flags |= UPF_FULL_PROBE;
+ up->port.get_divisor = pci_oxsemi_tornado_get_divisor;
+ up->port.set_divisor = pci_oxsemi_tornado_set_divisor;
+ up->port.set_mctrl = pci_oxsemi_tornado_set_mctrl;
+@@ -1627,7 +1632,6 @@ static int pci_fintek_init(struct pci_dev *dev)
+ resource_size_t bar_data[3];
+ u8 config_base;
+ struct serial_private *priv = pci_get_drvdata(dev);
+- struct uart_8250_port *port;
+
+ if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) ||
+ !(pci_resource_flags(dev, 4) & IORESOURCE_IO) ||
+@@ -1674,13 +1678,7 @@ static int pci_fintek_init(struct pci_dev *dev)
+
+ pci_write_config_byte(dev, config_base + 0x06, dev->irq);
+
+- if (priv) {
+- /* re-apply RS232/485 mode when
+- * pciserial_resume_ports()
+- */
+- port = serial8250_get_port(priv->line[i]);
+- uart_rs485_config(&port->port);
+- } else {
++ if (!priv) {
+ /* First init without port data
+ * force init to RS232 Mode
+ */
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 39b35a61958c0..2030a92ac66e7 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(serial8250_rpm_put);
+ static int serial8250_em485_init(struct uart_8250_port *p)
+ {
+ if (p->em485)
+- return 0;
++ goto deassert_rts;
+
+ p->em485 = kmalloc(sizeof(struct uart_8250_em485), GFP_ATOMIC);
+ if (!p->em485)
+@@ -616,7 +616,9 @@ static int serial8250_em485_init(struct uart_8250_port *p)
+ p->em485->active_timer = NULL;
+ p->em485->tx_stopped = true;
+
+- p->rs485_stop_tx(p);
++deassert_rts:
++ if (p->em485->tx_stopped)
++ p->rs485_stop_tx(p);
+
+ return 0;
+ }
+@@ -1021,7 +1023,8 @@ static void autoconfig_16550a(struct uart_8250_port *up)
+ up->port.type = PORT_16550A;
+ up->capabilities |= UART_CAP_FIFO;
+
+- if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS))
++ if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS) &&
++ !(up->port.flags & UPF_FULL_PROBE))
+ return;
+
+ /*
+@@ -2042,6 +2045,9 @@ EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
+
+ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
++ if (port->rs485.flags & SER_RS485_ENABLED)
++ return;
++
+ if (port->set_mctrl)
+ port->set_mctrl(port, mctrl);
+ else
+@@ -2294,6 +2300,10 @@ int serial8250_do_startup(struct uart_port *port)
+ if (port->irq && (up->port.flags & UPF_SHARE_IRQ))
+ up->port.irqflags |= IRQF_SHARED;
+
++ retval = up->ops->setup_irq(up);
++ if (retval)
++ goto out;
++
+ if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
+ unsigned char iir1;
+
+@@ -2336,9 +2346,7 @@ int serial8250_do_startup(struct uart_port *port)
+ }
+ }
+
+- retval = up->ops->setup_irq(up);
+- if (retval)
+- goto out;
++ up->ops->setup_timer(up);
+
+ /*
+ * Now, initialize the UART
+@@ -3187,9 +3195,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
+ if (flags & UART_CONFIG_TYPE)
+ autoconfig(up);
+
+- if (port->rs485.flags & SER_RS485_ENABLED)
+- uart_rs485_config(port);
+-
+ /* if access method is AU, it is a 16550 with a quirk */
+ if (port->type == PORT_16550A && port->iotype == UPIO_AU)
+ up->bugs |= UART_BUG_NOMSR;
+@@ -3314,8 +3319,13 @@ static void serial8250_console_restore(struct uart_8250_port *up)
+ unsigned int baud, quot, frac = 0;
+
+ termios.c_cflag = port->cons->cflag;
+- if (port->state->port.tty && termios.c_cflag == 0)
++ termios.c_ispeed = port->cons->ispeed;
++ termios.c_ospeed = port->cons->ospeed;
++ if (port->state->port.tty && termios.c_cflag == 0) {
+ termios.c_cflag = port->state->port.tty->termios.c_cflag;
++ termios.c_ispeed = port->state->port.tty->termios.c_ispeed;
++ termios.c_ospeed = port->state->port.tty->termios.c_ospeed;
++ }
+
+ baud = serial8250_get_baud_rate(port, &termios, NULL);
+ quot = serial8250_get_divisor(port, baud, &frac);
+diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
+index 32caeac129858..a4ce0b63aabdf 100644
+--- a/drivers/tty/serial/ar933x_uart.c
++++ b/drivers/tty/serial/ar933x_uart.c
+@@ -583,6 +583,13 @@ static const struct uart_ops ar933x_uart_ops = {
+ static int ar933x_config_rs485(struct uart_port *port, struct ktermios *termios,
+ struct serial_rs485 *rs485conf)
+ {
++ struct ar933x_uart_port *up =
++ container_of(port, struct ar933x_uart_port, port);
++
++ if (port->rs485.flags & SER_RS485_ENABLED)
++ gpiod_set_value(up->rts_gpiod,
++ !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
++
+ return 0;
+ }
+
+diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+index db07d6a5d764d..fa5c4633086e6 100644
+--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
++++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+@@ -1214,12 +1214,6 @@ static int cpm_uart_init_port(struct device_node *np,
+ pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
+ spin_lock_init(&pinfo->port.lock);
+
+- pinfo->port.irq = irq_of_parse_and_map(np, 0);
+- if (pinfo->port.irq == NO_IRQ) {
+- ret = -EINVAL;
+- goto out_pram;
+- }
+-
+ for (i = 0; i < NUM_GPIOS; i++) {
+ struct gpio_desc *gpiod;
+
+@@ -1229,7 +1223,7 @@ static int cpm_uart_init_port(struct device_node *np,
+
+ if (IS_ERR(gpiod)) {
+ ret = PTR_ERR(gpiod);
+- goto out_irq;
++ goto out_pram;
+ }
+
+ if (gpiod) {
+@@ -1255,8 +1249,6 @@ static int cpm_uart_init_port(struct device_node *np,
+
+ return cpm_uart_request_port(&pinfo->port);
+
+-out_irq:
+- irq_dispose_mapping(pinfo->port.irq);
+ out_pram:
+ cpm_uart_unmap_pram(pinfo, pram);
+ out_mem:
+@@ -1436,11 +1428,17 @@ static int cpm_uart_probe(struct platform_device *ofdev)
+ /* initialize the device pointer for the port */
+ pinfo->port.dev = &ofdev->dev;
+
++ pinfo->port.irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
++ if (!pinfo->port.irq)
++ return -EINVAL;
++
+ ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo);
+- if (ret)
+- return ret;
++ if (!ret)
++ return uart_add_one_port(&cpm_reg, &pinfo->port);
+
+- return uart_add_one_port(&cpm_reg, &pinfo->port);
++ irq_dispose_mapping(pinfo->port.irq);
++
++ return ret;
+ }
+
+ static int cpm_uart_remove(struct platform_device *ofdev)
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index fbc4b071b3309..34990901c805e 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1776,6 +1776,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
+ if (sport->lpuart_dma_rx_use) {
+ del_timer_sync(&sport->lpuart_timer);
+ lpuart_dma_rx_free(&sport->port);
++ sport->lpuart_dma_rx_use = false;
+ }
+
+ if (sport->lpuart_dma_tx_use) {
+@@ -1784,6 +1785,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
+ sport->dma_tx_in_progress = false;
+ dmaengine_terminate_all(sport->dma_tx_chan);
+ }
++ sport->lpuart_dma_tx_use = false;
+ }
+
+ if (sport->dma_tx_chan)
+@@ -2729,15 +2731,13 @@ static int lpuart_probe(struct platform_device *pdev)
+ if (ret)
+ goto failed_reset;
+
+- ret = uart_add_one_port(&lpuart_reg, &sport->port);
+- if (ret)
+- goto failed_attach_port;
+-
+ ret = uart_get_rs485_mode(&sport->port);
+ if (ret)
+ goto failed_get_rs485;
+
+- uart_rs485_config(&sport->port);
++ ret = uart_add_one_port(&lpuart_reg, &sport->port);
++ if (ret)
++ goto failed_attach_port;
+
+ ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
+ DRIVER_NAME, sport);
+@@ -2747,9 +2747,9 @@ static int lpuart_probe(struct platform_device *pdev)
+ return 0;
+
+ failed_irq_request:
+-failed_get_rs485:
+ uart_remove_one_port(&lpuart_reg, &sport->port);
+ failed_attach_port:
++failed_get_rs485:
+ failed_reset:
+ lpuart_disable_clks(sport);
+ return ret;
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 522445a8f666e..278b4033a3cce 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -380,8 +380,7 @@ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
+ {
+ *ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
+
+- sport->port.mctrl |= TIOCM_RTS;
+- mctrl_gpio_set(sport->gpios, sport->port.mctrl);
++ mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS);
+ }
+
+ /* called with port.lock taken and irqs caller dependent */
+@@ -390,8 +389,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
+ *ucr2 &= ~UCR2_CTSC;
+ *ucr2 |= UCR2_CTS;
+
+- sport->port.mctrl &= ~TIOCM_RTS;
+- mctrl_gpio_set(sport->gpios, sport->port.mctrl);
++ mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS);
+ }
+
+ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
+@@ -2347,8 +2345,6 @@ static int imx_uart_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev,
+ "low-active RTS not possible when receiver is off, enabling receiver\n");
+
+- uart_rs485_config(&sport->port);
+-
+ /* Disable interrupts before requesting them */
+ ucr1 = imx_uart_readl(sport, UCR1);
+ ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN);
+diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
+index 0ea799bf8dbb1..417a5b6bffc34 100644
+--- a/drivers/tty/serial/jsm/jsm_driver.c
++++ b/drivers/tty/serial/jsm/jsm_driver.c
+@@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ break;
+ default:
+- return -ENXIO;
++ rc = -ENXIO;
++ goto out_kfree_brd;
+ }
+
+ rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd);
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 12c87cd201a76..74b2784b8b5df 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -158,15 +158,10 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
+ unsigned long flags;
+ unsigned int old;
+
+- if (port->rs485.flags & SER_RS485_ENABLED) {
+- set &= ~TIOCM_RTS;
+- clear &= ~TIOCM_RTS;
+- }
+-
+ spin_lock_irqsave(&port->lock, flags);
+ old = port->mctrl;
+ port->mctrl = (old & ~clear) | set;
+- if (old != port->mctrl)
++ if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED))
+ port->ops->set_mctrl(port, port->mctrl);
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+@@ -1391,7 +1386,7 @@ static void uart_set_rs485_termination(struct uart_port *port,
+ !!(rs485->flags & SER_RS485_TERMINATE_BUS));
+ }
+
+-int uart_rs485_config(struct uart_port *port)
++static int uart_rs485_config(struct uart_port *port)
+ {
+ struct serial_rs485 *rs485 = &port->rs485;
+ int ret;
+@@ -1405,7 +1400,6 @@ int uart_rs485_config(struct uart_port *port)
+
+ return ret;
+ }
+-EXPORT_SYMBOL_GPL(uart_rs485_config);
+
+ static int uart_get_rs485_config(struct uart_port *port,
+ struct serial_rs485 __user *rs485)
+@@ -1444,8 +1438,13 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
+
+ spin_lock_irqsave(&port->lock, flags);
+ ret = port->rs485_config(port, &tty->termios, &rs485);
+- if (!ret)
++ if (!ret) {
+ port->rs485 = rs485;
++
++ /* Reset RTS and other mctrl lines when disabling RS485 */
++ if (!(rs485.flags & SER_RS485_ENABLED))
++ port->ops->set_mctrl(port, port->mctrl);
++ }
+ spin_unlock_irqrestore(&port->lock, flags);
+ if (ret)
+ return ret;
+@@ -2352,7 +2351,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
+
+ spin_lock_irq(&uport->lock);
+ ops->stop_tx(uport);
+- ops->set_mctrl(uport, 0);
++ if (!(uport->rs485.flags & SER_RS485_ENABLED))
++ ops->set_mctrl(uport, 0);
+ /* save mctrl so it can be restored on resume */
+ mctrl = uport->mctrl;
+ uport->mctrl = 0;
+@@ -2440,7 +2440,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
+
+ uart_change_pm(state, UART_PM_STATE_ON);
+ spin_lock_irq(&uport->lock);
+- ops->set_mctrl(uport, 0);
++ if (!(uport->rs485.flags & SER_RS485_ENABLED))
++ ops->set_mctrl(uport, 0);
+ spin_unlock_irq(&uport->lock);
+ if (console_suspend_enabled || !uart_console(uport)) {
+ /* Protected by port mutex for now */
+@@ -2451,7 +2452,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
+ if (tty)
+ uart_change_speed(tty, state, NULL);
+ spin_lock_irq(&uport->lock);
+- ops->set_mctrl(uport, uport->mctrl);
++ if (!(uport->rs485.flags & SER_RS485_ENABLED))
++ ops->set_mctrl(uport, uport->mctrl);
++ else
++ uart_rs485_config(uport);
+ ops->start_tx(uport);
+ spin_unlock_irq(&uport->lock);
+ tty_port_set_initialized(port, 1);
+@@ -2558,10 +2562,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+ */
+ spin_lock_irqsave(&port->lock, flags);
+ port->mctrl &= TIOCM_DTR;
+- if (port->rs485.flags & SER_RS485_ENABLED &&
+- !(port->rs485.flags & SER_RS485_RTS_AFTER_SEND))
+- port->mctrl |= TIOCM_RTS;
+- port->ops->set_mctrl(port, port->mctrl);
++ if (!(port->rs485.flags & SER_RS485_ENABLED))
++ port->ops->set_mctrl(port, port->mctrl);
++ else
++ uart_rs485_config(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ /*
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 2c85dbf165c4a..9a875558f5ef6 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -131,6 +131,53 @@ static void stm32_usart_clr_bits(struct uart_port *port, u32 reg, u32 bits)
+ writel_relaxed(val, port->membase + reg);
+ }
+
++static unsigned int stm32_usart_tx_empty(struct uart_port *port)
++{
++ struct stm32_port *stm32_port = to_stm32_port(port);
++ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
++
++ if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
++ return TIOCSER_TEMT;
++
++ return 0;
++}
++
++static void stm32_usart_rs485_rts_enable(struct uart_port *port)
++{
++ struct stm32_port *stm32_port = to_stm32_port(port);
++ struct serial_rs485 *rs485conf = &port->rs485;
++
++ if (stm32_port->hw_flow_control ||
++ !(rs485conf->flags & SER_RS485_ENABLED))
++ return;
++
++ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
++ mctrl_gpio_set(stm32_port->gpios,
++ stm32_port->port.mctrl | TIOCM_RTS);
++ } else {
++ mctrl_gpio_set(stm32_port->gpios,
++ stm32_port->port.mctrl & ~TIOCM_RTS);
++ }
++}
++
++static void stm32_usart_rs485_rts_disable(struct uart_port *port)
++{
++ struct stm32_port *stm32_port = to_stm32_port(port);
++ struct serial_rs485 *rs485conf = &port->rs485;
++
++ if (stm32_port->hw_flow_control ||
++ !(rs485conf->flags & SER_RS485_ENABLED))
++ return;
++
++ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
++ mctrl_gpio_set(stm32_port->gpios,
++ stm32_port->port.mctrl & ~TIOCM_RTS);
++ } else {
++ mctrl_gpio_set(stm32_port->gpios,
++ stm32_port->port.mctrl | TIOCM_RTS);
++ }
++}
++
+ static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
+ u32 delay_DDE, u32 baud)
+ {
+@@ -214,6 +261,12 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *ter
+
+ stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
+
++ /* Adjust RTS polarity in case it's driven in software */
++ if (stm32_usart_tx_empty(port))
++ stm32_usart_rs485_rts_disable(port);
++ else
++ stm32_usart_rs485_rts_enable(port);
++
+ return 0;
+ }
+
+@@ -529,42 +582,6 @@ static void stm32_usart_tc_interrupt_disable(struct uart_port *port)
+ stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TCIE);
+ }
+
+-static void stm32_usart_rs485_rts_enable(struct uart_port *port)
+-{
+- struct stm32_port *stm32_port = to_stm32_port(port);
+- struct serial_rs485 *rs485conf = &port->rs485;
+-
+- if (stm32_port->hw_flow_control ||
+- !(rs485conf->flags & SER_RS485_ENABLED))
+- return;
+-
+- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
+- mctrl_gpio_set(stm32_port->gpios,
+- stm32_port->port.mctrl | TIOCM_RTS);
+- } else {
+- mctrl_gpio_set(stm32_port->gpios,
+- stm32_port->port.mctrl & ~TIOCM_RTS);
+- }
+-}
+-
+-static void stm32_usart_rs485_rts_disable(struct uart_port *port)
+-{
+- struct stm32_port *stm32_port = to_stm32_port(port);
+- struct serial_rs485 *rs485conf = &port->rs485;
+-
+- if (stm32_port->hw_flow_control ||
+- !(rs485conf->flags & SER_RS485_ENABLED))
+- return;
+-
+- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
+- mctrl_gpio_set(stm32_port->gpios,
+- stm32_port->port.mctrl & ~TIOCM_RTS);
+- } else {
+- mctrl_gpio_set(stm32_port->gpios,
+- stm32_port->port.mctrl | TIOCM_RTS);
+- }
+-}
+-
+ static void stm32_usart_transmit_chars_pio(struct uart_port *port)
+ {
+ struct stm32_port *stm32_port = to_stm32_port(port);
+@@ -807,17 +824,6 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)
+ return IRQ_HANDLED;
+ }
+
+-static unsigned int stm32_usart_tx_empty(struct uart_port *port)
+-{
+- struct stm32_port *stm32_port = to_stm32_port(port);
+- const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+-
+- if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
+- return TIOCSER_TEMT;
+-
+- return 0;
+-}
+-
+ static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+ struct stm32_port *stm32_port = to_stm32_port(port);
+diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
+index 9e01fe6c0ab8c..769044dfe990a 100644
+--- a/drivers/tty/serial/xilinx_uartps.c
++++ b/drivers/tty/serial/xilinx_uartps.c
+@@ -361,6 +361,8 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+ isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
+ }
+
++ isrstatus &= port->read_status_mask;
++ isrstatus &= ~port->ignore_status_mask;
+ /*
+ * Skip RX processing if RX is disabled as RXEMPTY will never be set
+ * as read bytes will not be removed from the FIFO.
+@@ -1329,12 +1331,20 @@ static int cdns_uart_resume(struct device *device)
+ unsigned long flags;
+ u32 ctrl_reg;
+ int may_wake;
++ int ret;
+
+ may_wake = device_may_wakeup(device);
+
+ if (console_suspend_enabled && uart_console(port) && !may_wake) {
+- clk_enable(cdns_uart->pclk);
+- clk_enable(cdns_uart->uartclk);
++ ret = clk_enable(cdns_uart->pclk);
++ if (ret)
++ return ret;
++
++ ret = clk_enable(cdns_uart->uartclk);
++ if (ret) {
++ clk_disable(cdns_uart->pclk);
++ return ret;
++ }
+
+ spin_lock_irqsave(&port->lock, flags);
+
+diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c
+index 075f6b1b2a1a1..f204cec8d380a 100644
+--- a/drivers/usb/common/debug.c
++++ b/drivers/usb/common/debug.c
+@@ -208,30 +208,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
+ snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
+ }
+
+-/**
+- * usb_decode_ctrl - Returns human readable representation of control request.
+- * @str: buffer to return a human-readable representation of control request.
+- * This buffer should have about 200 bytes.
+- * @size: size of str buffer.
+- * @bRequestType: matches the USB bmRequestType field
+- * @bRequest: matches the USB bRequest field
+- * @wValue: matches the USB wValue field (CPU byte order)
+- * @wIndex: matches the USB wIndex field (CPU byte order)
+- * @wLength: matches the USB wLength field (CPU byte order)
+- *
+- * Function returns decoded, formatted and human-readable description of
+- * control request packet.
+- *
+- * The usage scenario for this is for tracepoints, so function as a return
+- * use the same value as in parameters. This approach allows to use this
+- * function in TP_printk
+- *
+- * Important: wValue, wIndex, wLength parameters before invoking this function
+- * should be processed by le16_to_cpu macro.
+- */
+-const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
+- __u8 bRequest, __u16 wValue, __u16 wIndex,
+- __u16 wLength)
++static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType,
++ __u8 bRequest, __u16 wValue, __u16 wIndex,
++ __u16 wLength)
++{
++ u8 recip = bRequestType & USB_RECIP_MASK;
++ u8 type = bRequestType & USB_TYPE_MASK;
++
++ snprintf(str, size,
++ "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u",
++ (type == USB_TYPE_STANDARD) ? "Standard" :
++ (type == USB_TYPE_VENDOR) ? "Vendor" :
++ (type == USB_TYPE_CLASS) ? "Class" : "Unknown",
++ (recip == USB_RECIP_DEVICE) ? "Device" :
++ (recip == USB_RECIP_INTERFACE) ? "Interface" :
++ (recip == USB_RECIP_ENDPOINT) ? "Endpoint" : "Unknown",
++ (bRequestType & USB_DIR_IN) ? "IN" : "OUT",
++ bRequest, wValue, wIndex, wLength);
++}
++
++static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType,
++ __u8 bRequest, __u16 wValue, __u16 wIndex,
++ __u16 wLength)
+ {
+ switch (bRequest) {
+ case USB_REQ_GET_STATUS:
+@@ -272,14 +270,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
+ usb_decode_set_isoch_delay(wValue, str, size);
+ break;
+ default:
+- snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
+- bRequestType, bRequest,
+- (u8)(cpu_to_le16(wValue) & 0xff),
+- (u8)(cpu_to_le16(wValue) >> 8),
+- (u8)(cpu_to_le16(wIndex) & 0xff),
+- (u8)(cpu_to_le16(wIndex) >> 8),
+- (u8)(cpu_to_le16(wLength) & 0xff),
+- (u8)(cpu_to_le16(wLength) >> 8));
++ usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
++ wValue, wIndex, wLength);
++ break;
++ }
++}
++
++/**
++ * usb_decode_ctrl - Returns human readable representation of control request.
++ * @str: buffer to return a human-readable representation of control request.
++ * This buffer should have about 200 bytes.
++ * @size: size of str buffer.
++ * @bRequestType: matches the USB bmRequestType field
++ * @bRequest: matches the USB bRequest field
++ * @wValue: matches the USB wValue field (CPU byte order)
++ * @wIndex: matches the USB wIndex field (CPU byte order)
++ * @wLength: matches the USB wLength field (CPU byte order)
++ *
++ * Function returns decoded, formatted and human-readable description of
++ * control request packet.
++ *
++ * The usage scenario for this is for tracepoints, so function as a return
++ * use the same value as in parameters. This approach allows to use this
++ * function in TP_printk
++ *
++ * Important: wValue, wIndex, wLength parameters before invoking this function
++ * should be processed by le16_to_cpu macro.
++ */
++const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
++ __u8 bRequest, __u16 wValue, __u16 wIndex,
++ __u16 wLength)
++{
++ switch (bRequestType & USB_TYPE_MASK) {
++ case USB_TYPE_STANDARD:
++ usb_decode_ctrl_standard(str, size, bRequestType, bRequest,
++ wValue, wIndex, wLength);
++ break;
++ case USB_TYPE_VENDOR:
++ case USB_TYPE_CLASS:
++ default:
++ usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
++ wValue, wIndex, wLength);
++ break;
+ }
+
+ return str;
+diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c
+index b39c9f1c375d6..e20874caba363 100644
+--- a/drivers/usb/common/usb-conn-gpio.c
++++ b/drivers/usb/common/usb-conn-gpio.c
+@@ -208,10 +208,8 @@ static int usb_conn_probe(struct platform_device *pdev)
+ if (PTR_ERR(info->vbus) == -ENODEV)
+ info->vbus = NULL;
+
+- if (IS_ERR(info->vbus)) {
+- ret = PTR_ERR(info->vbus);
+- return dev_err_probe(dev, ret, "failed to get vbus :%d\n", ret);
+- }
++ if (IS_ERR(info->vbus))
++ return dev_err_probe(dev, PTR_ERR(info->vbus), "failed to get vbus\n");
+
+ info->role_sw = usb_role_switch_get(dev);
+ if (IS_ERR(info->role_sw))
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index f99a65a64588f..999b7c9697fcd 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = {
+ { USB_DEVICE(0x1532, 0x0116), .driver_info =
+ USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+
++ /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
++ { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ /* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
+ { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 219d797e22301..68d986361c495 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -407,6 +407,10 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
+ reg |= FIELD_PREP(DWC3_GFLADJ_REFCLK_FLADJ_MASK, fladj)
+ | FIELD_PREP(DWC3_GFLADJ_240MHZDECR, decr >> 1)
+ | FIELD_PREP(DWC3_GFLADJ_240MHZDECR_PLS1, decr & 1);
++
++ if (dwc->gfladj_refclk_lpm_sel)
++ reg |= DWC3_GFLADJ_REFCLK_LPM_SEL;
++
+ dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ }
+
+@@ -788,7 +792,7 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
+ else
+ reg |= DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+- if (dwc->dis_u2_freeclk_exists_quirk)
++ if (dwc->dis_u2_freeclk_exists_quirk || dwc->gfladj_refclk_lpm_sel)
+ reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+@@ -1179,6 +1183,21 @@ static int dwc3_core_init(struct dwc3 *dwc)
+ dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ }
+
++ /*
++ * When configured in HOST mode, after issuing U3/L2 exit controller
++ * fails to send proper CRC checksum in CRC5 feild. Because of this
++ * behaviour Transaction Error is generated, resulting in reset and
++ * re-enumeration of usb device attached. All the termsel, xcvrsel,
++ * opmode becomes 0 during end of resume. Enabling bit 10 of GUCTL1
++ * will correct this problem. This option is to support certain
++ * legacy ULPI PHYs.
++ */
++ if (dwc->resume_hs_terminations) {
++ reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
++ reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST;
++ dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
++ }
++
+ if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+
+@@ -1522,8 +1541,12 @@ static void dwc3_get_properties(struct dwc3 *dwc)
+ "snps,dis-del-phy-power-chg-quirk");
+ dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
+ "snps,dis-tx-ipgap-linecheck-quirk");
++ dwc->resume_hs_terminations = device_property_read_bool(dev,
++ "snps,resume-hs-terminations");
+ dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
+ "snps,parkmode-disable-ss-quirk");
++ dwc->gfladj_refclk_lpm_sel = device_property_read_bool(dev,
++ "snps,gfladj-refclk-lpm-sel-quirk");
+
+ dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
+ "snps,tx_de_emphasis_quirk");
+@@ -1712,8 +1735,10 @@ static int dwc3_probe(struct platform_device *pdev)
+ dwc3_get_properties(dwc);
+
+ dwc->reset = devm_reset_control_array_get_optional_shared(dev);
+- if (IS_ERR(dwc->reset))
+- return PTR_ERR(dwc->reset);
++ if (IS_ERR(dwc->reset)) {
++ ret = PTR_ERR(dwc->reset);
++ goto put_usb_psy;
++ }
+
+ if (dev->of_node) {
+ /*
+@@ -1723,45 +1748,57 @@ static int dwc3_probe(struct platform_device *pdev)
+ * check for them to retain backwards compatibility.
+ */
+ dwc->bus_clk = devm_clk_get_optional(dev, "bus_early");
+- if (IS_ERR(dwc->bus_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
+- "could not get bus clock\n");
++ if (IS_ERR(dwc->bus_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
++ "could not get bus clock\n");
++ goto put_usb_psy;
++ }
+
+ if (dwc->bus_clk == NULL) {
+ dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk");
+- if (IS_ERR(dwc->bus_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
+- "could not get bus clock\n");
++ if (IS_ERR(dwc->bus_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
++ "could not get bus clock\n");
++ goto put_usb_psy;
++ }
+ }
+
+ dwc->ref_clk = devm_clk_get_optional(dev, "ref");
+- if (IS_ERR(dwc->ref_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
+- "could not get ref clock\n");
++ if (IS_ERR(dwc->ref_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
++ "could not get ref clock\n");
++ goto put_usb_psy;
++ }
+
+ if (dwc->ref_clk == NULL) {
+ dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk");
+- if (IS_ERR(dwc->ref_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
+- "could not get ref clock\n");
++ if (IS_ERR(dwc->ref_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
++ "could not get ref clock\n");
++ goto put_usb_psy;
++ }
+ }
+
+ dwc->susp_clk = devm_clk_get_optional(dev, "suspend");
+- if (IS_ERR(dwc->susp_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
+- "could not get suspend clock\n");
++ if (IS_ERR(dwc->susp_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
++ "could not get suspend clock\n");
++ goto put_usb_psy;
++ }
+
+ if (dwc->susp_clk == NULL) {
+ dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk");
+- if (IS_ERR(dwc->susp_clk))
+- return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
+- "could not get suspend clock\n");
++ if (IS_ERR(dwc->susp_clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
++ "could not get suspend clock\n");
++ goto put_usb_psy;
++ }
+ }
+ }
+
+ ret = reset_control_deassert(dwc->reset);
+ if (ret)
+- return ret;
++ goto put_usb_psy;
+
+ ret = dwc3_clk_enable(dwc);
+ if (ret)
+@@ -1861,7 +1898,7 @@ disable_clks:
+ dwc3_clk_disable(dwc);
+ assert_reset:
+ reset_control_assert(dwc->reset);
+-
++put_usb_psy:
+ if (dwc->usb_psy)
+ power_supply_put(dwc->usb_psy);
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 4fe4287dc934e..3ac9313e66f94 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -263,6 +263,7 @@
+ #define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK BIT(26)
+ #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
+ #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
++#define DWC3_GUCTL1_RESUME_OPMODE_HS_HOST BIT(10)
+
+ /* Global Status Register */
+ #define DWC3_GSTS_OTG_IP BIT(10)
+@@ -391,6 +392,7 @@
+ #define DWC3_GFLADJ_30MHZ_SDBND_SEL BIT(7)
+ #define DWC3_GFLADJ_30MHZ_MASK 0x3f
+ #define DWC3_GFLADJ_REFCLK_FLADJ_MASK GENMASK(21, 8)
++#define DWC3_GFLADJ_REFCLK_LPM_SEL BIT(23)
+ #define DWC3_GFLADJ_240MHZDECR GENMASK(30, 24)
+ #define DWC3_GFLADJ_240MHZDECR_PLS1 BIT(31)
+
+@@ -1096,6 +1098,8 @@ struct dwc3_scratchpad_array {
+ * change quirk.
+ * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
+ * check during HS transmit.
++ * @resume-hs-terminations: Set if we enable quirk for fixing improper crc
++ * generation after resume from suspend.
+ * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed
+ * instances in park mode.
+ * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
+@@ -1311,7 +1315,9 @@ struct dwc3 {
+ unsigned dis_u2_freeclk_exists_quirk:1;
+ unsigned dis_del_phy_power_chg_quirk:1;
+ unsigned dis_tx_ipgap_linecheck_quirk:1;
++ unsigned resume_hs_terminations:1;
+ unsigned parkmode_disable_ss_quirk:1;
++ unsigned gfladj_refclk_lpm_sel:1;
+
+ unsigned tx_de_emphasis_quirk:1;
+ unsigned tx_de_emphasis:2;
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index e0fa4b186ec6d..36184a7625273 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -2645,10 +2645,10 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
+ unsigned i = 0;
+ vla_group(d);
+ vla_item(d, struct usb_gadget_strings *, stringtabs,
+- lang_count + 1);
++ size_add(lang_count, 1));
+ vla_item(d, struct usb_gadget_strings, stringtab, lang_count);
+ vla_item(d, struct usb_string, strings,
+- lang_count*(needed_count+1));
++ size_mul(lang_count, (needed_count + 1)));
+
+ char *vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
+
+diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
+index abec5c58f5251..a881c69b1f2bf 100644
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -89,7 +89,7 @@ struct printer_dev {
+ u8 printer_cdev_open;
+ wait_queue_head_t wait;
+ unsigned q_len;
+- char *pnp_string; /* We don't own memory! */
++ char **pnp_string; /* We don't own memory! */
+ struct usb_function function;
+ };
+
+@@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f,
+ if ((wIndex>>8) != dev->interface)
+ break;
+
+- if (!dev->pnp_string) {
++ if (!*dev->pnp_string) {
+ value = 0;
+ break;
+ }
+- value = strlen(dev->pnp_string);
++ value = strlen(*dev->pnp_string);
+ buf[0] = (value >> 8) & 0xFF;
+ buf[1] = value & 0xFF;
+- memcpy(buf + 2, dev->pnp_string, value);
++ memcpy(buf + 2, *dev->pnp_string, value);
+ DBG(dev, "1284 PNP String: %x %s\n", value,
+- dev->pnp_string);
++ *dev->pnp_string);
+ break;
+
+ case GET_PORT_STATUS: /* Get Port Status */
+@@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi)
+ kref_init(&dev->kref);
+ ++opts->refcnt;
+ dev->minor = opts->minor;
+- dev->pnp_string = opts->pnp_string;
++ dev->pnp_string = &opts->pnp_string;
+ dev->q_len = opts->q_len;
+ mutex_unlock(&opts->lock);
+
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 71669e0e4d007..7ec223849d949 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -421,7 +421,7 @@ uvc_register_video(struct uvc_device *uvc)
+ int ret;
+
+ /* TODO reference counting. */
+- memset(&uvc->vdev, 0, sizeof(uvc->video));
++ memset(&uvc->vdev, 0, sizeof(uvc->vdev));
+ uvc->vdev.v4l2_dev = &uvc->v4l2_dev;
+ uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev;
+ uvc->vdev.fops = &uvc_v4l2_fops;
+@@ -897,10 +897,14 @@ static void uvc_function_unbind(struct usb_configuration *c,
+ {
+ struct usb_composite_dev *cdev = c->cdev;
+ struct uvc_device *uvc = to_uvc(f);
++ struct uvc_video *video = &uvc->video;
+ long wait_ret = 1;
+
+ uvcg_info(f, "%s()\n", __func__);
+
++ if (video->async_wq)
++ destroy_workqueue(video->async_wq);
++
+ /*
+ * If we know we're connected via v4l2, then there should be a cleanup
+ * of the device from userspace either via UVC_EVENT_DISCONNECT or
+diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
+index 58e383afdd440..1a31e6c6a5ffb 100644
+--- a/drivers/usb/gadget/function/uvc.h
++++ b/drivers/usb/gadget/function/uvc.h
+@@ -88,6 +88,7 @@ struct uvc_video {
+ struct usb_ep *ep;
+
+ struct work_struct pump;
++ struct workqueue_struct *async_wq;
+
+ /* Frame parameters */
+ u8 bpp;
+diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
+index fd8f73bb726dd..fddc392b8ab95 100644
+--- a/drivers/usb/gadget/function/uvc_v4l2.c
++++ b/drivers/usb/gadget/function/uvc_v4l2.c
+@@ -170,7 +170,7 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+ return ret;
+
+ if (uvc->state == UVC_STATE_STREAMING)
+- schedule_work(&video->pump);
++ queue_work(video->async_wq, &video->pump);
+
+ return ret;
+ }
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index c00ce0e91f5d5..bb037fcc90e69 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -277,7 +277,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
+ spin_unlock_irqrestore(&video->req_lock, flags);
+
+ if (uvc->state == UVC_STATE_STREAMING)
+- schedule_work(&video->pump);
++ queue_work(video->async_wq, &video->pump);
+ }
+
+ static int
+@@ -485,7 +485,7 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
+
+ video->req_int_count = 0;
+
+- schedule_work(&video->pump);
++ queue_work(video->async_wq, &video->pump);
+
+ return ret;
+ }
+@@ -499,6 +499,11 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
+ spin_lock_init(&video->req_lock);
+ INIT_WORK(&video->pump, uvcg_video_pump);
+
++ /* Allocate a work queue for asynchronous video pump handler. */
++ video->async_wq = alloc_workqueue("uvcgadget", WQ_UNBOUND | WQ_HIGHPRI, 0);
++ if (!video->async_wq)
++ return -EINVAL;
++
+ video->uvc = uvc;
+ video->fcc = V4L2_PIX_FMT_YUYV;
+ video->bpp = 16;
+diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
+index e61155fa63796..f1367b53b2600 100644
+--- a/drivers/usb/host/xhci-dbgcap.c
++++ b/drivers/usb/host/xhci-dbgcap.c
+@@ -988,7 +988,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *
+ dbc->driver = driver;
+
+ if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE)
+- return NULL;
++ goto err;
+
+ INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events);
+ spin_lock_init(&dbc->lock);
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 8c19e151a9454..9e56aa28efcd4 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -641,7 +641,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
+ num_stream_ctxs, &stream_info->ctx_array_dma,
+ mem_flags);
+ if (!stream_info->stream_ctx_array)
+- goto cleanup_ctx;
++ goto cleanup_ring_array;
+ memset(stream_info->stream_ctx_array, 0,
+ sizeof(struct xhci_stream_ctx)*num_stream_ctxs);
+
+@@ -702,6 +702,11 @@ cleanup_rings:
+ }
+ xhci_free_command(xhci, stream_info->free_streams_command);
+ cleanup_ctx:
++ xhci_free_stream_ctx(xhci,
++ stream_info->num_stream_ctxs,
++ stream_info->stream_ctx_array,
++ stream_info->ctx_array_dma);
++cleanup_ring_array:
+ kfree(stream_info->stream_rings);
+ cleanup_info:
+ kfree(stream_info);
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index a8641b6536eea..5fb55bf194931 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -123,7 +123,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
+ };
+
+ static const struct xhci_plat_priv xhci_plat_brcm = {
+- .quirks = XHCI_RESET_ON_RESUME,
++ .quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS,
+ };
+
+ static const struct of_device_id usb_xhci_of_match[] = {
+@@ -437,7 +437,16 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev)
+ * xhci_suspend() needs `do_wakeup` to know whether host is allowed
+ * to do wakeup during suspend.
+ */
+- return xhci_suspend(xhci, device_may_wakeup(dev));
++ ret = xhci_suspend(xhci, device_may_wakeup(dev));
++ if (ret)
++ return ret;
++
++ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
++ clk_disable_unprepare(xhci->clk);
++ clk_disable_unprepare(xhci->reg_clk);
++ }
++
++ return 0;
+ }
+
+ static int __maybe_unused xhci_plat_resume(struct device *dev)
+@@ -446,6 +455,11 @@ static int __maybe_unused xhci_plat_resume(struct device *dev)
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ int ret;
+
++ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
++ clk_prepare_enable(xhci->clk);
++ clk_prepare_enable(xhci->reg_clk);
++ }
++
+ ret = xhci_priv_resume_quirk(hcd);
+ if (ret)
+ return ret;
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 38649284ff889..a7ef675f00fdd 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1183,7 +1183,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
+ /* re-initialize the HC on Restore Error, or Host Controller Error */
+ if (temp & (STS_SRE | STS_HCE)) {
+ reinit_xhc = true;
+- xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
++ if (!xhci->broken_suspend)
++ xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+ }
+
+ if (reinit_xhc) {
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 7caa0db5e826d..6dfbf73ee840d 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1899,6 +1899,7 @@ struct xhci_hcd {
+ #define XHCI_NO_SOFT_RETRY BIT_ULL(40)
+ #define XHCI_BROKEN_D3COLD BIT_ULL(41)
+ #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
++#define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43)
+
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
+index e9437a176518a..ea39243efee39 100644
+--- a/drivers/usb/misc/idmouse.c
++++ b/drivers/usb/misc/idmouse.c
+@@ -177,10 +177,6 @@ static int idmouse_create_image(struct usb_idmouse *dev)
+ bytes_read += bulk_read;
+ }
+
+- /* reset the device */
+-reset:
+- ftip_command(dev, FTIP_RELEASE, 0, 0);
+-
+ /* check for valid image */
+ /* right border should be black (0x00) */
+ for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
+@@ -192,6 +188,10 @@ reset:
+ if (dev->bulk_in_buffer[bytes_read] != 0xFF)
+ return -EAGAIN;
+
++ /* reset the device */
++reset:
++ ftip_command(dev, FTIP_RELEASE, 0, 0);
++
+ /* should be IMGSIZE == 65040 */
+ dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
+ bytes_read);
+diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
+index 0ca173af87bb6..a3a6282893d09 100644
+--- a/drivers/usb/mtu3/mtu3_core.c
++++ b/drivers/usb/mtu3/mtu3_core.c
+@@ -978,8 +978,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ goto irq_err;
+ }
+
+- device_init_wakeup(dev, true);
+-
+ /* power down device IP for power saving by default */
+ mtu3_stop(mtu);
+
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 4cb65346789d6..d78ae52b4e261 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -356,6 +356,8 @@ static int mtu3_probe(struct platform_device *pdev)
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+
++ device_init_wakeup(dev, true);
++
+ ret = ssusb_rscs_init(ssusb);
+ if (ret)
+ goto comm_init_err;
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index daada4b66a922..6704a62a16659 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -760,6 +760,9 @@ static void rxstate(struct musb *musb, struct musb_request *req)
+ musb_writew(epio, MUSB_RXCSR, csr);
+
+ buffer_aint_mapped:
++ fifo_count = min_t(unsigned int,
++ request->length - request->actual,
++ (unsigned int)fifo_count);
+ musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
+ (request->buf + request->actual));
+ request->actual += fifo_count;
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 4993227ab2930..20dcbccb290b3 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1275,12 +1275,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
+ USB_SC_RBC, USB_PR_BULK, NULL,
+ 0 ),
+
+-UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100,
+- "Samsung",
+- "Flash Drive FIT",
+- USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+- US_FL_MAX_SECTORS_64),
+-
+ /* aeb */
+ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
+ "Feiya",
+diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c
+index c0f0842d443c6..f178d0eb47b18 100644
+--- a/drivers/usb/typec/anx7411.c
++++ b/drivers/usb/typec/anx7411.c
+@@ -1105,7 +1105,7 @@ static int anx7411_typec_switch_probe(struct anx7411_data *ctx,
+ int ret;
+ struct device_node *node;
+
+- node = of_find_node_by_name(dev->of_node, "orientation_switch");
++ node = of_get_child_by_name(dev->of_node, "orientation_switch");
+ if (!node)
+ return 0;
+
+@@ -1115,7 +1115,7 @@ static int anx7411_typec_switch_probe(struct anx7411_data *ctx,
+ return ret;
+ }
+
+- node = of_find_node_by_name(dev->of_node, "mode_switch");
++ node = of_get_child_by_name(dev->of_node, "mode_switch");
+ if (!node) {
+ dev_err(dev, "no typec mux exist");
+ ret = -ENODEV;
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 6364f0d467ea3..74fb5a4c6f21b 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1067,11 +1067,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
+
+ cap->fwnode = ucsi_find_fwnode(con);
+ con->usb_role_sw = fwnode_usb_role_switch_get(cap->fwnode);
+- if (IS_ERR(con->usb_role_sw)) {
+- dev_err(ucsi->dev, "con%d: failed to get usb role switch\n",
+- con->num);
+- return PTR_ERR(con->usb_role_sw);
+- }
++ if (IS_ERR(con->usb_role_sw))
++ return dev_err_probe(ucsi->dev, PTR_ERR(con->usb_role_sw),
++ "con%d: failed to get usb role switch\n", con->num);
+
+ /* Delay other interactions with the con until registration is complete */
+ mutex_lock(&con->lock);
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index 368330417bde2..5703775af1297 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,
+ return NULL;
+ }
+
+- pkt->buf = kmalloc(pkt->len, GFP_KERNEL);
++ pkt->buf = kvmalloc(pkt->len, GFP_KERNEL);
+ if (!pkt->buf) {
+ kfree(pkt);
+ return NULL;
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 538f2d40acdac..d245826a9324d 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -8,6 +8,7 @@
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/sysfb.h>
+ #include <linux/types.h>
+ #include <linux/vgaarb.h>
+
+@@ -286,7 +287,20 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si
+ #if IS_REACHABLE(CONFIG_FB)
+ struct apertures_struct *a;
+ int ret;
++#endif
++
++ /*
++ * If a driver asked to unregister a platform device registered by
++ * sysfb, then can be assumed that this is a driver for a display
++ * that is set up by the system firmware and has a generic driver.
++ *
++ * Drivers for devices that don't have a generic driver will never
++ * ask for this, so let's assume that a real driver for the display
++ * was already probed and prevent sysfb to register devices later.
++ */
++ sysfb_disable();
+
++#if IS_REACHABLE(CONFIG_FB)
+ a = alloc_apertures(1);
+ if (!a)
+ return -ENOMEM;
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index 02b0cf2cfafed..bda4d304feb68 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -19,7 +19,6 @@
+ #include <linux/kernel.h>
+ #include <linux/major.h>
+ #include <linux/slab.h>
+-#include <linux/sysfb.h>
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/vt.h>
+@@ -1777,17 +1776,6 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
+ do_free = true;
+ }
+
+- /*
+- * If a driver asked to unregister a platform device registered by
+- * sysfb, then can be assumed that this is a driver for a display
+- * that is set up by the system firmware and has a generic driver.
+- *
+- * Drivers for devices that don't have a generic driver will never
+- * ask for this, so let's assume that a real driver for the display
+- * was already probed and prevent sysfb to register devices later.
+- */
+- sysfb_disable();
+-
+ mutex_lock(®istration_lock);
+ do_remove_conflicting_framebuffers(a, name, primary);
+ mutex_unlock(®istration_lock);
+diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
+index d7aa5511c3617..e65bdc499c236 100644
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -137,6 +137,8 @@ static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len);
+ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size);
+ static void ufx_free_urb_list(struct ufx_data *dev);
+
++static DEFINE_MUTEX(disconnect_mutex);
++
+ /* reads a control register */
+ static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data)
+ {
+@@ -1071,9 +1073,13 @@ static int ufx_ops_open(struct fb_info *info, int user)
+ if (user == 0 && !console)
+ return -EBUSY;
+
++ mutex_lock(&disconnect_mutex);
++
+ /* If the USB device is gone, we don't accept new opens */
+- if (dev->virtualized)
++ if (dev->virtualized) {
++ mutex_unlock(&disconnect_mutex);
+ return -ENODEV;
++ }
+
+ dev->fb_count++;
+
+@@ -1097,6 +1103,8 @@ static int ufx_ops_open(struct fb_info *info, int user)
+ pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d",
+ info->node, user, info, dev->fb_count);
+
++ mutex_unlock(&disconnect_mutex);
++
+ return 0;
+ }
+
+@@ -1741,6 +1749,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+ {
+ struct ufx_data *dev;
+
++ mutex_lock(&disconnect_mutex);
++
+ dev = usb_get_intfdata(interface);
+
+ pr_debug("USB disconnect starting\n");
+@@ -1761,6 +1771,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+ kref_put(&dev->kref, ufx_free);
+
+ /* consider ufx_data freed */
++
++ mutex_unlock(&disconnect_mutex);
+ }
+
+ static struct usb_driver ufx_driver = {
+diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
+index 38a861e22c339..7753e586e65a0 100644
+--- a/drivers/video/fbdev/stifb.c
++++ b/drivers/video/fbdev/stifb.c
+@@ -1298,7 +1298,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
+
+ /* limit fbsize to max visible screen size */
+ if (fix->smem_len > yres*fix->line_length)
+- fix->smem_len = yres*fix->line_length;
++ fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024);
+
+ fix->accel = FB_ACCEL_NONE;
+
+diff --git a/drivers/xen/gntdev-common.h b/drivers/xen/gntdev-common.h
+index 40ef379c28ab0..9c286b2a19001 100644
+--- a/drivers/xen/gntdev-common.h
++++ b/drivers/xen/gntdev-common.h
+@@ -44,9 +44,10 @@ struct gntdev_unmap_notify {
+ };
+
+ struct gntdev_grant_map {
++ atomic_t in_use;
+ struct mmu_interval_notifier notifier;
++ bool notifier_init;
+ struct list_head next;
+- struct vm_area_struct *vma;
+ int index;
+ int count;
+ int flags;
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
+index 84b143eef395b..4d9a3050de6a3 100644
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -286,6 +286,9 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
+ */
+ }
+
++ if (use_ptemod && map->notifier_init)
++ mmu_interval_notifier_remove(&map->notifier);
++
+ if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
+ notify_remote_via_evtchn(map->notify.event);
+ evtchn_put(map->notify.event);
+@@ -298,7 +301,7 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
+ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data)
+ {
+ struct gntdev_grant_map *map = data;
+- unsigned int pgnr = (addr - map->vma->vm_start) >> PAGE_SHIFT;
++ unsigned int pgnr = (addr - map->pages_vm_start) >> PAGE_SHIFT;
+ int flags = map->flags | GNTMAP_application_map | GNTMAP_contains_pte |
+ (1 << _GNTMAP_guest_avail0);
+ u64 pte_maddr;
+@@ -367,8 +370,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
+ for (i = 0; i < map->count; i++) {
+ if (map->map_ops[i].status == GNTST_okay) {
+ map->unmap_ops[i].handle = map->map_ops[i].handle;
+- if (!use_ptemod)
+- alloced++;
++ alloced++;
+ } else if (!err)
+ err = -EINVAL;
+
+@@ -377,8 +379,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
+
+ if (use_ptemod) {
+ if (map->kmap_ops[i].status == GNTST_okay) {
+- if (map->map_ops[i].status == GNTST_okay)
+- alloced++;
++ alloced++;
+ map->kunmap_ops[i].handle = map->kmap_ops[i].handle;
+ } else if (!err)
+ err = -EINVAL;
+@@ -394,8 +395,14 @@ static void __unmap_grant_pages_done(int result,
+ unsigned int i;
+ struct gntdev_grant_map *map = data->data;
+ unsigned int offset = data->unmap_ops - map->unmap_ops;
++ int successful_unmaps = 0;
++ int live_grants;
+
+ for (i = 0; i < data->count; i++) {
++ if (map->unmap_ops[offset + i].status == GNTST_okay &&
++ map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE)
++ successful_unmaps++;
++
+ WARN_ON(map->unmap_ops[offset + i].status != GNTST_okay &&
+ map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE);
+ pr_debug("unmap handle=%d st=%d\n",
+@@ -403,6 +410,10 @@ static void __unmap_grant_pages_done(int result,
+ map->unmap_ops[offset+i].status);
+ map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE;
+ if (use_ptemod) {
++ if (map->kunmap_ops[offset + i].status == GNTST_okay &&
++ map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE)
++ successful_unmaps++;
++
+ WARN_ON(map->kunmap_ops[offset + i].status != GNTST_okay &&
+ map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE);
+ pr_debug("kunmap handle=%u st=%d\n",
+@@ -411,11 +422,15 @@ static void __unmap_grant_pages_done(int result,
+ map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE;
+ }
+ }
++
+ /*
+ * Decrease the live-grant counter. This must happen after the loop to
+ * prevent premature reuse of the grants by gnttab_mmap().
+ */
+- atomic_sub(data->count, &map->live_grants);
++ live_grants = atomic_sub_return(successful_unmaps, &map->live_grants);
++ if (WARN_ON(live_grants < 0))
++ pr_err("%s: live_grants became negative (%d) after unmapping %d pages!\n",
++ __func__, live_grants, successful_unmaps);
+
+ /* Release reference taken by __unmap_grant_pages */
+ gntdev_put_map(NULL, map);
+@@ -496,11 +511,7 @@ static void gntdev_vma_close(struct vm_area_struct *vma)
+ struct gntdev_priv *priv = file->private_data;
+
+ pr_debug("gntdev_vma_close %p\n", vma);
+- if (use_ptemod) {
+- WARN_ON(map->vma != vma);
+- mmu_interval_notifier_remove(&map->notifier);
+- map->vma = NULL;
+- }
++
+ vma->vm_private_data = NULL;
+ gntdev_put_map(priv, map);
+ }
+@@ -528,29 +539,30 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn,
+ struct gntdev_grant_map *map =
+ container_of(mn, struct gntdev_grant_map, notifier);
+ unsigned long mstart, mend;
++ unsigned long map_start, map_end;
+
+ if (!mmu_notifier_range_blockable(range))
+ return false;
+
++ map_start = map->pages_vm_start;
++ map_end = map->pages_vm_start + (map->count << PAGE_SHIFT);
++
+ /*
+ * If the VMA is split or otherwise changed the notifier is not
+ * updated, but we don't want to process VA's outside the modified
+ * VMA. FIXME: It would be much more understandable to just prevent
+ * modifying the VMA in the first place.
+ */
+- if (map->vma->vm_start >= range->end ||
+- map->vma->vm_end <= range->start)
++ if (map_start >= range->end || map_end <= range->start)
+ return true;
+
+- mstart = max(range->start, map->vma->vm_start);
+- mend = min(range->end, map->vma->vm_end);
++ mstart = max(range->start, map_start);
++ mend = min(range->end, map_end);
+ pr_debug("map %d+%d (%lx %lx), range %lx %lx, mrange %lx %lx\n",
+- map->index, map->count,
+- map->vma->vm_start, map->vma->vm_end,
+- range->start, range->end, mstart, mend);
+- unmap_grant_pages(map,
+- (mstart - map->vma->vm_start) >> PAGE_SHIFT,
+- (mend - mstart) >> PAGE_SHIFT);
++ map->index, map->count, map_start, map_end,
++ range->start, range->end, mstart, mend);
++ unmap_grant_pages(map, (mstart - map_start) >> PAGE_SHIFT,
++ (mend - mstart) >> PAGE_SHIFT);
+
+ return true;
+ }
+@@ -1030,18 +1042,15 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ return -EINVAL;
+
+ pr_debug("map %d+%d at %lx (pgoff %lx)\n",
+- index, count, vma->vm_start, vma->vm_pgoff);
++ index, count, vma->vm_start, vma->vm_pgoff);
+
+ mutex_lock(&priv->lock);
+ map = gntdev_find_map_index(priv, index, count);
+ if (!map)
+ goto unlock_out;
+- if (use_ptemod && map->vma)
++ if (!atomic_add_unless(&map->in_use, 1, 1))
+ goto unlock_out;
+- if (atomic_read(&map->live_grants)) {
+- err = -EAGAIN;
+- goto unlock_out;
+- }
++
+ refcount_inc(&map->users);
+
+ vma->vm_ops = &gntdev_vmops;
+@@ -1062,15 +1071,16 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ map->flags |= GNTMAP_readonly;
+ }
+
++ map->pages_vm_start = vma->vm_start;
++
+ if (use_ptemod) {
+- map->vma = vma;
+ err = mmu_interval_notifier_insert_locked(
+ &map->notifier, vma->vm_mm, vma->vm_start,
+ vma->vm_end - vma->vm_start, &gntdev_mmu_ops);
+- if (err) {
+- map->vma = NULL;
++ if (err)
+ goto out_unlock_put;
+- }
++
++ map->notifier_init = true;
+ }
+ mutex_unlock(&priv->lock);
+
+@@ -1087,7 +1097,6 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ */
+ mmu_interval_read_begin(&map->notifier);
+
+- map->pages_vm_start = vma->vm_start;
+ err = apply_to_page_range(vma->vm_mm, vma->vm_start,
+ vma->vm_end - vma->vm_start,
+ find_grant_ptes, map);
+@@ -1116,13 +1125,8 @@ unlock_out:
+ out_unlock_put:
+ mutex_unlock(&priv->lock);
+ out_put_map:
+- if (use_ptemod) {
++ if (use_ptemod)
+ unmap_grant_pages(map, 0, map->count);
+- if (map->vma) {
+- mmu_interval_notifier_remove(&map->notifier);
+- map->vma = NULL;
+- }
+- }
+ gntdev_put_map(priv, map);
+ return err;
+ }
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index e0375ba9d0fed..4b9c095070ccf 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2190,7 +2190,16 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
+ int need_clear = 0;
+ u64 cache_gen;
+
+- if (!root)
++ /*
++ * Either no extent root (with ibadroots rescue option) or we have
++ * unsupported RO options. The fs can never be mounted read-write, so no
++ * need to waste time searching block group items.
++ *
++ * This also allows new extent tree related changes to be RO compat,
++ * no need for a full incompat flag.
++ */
++ if (!root || (btrfs_super_compat_ro_flags(info->super_copy) &
++ ~BTRFS_FEATURE_COMPAT_RO_SUPP))
+ return fill_dummy_bgs(info);
+
+ key.objectid = 0;
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 6914cd8024ba0..cfbbd7dc3c46b 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4888,6 +4888,9 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ !test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
+ lockdep_owner = BTRFS_FS_TREE_OBJECTID;
+
++ /* btrfs_clean_tree_block() accesses generation field. */
++ btrfs_set_header_generation(buf, trans->transid);
++
+ /*
+ * This needs to stay, because we could allocate a freed block from an
+ * old tree into a new tree, so we need to make sure this new block is
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 5a3f6e0d9688f..19e9df0c86496 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -523,6 +523,7 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ testend = 0;
+ }
+ while (1) {
++ bool ends_after_range = false;
+ int no_splits = 0;
+
+ modified = false;
+@@ -539,10 +540,12 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ write_unlock(&em_tree->lock);
+ break;
+ }
++ if (testend && em->start + em->len > start + len)
++ ends_after_range = true;
+ flags = em->flags;
+ gen = em->generation;
+ if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) {
+- if (testend && em->start + em->len >= start + len) {
++ if (ends_after_range) {
+ free_extent_map(em);
+ write_unlock(&em_tree->lock);
+ break;
+@@ -592,7 +595,7 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ split = split2;
+ split2 = NULL;
+ }
+- if (testend && em->start + em->len > start + len) {
++ if (ends_after_range) {
+ u64 diff = start + len - em->start;
+
+ split->start = start + len;
+@@ -630,14 +633,42 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ } else {
+ ret = add_extent_mapping(em_tree, split,
+ modified);
+- ASSERT(ret == 0); /* Logic error */
++ /* Logic error, shouldn't happen. */
++ ASSERT(ret == 0);
++ if (WARN_ON(ret != 0) && modified)
++ btrfs_set_inode_full_sync(inode);
+ }
+ free_extent_map(split);
+ split = NULL;
+ }
+ next:
+- if (extent_map_in_tree(em))
++ if (extent_map_in_tree(em)) {
++ /*
++ * If the extent map is still in the tree it means that
++ * either of the following is true:
++ *
++ * 1) It fits entirely in our range (doesn't end beyond
++ * it or starts before it);
++ *
++ * 2) It starts before our range and/or ends after our
++ * range, and we were not able to allocate the extent
++ * maps for split operations, @split and @split2.
++ *
++ * If we are at case 2) then we just remove the entire
++ * extent map - this is fine since if anyone needs it to
++ * access the subranges outside our range, will just
++ * load it again from the subvolume tree's file extent
++ * item. However if the extent map was in the list of
++ * modified extents, then we must mark the inode for a
++ * full fsync, otherwise a fast fsync will miss this
++ * extent if it's new and needs to be logged.
++ */
++ if ((em->start < start || ends_after_range) && modified) {
++ ASSERT(no_splits);
++ btrfs_set_inode_full_sync(inode);
++ }
+ remove_extent_mapping(em_tree, em);
++ }
+ write_unlock(&em_tree->lock);
+
+ /* once for us */
+@@ -2200,14 +2231,6 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+
+ atomic_inc(&root->log_batch);
+
+- /*
+- * Always check for the full sync flag while holding the inode's lock,
+- * to avoid races with other tasks. The flag must be either set all the
+- * time during logging or always off all the time while logging.
+- */
+- full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+- &BTRFS_I(inode)->runtime_flags);
+-
+ /*
+ * Before we acquired the inode's lock and the mmap lock, someone may
+ * have dirtied more pages in the target range. We need to make sure
+@@ -2232,6 +2255,17 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ goto out;
+ }
+
++ /*
++ * Always check for the full sync flag while holding the inode's lock,
++ * to avoid races with other tasks. The flag must be either set all the
++ * time during logging or always off all the time while logging.
++ * We check the flag here after starting delalloc above, because when
++ * running delalloc the full sync flag may be set if we need to drop
++ * extra extent map ranges due to temporary memory allocation failures.
++ */
++ full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
++ &BTRFS_I(inode)->runtime_flags);
++
+ /*
+ * We have to do this here to avoid the priority inversion of waiting on
+ * IO of a lower priority task while holding a transaction open.
+@@ -3810,6 +3844,7 @@ const struct file_operations btrfs_file_operations = {
+ .mmap = btrfs_file_mmap,
+ .open = btrfs_file_open,
+ .release = btrfs_release_file,
++ .get_unmapped_area = thp_get_unmapped_area,
+ .fsync = btrfs_sync_file,
+ .fallocate = btrfs_fallocate,
+ .unlocked_ioctl = btrfs_ioctl,
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 996da650ecdc3..015b0440df5dc 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info, u64 offset,
+ u64 bytes, bool update_stats);
+
++static void __btrfs_remove_free_space_cache_locked(
++ struct btrfs_free_space_ctl *ctl)
++{
++ struct btrfs_free_space *info;
++ struct rb_node *node;
++
++ while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
++ info = rb_entry(node, struct btrfs_free_space, offset_index);
++ if (!info->bitmap) {
++ unlink_free_space(ctl, info, true);
++ kmem_cache_free(btrfs_free_space_cachep, info);
++ } else {
++ free_bitmap(ctl, info);
++ }
++
++ cond_resched_lock(&ctl->tree_lock);
++ }
++}
++
+ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
+ struct btrfs_path *path,
+ u64 offset)
+@@ -693,6 +712,12 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
+
+ max_bitmaps = max_t(u64, max_bitmaps, 1);
+
++ if (ctl->total_bitmaps > max_bitmaps)
++ btrfs_err(block_group->fs_info,
++"invalid free space control: bg start=%llu len=%llu total_bitmaps=%u unit=%u max_bitmaps=%llu bytes_per_bg=%llu",
++ block_group->start, block_group->length,
++ ctl->total_bitmaps, ctl->unit, max_bitmaps,
++ bytes_per_bg);
+ ASSERT(ctl->total_bitmaps <= max_bitmaps);
+
+ /*
+@@ -875,7 +900,14 @@ out:
+ return ret;
+ free_cache:
+ io_ctl_drop_pages(&io_ctl);
+- __btrfs_remove_free_space_cache(ctl);
++
++ /*
++ * We need to call the _locked variant so we don't try to update the
++ * discard counters.
++ */
++ spin_lock(&ctl->tree_lock);
++ __btrfs_remove_free_space_cache_locked(ctl);
++ spin_unlock(&ctl->tree_lock);
+ goto out;
+ }
+
+@@ -1001,7 +1033,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+ if (ret == 0)
+ ret = 1;
+ } else {
++ /*
++ * We need to call the _locked variant so we don't try to update
++ * the discard counters.
++ */
++ spin_lock(&tmp_ctl.tree_lock);
+ __btrfs_remove_free_space_cache(&tmp_ctl);
++ spin_unlock(&tmp_ctl.tree_lock);
+ btrfs_warn(fs_info,
+ "block group %llu has wrong amount of free space",
+ block_group->start);
+@@ -2964,25 +3002,6 @@ static void __btrfs_return_cluster_to_free_space(
+ btrfs_put_block_group(block_group);
+ }
+
+-static void __btrfs_remove_free_space_cache_locked(
+- struct btrfs_free_space_ctl *ctl)
+-{
+- struct btrfs_free_space *info;
+- struct rb_node *node;
+-
+- while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
+- info = rb_entry(node, struct btrfs_free_space, offset_index);
+- if (!info->bitmap) {
+- unlink_free_space(ctl, info, true);
+- kmem_cache_free(btrfs_free_space_cachep, info);
+- } else {
+- free_bitmap(ctl, info);
+- }
+-
+- cond_resched_lock(&ctl->tree_lock);
+- }
+-}
+-
+ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
+ {
+ spin_lock(&ctl->tree_lock);
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index db723c0026bd2..ba323dcb0a0b8 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1174,6 +1174,21 @@ out_add_root:
+ fs_info->qgroup_rescan_running = true;
+ btrfs_queue_work(fs_info->qgroup_rescan_workers,
+ &fs_info->qgroup_rescan_work);
++ } else {
++ /*
++ * We have set both BTRFS_FS_QUOTA_ENABLED and
++ * BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with
++ * -EINPROGRESS. That can happen because someone started the
++ * rescan worker by calling quota rescan ioctl before we
++ * attempted to initialize the rescan worker. Failure due to
++ * quotas disabled in the meanwhile is not possible, because
++ * we are holding a write lock on fs_info->subvol_sem, which
++ * is also acquired when disabling quotas.
++ * Ignore such error, and any other error would need to undo
++ * everything we did in the transaction we just committed.
++ */
++ ASSERT(ret == -EINPROGRESS);
++ ret = 0;
+ }
+
+ out_free_path:
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 3afe5fa50a631..7d9b09e3ca70c 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -729,6 +729,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
+ dev = sblock->sectors[0]->dev;
+ fs_info = sblock->sctx->fs_info;
+
++ /* Super block error, no need to search extent tree. */
++ if (sblock->sectors[0]->flags & BTRFS_EXTENT_FLAG_SUPER) {
++ btrfs_warn_in_rcu(fs_info, "%s on device %s, physical %llu",
++ errstr, rcu_str_deref(dev->name),
++ sblock->sectors[0]->physical);
++ return;
++ }
+ path = btrfs_alloc_path();
+ if (!path)
+ return;
+@@ -804,7 +811,7 @@ static inline void scrub_put_recover(struct btrfs_fs_info *fs_info,
+ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ {
+ struct scrub_ctx *sctx = sblock_to_check->sctx;
+- struct btrfs_device *dev;
++ struct btrfs_device *dev = sblock_to_check->sectors[0]->dev;
+ struct btrfs_fs_info *fs_info;
+ u64 logical;
+ unsigned int failed_mirror_index;
+@@ -825,13 +832,15 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ fs_info = sctx->fs_info;
+ if (sblock_to_check->sectors[0]->flags & BTRFS_EXTENT_FLAG_SUPER) {
+ /*
+- * if we find an error in a super block, we just report it.
++ * If we find an error in a super block, we just report it.
+ * They will get written with the next transaction commit
+ * anyway
+ */
++ scrub_print_warning("super block error", sblock_to_check);
+ spin_lock(&sctx->stat_lock);
+ ++sctx->stat.super_errors;
+ spin_unlock(&sctx->stat_lock);
++ btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_CORRUPTION_ERRS);
+ return 0;
+ }
+ logical = sblock_to_check->sectors[0]->logical;
+@@ -840,7 +849,6 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ is_metadata = !(sblock_to_check->sectors[0]->flags &
+ BTRFS_EXTENT_FLAG_DATA);
+ have_csum = sblock_to_check->sectors[0]->have_csum;
+- dev = sblock_to_check->sectors[0]->dev;
+
+ if (!sctx->is_dev_replace && btrfs_repair_one_zone(fs_info, logical))
+ return 0;
+@@ -1762,7 +1770,7 @@ static int scrub_checksum(struct scrub_block *sblock)
+ else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ ret = scrub_checksum_tree_block(sblock);
+ else if (flags & BTRFS_EXTENT_FLAG_SUPER)
+- (void)scrub_checksum_super(sblock);
++ ret = scrub_checksum_super(sblock);
+ else
+ WARN_ON(1);
+ if (ret)
+@@ -1901,23 +1909,6 @@ static int scrub_checksum_super(struct scrub_block *sblock)
+ if (memcmp(calculated_csum, s->csum, sctx->fs_info->csum_size))
+ ++fail_cor;
+
+- if (fail_cor + fail_gen) {
+- /*
+- * if we find an error in a super block, we just report it.
+- * They will get written with the next transaction commit
+- * anyway
+- */
+- spin_lock(&sctx->stat_lock);
+- ++sctx->stat.super_errors;
+- spin_unlock(&sctx->stat_lock);
+- if (fail_cor)
+- btrfs_dev_stat_inc_and_print(sector->dev,
+- BTRFS_DEV_STAT_CORRUPTION_ERRS);
+- else
+- btrfs_dev_stat_inc_and_print(sector->dev,
+- BTRFS_DEV_STAT_GENERATION_ERRS);
+- }
+-
+ return fail_cor + fail_gen;
+ }
+
+@@ -4102,6 +4093,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ int ret;
+ struct btrfs_device *dev;
+ unsigned int nofs_flag;
++ bool need_commit = false;
+
+ if (btrfs_fs_closing(fs_info))
+ return -EAGAIN;
+@@ -4205,6 +4197,12 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ */
+ nofs_flag = memalloc_nofs_save();
+ if (!is_dev_replace) {
++ u64 old_super_errors;
++
++ spin_lock(&sctx->stat_lock);
++ old_super_errors = sctx->stat.super_errors;
++ spin_unlock(&sctx->stat_lock);
++
+ btrfs_info(fs_info, "scrub: started on devid %llu", devid);
+ /*
+ * by holding device list mutex, we can
+@@ -4213,6 +4211,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ mutex_lock(&fs_info->fs_devices->device_list_mutex);
+ ret = scrub_supers(sctx, dev);
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
++
++ spin_lock(&sctx->stat_lock);
++ /*
++ * Super block errors found, but we can not commit transaction
++ * at current context, since btrfs_commit_transaction() needs
++ * to pause the current running scrub (hold by ourselves).
++ */
++ if (sctx->stat.super_errors > old_super_errors && !sctx->readonly)
++ need_commit = true;
++ spin_unlock(&sctx->stat_lock);
+ }
+
+ if (!ret)
+@@ -4239,6 +4247,25 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ scrub_workers_put(fs_info);
+ scrub_put_ctx(sctx);
+
++ /*
++ * We found some super block errors before, now try to force a
++ * transaction commit, as scrub has finished.
++ */
++ if (need_commit) {
++ struct btrfs_trans_handle *trans;
++
++ trans = btrfs_start_transaction(fs_info->tree_root, 0);
++ if (IS_ERR(trans)) {
++ ret = PTR_ERR(trans);
++ btrfs_err(fs_info,
++ "scrub: failed to start transaction to fix super block errors: %d", ret);
++ return ret;
++ }
++ ret = btrfs_commit_transaction(trans);
++ if (ret < 0)
++ btrfs_err(fs_info,
++ "scrub: failed to commit transaction to fix super block errors: %d", ret);
++ }
+ return ret;
+ out:
+ scrub_workers_put(fs_info);
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index f89beac3c6656..ad3ce9700eaf3 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -626,6 +626,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
+ int saved_compress_level;
+ bool saved_compress_force;
+ int no_compress = 0;
++ const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state);
+
+ if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE))
+ btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE);
+@@ -1137,10 +1138,12 @@ out:
+ }
+ if (!ret)
+ ret = btrfs_check_mountopts_zoned(info);
+- if (!ret && btrfs_test_opt(info, SPACE_CACHE))
+- btrfs_info(info, "disk space caching is enabled");
+- if (!ret && btrfs_test_opt(info, FREE_SPACE_TREE))
+- btrfs_info(info, "using free space tree");
++ if (!ret && !remounting) {
++ if (btrfs_test_opt(info, SPACE_CACHE))
++ btrfs_info(info, "disk space caching is enabled");
++ if (btrfs_test_opt(info, FREE_SPACE_TREE))
++ btrfs_info(info, "using free space tree");
++ }
+ return ret;
+ }
+
+@@ -2112,6 +2115,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ ret = -EINVAL;
+ goto restore;
+ }
++ if (btrfs_super_compat_ro_flags(fs_info->super_copy) &
++ ~BTRFS_FEATURE_COMPAT_RO_SUPP) {
++ btrfs_err(fs_info,
++ "can not remount read-write due to unsupported optional flags 0x%llx",
++ btrfs_super_compat_ro_flags(fs_info->super_copy) &
++ ~BTRFS_FEATURE_COMPAT_RO_SUPP);
++ ret = -EINVAL;
++ goto restore;
++ }
+ if (fs_info->fs_devices->rw_devices == 0) {
+ ret = -EACCES;
+ goto restore;
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 3bc94bcc7177e..71386978858eb 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -639,7 +639,7 @@ cifs_chan_is_iface_active(struct cifs_ses *ses,
+ int
+ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
+ int
+-SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon);
++SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount);
+
+ void extract_unc_hostname(const char *unc, const char **h, size_t *len);
+ int copy_path_name(char *dst, const char *src);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 7ae6f2c08153e..e960dda893c63 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -155,7 +155,7 @@ static void smb2_query_server_interfaces(struct work_struct *work)
+ /*
+ * query server network interfaces, in case they change
+ */
+- rc = SMB3_request_interfaces(0, tcon);
++ rc = SMB3_request_interfaces(0, tcon, false);
+ if (rc) {
+ cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
+ __func__, rc);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 6f38b134a3468..7d756721e1a68 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -4271,6 +4271,15 @@ static ssize_t __cifs_readv(
+ len = ctx->len;
+ }
+
++ if (direct) {
++ rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
++ offset, offset + len - 1);
++ if (rc) {
++ kref_put(&ctx->refcount, cifs_aio_ctx_release);
++ return -EAGAIN;
++ }
++ }
++
+ /* grab a lock here due to read response handlers can access ctx */
+ mutex_lock(&ctx->aio_mutex);
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 421be43af4253..b02552e5f3eeb 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -512,8 +512,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
+
+ static int
+ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+- size_t buf_len,
+- struct cifs_ses *ses)
++ size_t buf_len, struct cifs_ses *ses, bool in_mount)
+ {
+ struct network_interface_info_ioctl_rsp *p;
+ struct sockaddr_in *addr4;
+@@ -543,6 +542,20 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ }
+ spin_unlock(&ses->iface_lock);
+
++ /*
++ * Samba server e.g. can return an empty interface list in some cases,
++ * which would only be a problem if we were requesting multichannel
++ */
++ if (bytes_left == 0) {
++ /* avoid spamming logs every 10 minutes, so log only in mount */
++ if ((ses->chan_max > 1) && in_mount)
++ cifs_dbg(VFS,
++ "empty network interface list returned by server %s\n",
++ ses->server->hostname);
++ rc = -EINVAL;
++ goto out;
++ }
++
+ while (bytes_left >= sizeof(*p)) {
+ memset(&tmp_iface, 0, sizeof(tmp_iface));
+ tmp_iface.speed = le64_to_cpu(p->LinkSpeed);
+@@ -673,7 +686,7 @@ out:
+ }
+
+ int
+-SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
++SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount)
+ {
+ int rc;
+ unsigned int ret_data_len = 0;
+@@ -693,7 +706,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
+ goto out;
+ }
+
+- rc = parse_server_interfaces(out_buf, ret_data_len, ses);
++ rc = parse_server_interfaces(out_buf, ret_data_len, ses, in_mount);
+ if (rc)
+ goto out;
+
+@@ -729,7 +742,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
+ if (rc)
+ return;
+
+- SMB3_request_interfaces(xid, tcon);
++ SMB3_request_interfaces(xid, tcon, true /* called during mount */);
+
+ SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+ FS_ATTRIBUTE_INFORMATION);
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 6352ab32c7e7a..5016d742576d0 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1169,9 +1169,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+ pneg_inbuf->Dialects[0] =
+ cpu_to_le16(server->vals->protocol_id);
+ pneg_inbuf->DialectCount = cpu_to_le16(1);
+- /* structure is big enough for 3 dialects, sending only 1 */
++ /* structure is big enough for 4 dialects, sending only 1 */
+ inbuflen = sizeof(*pneg_inbuf) -
+- sizeof(pneg_inbuf->Dialects[0]) * 2;
++ sizeof(pneg_inbuf->Dialects[0]) * 3;
+ }
+
+ rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+@@ -2411,7 +2411,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+ unsigned int acelen, acl_size, ace_count;
+ unsigned int owner_offset = 0;
+ unsigned int group_offset = 0;
+- struct smb3_acl acl;
++ struct smb3_acl acl = {};
+
+ *len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
+
+@@ -2484,6 +2484,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+ acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
+ acl.AclSize = cpu_to_le16(acl_size);
+ acl.AceCount = cpu_to_le16(ace_count);
++ /* acl.Sbz1 and Sbz2 MBZ so are not set here, but initialized above */
+ memcpy(aclptr, &acl, sizeof(struct smb3_acl));
+
+ buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index 1a5fc3314dbf5..4640fc4a8b133 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -225,9 +225,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ struct smb_rqst drqst;
+
+ ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+- if (!ses) {
++ if (unlikely(!ses)) {
+ cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
+- return 0;
++ return -ENOENT;
+ }
+
+ memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
+@@ -557,8 +557,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ u8 key[SMB3_SIGN_KEY_SIZE];
+
+ rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+- if (rc)
+- return 0;
++ if (unlikely(rc)) {
++ cifs_server_dbg(VFS, "%s: Could not get signing key\n", __func__);
++ return rc;
++ }
+
+ if (allocate_crypto) {
+ rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc);
+diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
+index 19ef136f9e4fc..a44cc42b63171 100644
+--- a/fs/dlm/ast.c
++++ b/fs/dlm/ast.c
+@@ -200,13 +200,13 @@ void dlm_add_cb(struct dlm_lkb *lkb, uint32_t flags, int mode, int status,
+ if (!prev_seq) {
+ kref_get(&lkb->lkb_ref);
+
++ mutex_lock(&ls->ls_cb_mutex);
+ if (test_bit(LSFL_CB_DELAY, &ls->ls_flags)) {
+- mutex_lock(&ls->ls_cb_mutex);
+ list_add(&lkb->lkb_cb_list, &ls->ls_cb_delay);
+- mutex_unlock(&ls->ls_cb_mutex);
+ } else {
+ queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work);
+ }
++ mutex_unlock(&ls->ls_cb_mutex);
+ }
+ out:
+ mutex_unlock(&lkb->lkb_cb_mutex);
+@@ -288,7 +288,9 @@ void dlm_callback_stop(struct dlm_ls *ls)
+
+ void dlm_callback_suspend(struct dlm_ls *ls)
+ {
++ mutex_lock(&ls->ls_cb_mutex);
+ set_bit(LSFL_CB_DELAY, &ls->ls_flags);
++ mutex_unlock(&ls->ls_cb_mutex);
+
+ if (ls->ls_callback_wq)
+ flush_workqueue(ls->ls_callback_wq);
+diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
+index dac7eb75dba95..4ac0478c07267 100644
+--- a/fs/dlm/lock.c
++++ b/fs/dlm/lock.c
+@@ -2864,17 +2864,9 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args)
+ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
+ struct dlm_args *args)
+ {
+- int rv = -EINVAL;
++ int rv = -EBUSY;
+
+ if (args->flags & DLM_LKF_CONVERT) {
+- if (lkb->lkb_flags & DLM_IFL_MSTCPY)
+- goto out;
+-
+- if (args->flags & DLM_LKF_QUECVT &&
+- !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
+- goto out;
+-
+- rv = -EBUSY;
+ if (lkb->lkb_status != DLM_LKSTS_GRANTED)
+ goto out;
+
+@@ -2884,6 +2876,14 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
+
+ if (is_overlap(lkb))
+ goto out;
++
++ rv = -EINVAL;
++ if (lkb->lkb_flags & DLM_IFL_MSTCPY)
++ goto out;
++
++ if (args->flags & DLM_LKF_QUECVT &&
++ !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
++ goto out;
+ }
+
+ lkb->lkb_exflags = args->flags;
+@@ -3623,7 +3623,7 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb,
+ case cpu_to_le32(DLM_MSG_REQUEST_REPLY):
+ case cpu_to_le32(DLM_MSG_CONVERT_REPLY):
+ case cpu_to_le32(DLM_MSG_GRANT):
+- if (!lkb->lkb_lvbptr)
++ if (!lkb->lkb_lvbptr || !(lkb->lkb_exflags & DLM_LKF_VALBLK))
+ break;
+ memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
+ break;
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index a4e84e8d94c87..59f64c596233b 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1336,6 +1336,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation,
+ return NULL;
+ }
+
++ /* for dlm_lowcomms_commit_msg() */
++ kref_get(&msg->ref);
+ /* we assume if successful commit must called */
+ msg->idx = idx;
+ return msg;
+@@ -1375,6 +1377,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg)
+ {
+ _dlm_lowcomms_commit_msg(msg);
+ srcu_read_unlock(&connections_srcu, msg->idx);
++ /* because dlm_lowcomms_new_msg() */
++ kref_put(&msg->ref, dlm_msg_release);
+ }
+ #endif
+
+diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
+index 95a403720e8c7..16cf9a2835574 100644
+--- a/fs/erofs/inode.c
++++ b/fs/erofs/inode.c
+@@ -214,7 +214,7 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
+
+ /* if it cannot be handled with fast symlink scheme */
+ if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
+- inode->i_size >= EROFS_BLKSIZ) {
++ inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) {
+ inode->i_op = &erofs_symlink_iops;
+ return 0;
+ }
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index 3173debeaa5a1..9716d355a63ef 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -879,7 +879,7 @@ static void erofs_kill_sb(struct super_block *sb)
+ WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC);
+
+ if (erofs_is_fscache_mode(sb))
+- generic_shutdown_super(sb);
++ kill_anon_super(sb);
+ else
+ kill_block_super(sb);
+
+diff --git a/fs/eventfd.c b/fs/eventfd.c
+index 3627dd7d25db8..c0ffee99ad238 100644
+--- a/fs/eventfd.c
++++ b/fs/eventfd.c
+@@ -69,17 +69,17 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ * it returns false, the eventfd_signal() call should be deferred to a
+ * safe context.
+ */
+- if (WARN_ON_ONCE(current->in_eventfd_signal))
++ if (WARN_ON_ONCE(current->in_eventfd))
+ return 0;
+
+ spin_lock_irqsave(&ctx->wqh.lock, flags);
+- current->in_eventfd_signal = 1;
++ current->in_eventfd = 1;
+ if (ULLONG_MAX - ctx->count < n)
+ n = ULLONG_MAX - ctx->count;
+ ctx->count += n;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked_poll(&ctx->wqh, EPOLLIN);
+- current->in_eventfd_signal = 0;
++ current->in_eventfd = 0;
+ spin_unlock_irqrestore(&ctx->wqh.lock, flags);
+
+ return n;
+@@ -253,8 +253,10 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
+ __set_current_state(TASK_RUNNING);
+ }
+ eventfd_ctx_do_read(ctx, &ucnt);
++ current->in_eventfd = 1;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked_poll(&ctx->wqh, EPOLLOUT);
++ current->in_eventfd = 0;
+ spin_unlock_irq(&ctx->wqh.lock);
+ if (unlikely(copy_to_iter(&ucnt, sizeof(ucnt), to) != sizeof(ucnt)))
+ return -EFAULT;
+@@ -301,8 +303,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
+ }
+ if (likely(res > 0)) {
+ ctx->count += ucnt;
++ current->in_eventfd = 1;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked_poll(&ctx->wqh, EPOLLIN);
++ current->in_eventfd = 0;
+ }
+ spin_unlock_irq(&ctx->wqh.lock);
+
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index 252c742379cfb..03f2af98b1b48 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -163,7 +163,7 @@ static void ext2_put_super (struct super_block * sb)
+ db_count = sbi->s_gdb_count;
+ for (i = 0; i < db_count; i++)
+ brelse(sbi->s_group_desc[i]);
+- kfree(sbi->s_group_desc);
++ kvfree(sbi->s_group_desc);
+ kfree(sbi->s_debts);
+ percpu_counter_destroy(&sbi->s_freeblocks_counter);
+ percpu_counter_destroy(&sbi->s_freeinodes_counter);
+@@ -1052,6 +1052,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ sbi->s_blocks_per_group);
+ goto failed_mount;
+ }
++ /* At least inode table, bitmaps, and sb have to fit in one group */
++ if (sbi->s_blocks_per_group <= sbi->s_itb_per_group + 3) {
++ ext2_msg(sb, KERN_ERR,
++ "error: #blocks per group smaller than metadata size: %lu <= %lu",
++ sbi->s_blocks_per_group, sbi->s_inodes_per_group + 3);
++ goto failed_mount;
++ }
+ if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
+ ext2_msg(sb, KERN_ERR,
+ "error: #fragments per group too big: %lu",
+@@ -1065,9 +1072,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ sbi->s_inodes_per_group);
+ goto failed_mount;
+ }
++ if (sb_bdev_nr_blocks(sb) < le32_to_cpu(es->s_blocks_count)) {
++ ext2_msg(sb, KERN_ERR,
++ "bad geometry: block count %u exceeds size of device (%u blocks)",
++ le32_to_cpu(es->s_blocks_count),
++ (unsigned)sb_bdev_nr_blocks(sb));
++ goto failed_mount;
++ }
+
+- if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
+- goto cantfind_ext2;
+ sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+ le32_to_cpu(es->s_first_data_block) - 1)
+ / EXT2_BLOCKS_PER_GROUP(sb)) + 1;
+@@ -1080,7 +1092,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ }
+ db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+ EXT2_DESC_PER_BLOCK(sb);
+- sbi->s_group_desc = kmalloc_array(db_count,
++ sbi->s_group_desc = kvmalloc_array(db_count,
+ sizeof(struct buffer_head *),
+ GFP_KERNEL);
+ if (sbi->s_group_desc == NULL) {
+@@ -1206,7 +1218,7 @@ failed_mount2:
+ for (i = 0; i < db_count; i++)
+ brelse(sbi->s_group_desc[i]);
+ failed_mount_group_desc:
+- kfree(sbi->s_group_desc);
++ kvfree(sbi->s_group_desc);
+ kfree(sbi->s_debts);
+ failed_mount:
+ brelse(bh);
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index 2af962cbb835f..b26f304baa52e 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -874,22 +874,25 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc)
+ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_INODE);
+ tl.fc_len = cpu_to_le16(inode_len + sizeof(fc_inode.fc_ino));
+
++ ret = -ECANCELED;
+ dst = ext4_fc_reserve_space(inode->i_sb,
+ sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc);
+ if (!dst)
+- return -ECANCELED;
++ goto err;
+
+ if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc))
+- return -ECANCELED;
++ goto err;
+ dst += sizeof(tl);
+ if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc))
+- return -ECANCELED;
++ goto err;
+ dst += sizeof(fc_inode);
+ if (!ext4_fc_memcpy(inode->i_sb, dst, (u8 *)ext4_raw_inode(&iloc),
+ inode_len, crc))
+- return -ECANCELED;
+-
+- return 0;
++ goto err;
++ ret = 0;
++err:
++ brelse(iloc.bh);
++ return ret;
+ }
+
+ /*
+@@ -1491,13 +1494,15 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
+ if (state->fc_modified_inodes[i] == ino)
+ return 0;
+ if (state->fc_modified_inodes_used == state->fc_modified_inodes_size) {
+- state->fc_modified_inodes = krealloc(
+- state->fc_modified_inodes,
++ int *fc_modified_inodes;
++
++ fc_modified_inodes = krealloc(state->fc_modified_inodes,
+ sizeof(int) * (state->fc_modified_inodes_size +
+ EXT4_FC_REPLAY_REALLOC_INCREMENT),
+ GFP_KERNEL);
+- if (!state->fc_modified_inodes)
++ if (!fc_modified_inodes)
+ return -ENOMEM;
++ state->fc_modified_inodes = fc_modified_inodes;
+ state->fc_modified_inodes_size +=
+ EXT4_FC_REPLAY_REALLOC_INCREMENT;
+ }
+@@ -1682,15 +1687,18 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
+ if (replay && state->fc_regions_used != state->fc_regions_valid)
+ state->fc_regions_used = state->fc_regions_valid;
+ if (state->fc_regions_used == state->fc_regions_size) {
++ struct ext4_fc_alloc_region *fc_regions;
++
++ fc_regions = krealloc(state->fc_regions,
++ sizeof(struct ext4_fc_alloc_region) *
++ (state->fc_regions_size +
++ EXT4_FC_REPLAY_REALLOC_INCREMENT),
++ GFP_KERNEL);
++ if (!fc_regions)
++ return -ENOMEM;
+ state->fc_regions_size +=
+ EXT4_FC_REPLAY_REALLOC_INCREMENT;
+- state->fc_regions = krealloc(
+- state->fc_regions,
+- state->fc_regions_size *
+- sizeof(struct ext4_fc_alloc_region),
+- GFP_KERNEL);
+- if (!state->fc_regions)
+- return -ENOMEM;
++ state->fc_regions = fc_regions;
+ }
+ region = &state->fc_regions[state->fc_regions_used++];
+ region->ino = ino;
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 109d07629f81f..847a2f806b8f6 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -528,6 +528,12 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
+ ret = -EAGAIN;
+ goto out;
+ }
++ /*
++ * Make sure inline data cannot be created anymore since we are going
++ * to allocate blocks for DIO. We know the inode does not have any
++ * inline data now because ext4_dio_supported() checked for that.
++ */
++ ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+
+ offset = iocb->ki_pos;
+ count = ret;
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 601214453c3ae..6da73be32bff3 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1188,6 +1188,13 @@ retry_grab:
+ page = grab_cache_page_write_begin(mapping, index);
+ if (!page)
+ return -ENOMEM;
++ /*
++ * The same as page allocation, we prealloc buffer heads before
++ * starting the handle.
++ */
++ if (!page_has_buffers(page))
++ create_empty_buffers(page, inode->i_sb->s_blocksize, 0);
++
+ unlock_page(page);
+
+ retry_journal:
+@@ -5342,6 +5349,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+ int error, rc = 0;
+ int orphan = 0;
+ const unsigned int ia_valid = attr->ia_valid;
++ bool inc_ivers = true;
+
+ if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
+ return -EIO;
+@@ -5425,8 +5433,8 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+ return -EINVAL;
+ }
+
+- if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size)
+- inode_inc_iversion(inode);
++ if (attr->ia_size == inode->i_size)
++ inc_ivers = false;
+
+ if (shrink) {
+ if (ext4_should_order_data(inode)) {
+@@ -5528,6 +5536,8 @@ out_mmap_sem:
+ }
+
+ if (!error) {
++ if (inc_ivers)
++ inode_inc_iversion(inode);
+ setattr_copy(mnt_userns, inode, attr);
+ mark_inode_dirty(inode);
+ }
+@@ -5731,9 +5741,6 @@ int ext4_mark_iloc_dirty(handle_t *handle,
+ }
+ ext4_fc_track_inode(handle, inode);
+
+- if (IS_I_VERSION(inode))
+- inode_inc_iversion(inode);
+-
+ /* the do_update_inode consumes one bh->b_count */
+ get_bh(iloc->bh);
+
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 3cf3ec4b1c214..ad3a294a88eb2 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -452,6 +452,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ swap_inode_data(inode, inode_bl);
+
+ inode->i_ctime = inode_bl->i_ctime = current_time(inode);
++ inode_inc_iversion(inode);
+
+ inode->i_generation = prandom_u32();
+ inode_bl->i_generation = prandom_u32();
+@@ -665,6 +666,7 @@ static int ext4_ioctl_setflags(struct inode *inode,
+ ext4_set_inode_flags(inode, false);
+
+ inode->i_ctime = current_time(inode);
++ inode_inc_iversion(inode);
+
+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ flags_err:
+@@ -775,6 +777,7 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+
+ EXT4_I(inode)->i_projid = kprojid;
+ inode->i_ctime = current_time(inode);
++ inode_inc_iversion(inode);
+ out_dirty:
+ rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ if (!err)
+@@ -1257,6 +1260,7 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ err = ext4_reserve_inode_write(handle, inode, &iloc);
+ if (err == 0) {
+ inode->i_ctime = current_time(inode);
++ inode_inc_iversion(inode);
+ inode->i_generation = generation;
+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ }
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 3a31b662f6619..4183a4cb4a21e 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -85,15 +85,20 @@ static struct buffer_head *ext4_append(handle_t *handle,
+ return bh;
+ inode->i_size += inode->i_sb->s_blocksize;
+ EXT4_I(inode)->i_disksize = inode->i_size;
++ err = ext4_mark_inode_dirty(handle, inode);
++ if (err)
++ goto out;
+ BUFFER_TRACE(bh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+ EXT4_JTR_NONE);
+- if (err) {
+- brelse(bh);
+- ext4_std_error(inode->i_sb, err);
+- return ERR_PTR(err);
+- }
++ if (err)
++ goto out;
+ return bh;
++
++out:
++ brelse(bh);
++ ext4_std_error(inode->i_sb, err);
++ return ERR_PTR(err);
+ }
+
+ static int ext4_dx_csum_verify(struct inode *inode,
+@@ -126,7 +131,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
+ struct ext4_dir_entry *dirent;
+ int is_dx_block = 0;
+
+- if (block >= inode->i_size) {
++ if (block >= inode->i_size >> inode->i_blkbits) {
+ ext4_error_inode(inode, func, line, block,
+ "Attempting to read directory block (%u) that is past i_size (%llu)",
+ block, inode->i_size);
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index fea2a68d067b0..6dfe9ccae0c50 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -2122,7 +2122,7 @@ retry:
+ goto out;
+ }
+
+- if (ext4_blocks_count(es) == n_blocks_count)
++ if (ext4_blocks_count(es) == n_blocks_count && n_blocks_count_retry == 0)
+ goto out;
+
+ err = ext4_alloc_flex_bg_array(sb, n_group + 1);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 9a66abcca1a85..091db733834ee 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -205,19 +205,12 @@ int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags, bh_end_io_t *end_io
+
+ int ext4_read_bh_lock(struct buffer_head *bh, blk_opf_t op_flags, bool wait)
+ {
+- if (trylock_buffer(bh)) {
+- if (wait)
+- return ext4_read_bh(bh, op_flags, NULL);
++ lock_buffer(bh);
++ if (!wait) {
+ ext4_read_bh_nowait(bh, op_flags, NULL);
+ return 0;
+ }
+- if (wait) {
+- wait_on_buffer(bh);
+- if (buffer_uptodate(bh))
+- return 0;
+- return -EIO;
+- }
+- return 0;
++ return ext4_read_bh(bh, op_flags, NULL);
+ }
+
+ /*
+@@ -264,7 +257,8 @@ void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+ struct buffer_head *bh = sb_getblk_gfp(sb, block, 0);
+
+ if (likely(bh)) {
+- ext4_read_bh_lock(bh, REQ_RAHEAD, false);
++ if (trylock_buffer(bh))
++ ext4_read_bh_nowait(bh, REQ_RAHEAD, NULL);
+ brelse(bh);
+ }
+ }
+@@ -1585,7 +1579,7 @@ enum {
+ Opt_inlinecrypt,
+ Opt_usrjquota, Opt_grpjquota, Opt_quota,
+ Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
+- Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version,
++ Opt_usrquota, Opt_grpquota, Opt_prjquota,
+ Opt_dax, Opt_dax_always, Opt_dax_inode, Opt_dax_never,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error,
+ Opt_nowarn_on_error, Opt_mblk_io_submit, Opt_debug_want_extra_isize,
+@@ -1694,7 +1688,7 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
+ fsparam_flag ("barrier", Opt_barrier),
+ fsparam_u32 ("barrier", Opt_barrier),
+ fsparam_flag ("nobarrier", Opt_nobarrier),
+- fsparam_flag ("i_version", Opt_i_version),
++ fsparam_flag ("i_version", Opt_removed),
+ fsparam_flag ("dax", Opt_dax),
+ fsparam_enum ("dax", Opt_dax_type, ext4_param_dax),
+ fsparam_u32 ("stripe", Opt_stripe),
+@@ -2140,11 +2134,6 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ case Opt_abort:
+ ctx_set_mount_flag(ctx, EXT4_MF_FS_ABORTED);
+ return 0;
+- case Opt_i_version:
+- ext4_msg(NULL, KERN_WARNING, deprecated_msg, param->key, "5.20");
+- ext4_msg(NULL, KERN_WARNING, "Use iversion instead\n");
+- ctx_set_flags(ctx, SB_I_VERSION);
+- return 0;
+ case Opt_inlinecrypt:
+ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
+ ctx_set_flags(ctx, SB_INLINECRYPT);
+@@ -2814,14 +2803,6 @@ static void ext4_apply_options(struct fs_context *fc, struct super_block *sb)
+ sb->s_flags &= ~ctx->mask_s_flags;
+ sb->s_flags |= ctx->vals_s_flags;
+
+- /*
+- * i_version differs from common mount option iversion so we have
+- * to let vfs know that it was set, otherwise it would get cleared
+- * on remount
+- */
+- if (ctx->mask_s_flags & SB_I_VERSION)
+- fc->sb_flags |= SB_I_VERSION;
+-
+ #define APPLY(X) ({ if (ctx->spec & EXT4_SPEC_##X) sbi->X = ctx->X; })
+ APPLY(s_commit_interval);
+ APPLY(s_stripe);
+@@ -2970,8 +2951,6 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+ SEQ_OPTS_PRINT("min_batch_time=%u", sbi->s_min_batch_time);
+ if (nodefs || sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME)
+ SEQ_OPTS_PRINT("max_batch_time=%u", sbi->s_max_batch_time);
+- if (sb->s_flags & SB_I_VERSION)
+- SEQ_OPTS_PUTS("i_version");
+ if (nodefs || sbi->s_stripe)
+ SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe);
+ if (nodefs || EXT4_MOUNT_DATA_FLAGS &
+@@ -3767,6 +3746,7 @@ static int ext4_lazyinit_thread(void *arg)
+ unsigned long next_wakeup, cur;
+
+ BUG_ON(NULL == eli);
++ set_freezable();
+
+ cont_thread:
+ while (true) {
+@@ -3982,9 +3962,9 @@ int ext4_register_li_request(struct super_block *sb,
+ goto out;
+ }
+
+- if (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) &&
+- (first_not_zeroed == ngroups || sb_rdonly(sb) ||
+- !test_opt(sb, INIT_INODE_TABLE)))
++ if (sb_rdonly(sb) ||
++ (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) &&
++ (first_not_zeroed == ngroups || !test_opt(sb, INIT_INODE_TABLE))))
+ goto out;
+
+ elr = ext4_li_request_new(sb, first_not_zeroed);
+@@ -4640,6 +4620,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+ sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
+ (test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
+
++ /* i_version is always enabled now */
++ sb->s_flags |= SB_I_VERSION;
++
+ if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
+ (ext4_has_compat_features(sb) ||
+ ext4_has_ro_compat_features(sb) ||
+@@ -6653,7 +6636,7 @@ static int ext4_write_info(struct super_block *sb, int type)
+ handle_t *handle;
+
+ /* Data block + inode block */
+- handle = ext4_journal_start(d_inode(sb->s_root), EXT4_HT_QUOTA, 2);
++ handle = ext4_journal_start_sb(sb, EXT4_HT_QUOTA, 2);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ ret = dquot_commit_info(sb, type);
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 533216e80fa2b..36d6ba7190b6d 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2412,6 +2412,7 @@ retry_inode:
+ if (!error) {
+ ext4_xattr_update_super_block(handle, inode->i_sb);
+ inode->i_ctime = current_time(inode);
++ inode_inc_iversion(inode);
+ if (!value)
+ no_expand = 0;
+ error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 8259e0fa97e1f..e04ed60cc9e26 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -140,7 +140,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+ unsigned int segno, offset;
+ bool exist;
+
+- if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ)
++ if (type == DATA_GENERIC)
+ return true;
+
+ segno = GET_SEGNO(sbi, blkaddr);
+@@ -148,6 +148,13 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+ se = get_seg_entry(sbi, segno);
+
+ exist = f2fs_test_bit(offset, se->cur_valid_map);
++ if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
++ f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
++ blkaddr, exist);
++ set_sbi_flag(sbi, SBI_NEED_FSCK);
++ return exist;
++ }
++
+ if (!exist && type == DATA_GENERIC_ENHANCE) {
+ f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+ blkaddr, exist);
+@@ -185,6 +192,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
+ case DATA_GENERIC:
+ case DATA_GENERIC_ENHANCE:
+ case DATA_GENERIC_ENHANCE_READ:
++ case DATA_GENERIC_ENHANCE_UPDATE:
+ if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
+ blkaddr < MAIN_BLKADDR(sbi))) {
+ f2fs_warn(sbi, "access invalid blkaddr:%u",
+@@ -1053,7 +1061,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)
+ spin_unlock(&sbi->inode_lock[type]);
+ }
+
+-int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
++int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
++ bool from_cp)
+ {
+ struct list_head *head;
+ struct inode *inode;
+@@ -1088,11 +1097,15 @@ retry:
+ if (inode) {
+ unsigned long cur_ino = inode->i_ino;
+
+- F2FS_I(inode)->cp_task = current;
++ if (from_cp)
++ F2FS_I(inode)->cp_task = current;
++ F2FS_I(inode)->wb_task = current;
+
+ filemap_fdatawrite(inode->i_mapping);
+
+- F2FS_I(inode)->cp_task = NULL;
++ F2FS_I(inode)->wb_task = NULL;
++ if (from_cp)
++ F2FS_I(inode)->cp_task = NULL;
+
+ iput(inode);
+ /* We need to give cpu to another writers. */
+@@ -1221,7 +1234,7 @@ retry_flush_dents:
+ /* write all the dirty dentry pages */
+ if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
+ f2fs_unlock_all(sbi);
+- err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
++ err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true);
+ if (err)
+ return err;
+ cond_resched();
+@@ -1892,15 +1905,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
+ void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi)
+ {
+ struct ckpt_req_control *cprc = &sbi->cprc_info;
++ struct task_struct *ckpt_task;
+
+- if (cprc->f2fs_issue_ckpt) {
+- struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt;
++ if (!cprc->f2fs_issue_ckpt)
++ return;
+
+- cprc->f2fs_issue_ckpt = NULL;
+- kthread_stop(ckpt_task);
++ ckpt_task = cprc->f2fs_issue_ckpt;
++ cprc->f2fs_issue_ckpt = NULL;
++ kthread_stop(ckpt_task);
+
+- flush_remained_ckpt_reqs(sbi, NULL);
+- }
++ f2fs_flush_ckpt_thread(sbi);
++}
++
++void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
++{
++ struct ckpt_req_control *cprc = &sbi->cprc_info;
++
++ flush_remained_ckpt_reqs(sbi, NULL);
++
++ /* Let's wait for the previous dispatched checkpoint. */
++ while (atomic_read(&cprc->queued_ckpt))
++ io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+ }
+
+ void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index aa3ccddfa0376..5e88272d94e42 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2856,7 +2856,7 @@ out:
+ }
+ unlock_page(page);
+ if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) &&
+- !F2FS_I(inode)->cp_task && allow_balance)
++ !F2FS_I(inode)->wb_task && allow_balance)
+ f2fs_balance_fs(sbi, need_balance_fs);
+
+ if (unlikely(f2fs_cp_error(sbi))) {
+@@ -3156,7 +3156,7 @@ static inline bool __should_serialize_io(struct inode *inode,
+ struct writeback_control *wbc)
+ {
+ /* to avoid deadlock in path of data flush */
+- if (F2FS_I(inode)->cp_task)
++ if (F2FS_I(inode)->wb_task)
+ return false;
+
+ if (!S_ISREG(inode->i_mode))
+diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
+index 866e72b29bd5a..761fd42c93f23 100644
+--- a/fs/f2fs/extent_cache.c
++++ b/fs/f2fs/extent_cache.c
+@@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode)
+ if (!f2fs_may_extent_tree(inode))
+ return;
+
+- set_inode_flag(inode, FI_NO_EXTENT);
+-
+ write_lock(&et->lock);
++ set_inode_flag(inode, FI_NO_EXTENT);
+ __free_extent_tree(sbi, et);
+ if (et->largest.len) {
+ et->largest.len = 0;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 3c7cdb70fe2ef..1e57b11ffe2a6 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -266,6 +266,10 @@ enum {
+ * condition of read on truncated area
+ * by extent_cache
+ */
++ DATA_GENERIC_ENHANCE_UPDATE, /*
++ * strong check on range and segment
++ * bitmap for update case
++ */
+ META_GENERIC,
+ };
+
+@@ -782,6 +786,7 @@ struct f2fs_inode_info {
+ unsigned int clevel; /* maximum level of given file name */
+ struct task_struct *task; /* lookup and create consistency */
+ struct task_struct *cp_task; /* separate cp/wb IO stats*/
++ struct task_struct *wb_task; /* indicate inode is in context of writeback */
+ nid_t i_xattr_nid; /* node id that contains xattrs */
+ loff_t last_disk_size; /* lastly written file size */
+ spinlock_t i_size_lock; /* protect last_disk_size */
+@@ -3707,6 +3712,7 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi)
+ * checkpoint.c
+ */
+ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
++void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
+ struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index);
+@@ -3736,7 +3742,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);
+ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi);
+ void f2fs_update_dirty_folio(struct inode *inode, struct folio *folio);
+ void f2fs_remove_dirty_inode(struct inode *inode);
+-int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
++int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
++ bool from_cp);
+ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type);
+ u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi);
+ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
+@@ -4508,7 +4515,12 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
+ /* disallow direct IO if any of devices has unaligned blksize */
+ if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
+ return true;
+-
++ /*
++ * for blkzoned device, fallback direct IO to buffered IO, so
++ * all IOs can be serialized by log-structured write.
++ */
++ if (f2fs_sb_has_blkzoned(sbi) && (rw == WRITE))
++ return true;
+ if (f2fs_lfs_mode(sbi) && (rw == WRITE)) {
+ if (block_unaligned_IO(inode, iocb, iter))
+ return true;
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6da21d405ce1e..73881314bdda8 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -97,14 +97,10 @@ static int gc_thread_func(void *data)
+ */
+ if (sbi->gc_mode == GC_URGENT_HIGH) {
+ spin_lock(&sbi->gc_urgent_high_lock);
+- if (sbi->gc_urgent_high_limited) {
+- if (!sbi->gc_urgent_high_remaining) {
+- sbi->gc_urgent_high_limited = false;
+- spin_unlock(&sbi->gc_urgent_high_lock);
+- sbi->gc_mode = GC_NORMAL;
+- continue;
+- }
+- sbi->gc_urgent_high_remaining--;
++ if (sbi->gc_urgent_high_limited &&
++ !sbi->gc_urgent_high_remaining--) {
++ sbi->gc_urgent_high_limited = false;
++ sbi->gc_mode = GC_NORMAL;
+ }
+ spin_unlock(&sbi->gc_urgent_high_lock);
+ }
+@@ -1082,7 +1078,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ {
+ struct page *node_page;
+ nid_t nid;
+- unsigned int ofs_in_node;
++ unsigned int ofs_in_node, max_addrs;
+ block_t source_blkaddr;
+
+ nid = le32_to_cpu(sum->nid);
+@@ -1108,6 +1104,14 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ return false;
+ }
+
++ max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
++ DEF_ADDRS_PER_BLOCK;
++ if (ofs_in_node >= max_addrs) {
++ f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
++ ofs_in_node, dni->ino, dni->nid, max_addrs);
++ return false;
++ }
++
+ *nofs = ofs_of_node(node_page);
+ source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node);
+ f2fs_put_page(node_page, 1);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index dcd0a1e350951..5c9facec98f69 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -474,7 +474,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+ struct dnode_of_data tdn = *dn;
+ nid_t ino, nid;
+ struct inode *inode;
+- unsigned int offset;
++ unsigned int offset, ofs_in_node, max_addrs;
+ block_t bidx;
+ int i;
+
+@@ -501,15 +501,24 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+ got_it:
+ /* Use the locked dnode page and inode */
+ nid = le32_to_cpu(sum.nid);
++ ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++
++ max_addrs = ADDRS_PER_PAGE(dn->node_page, dn->inode);
++ if (ofs_in_node >= max_addrs) {
++ f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u",
++ ofs_in_node, dn->inode->i_ino, nid, max_addrs);
++ return -EFSCORRUPTED;
++ }
++
+ if (dn->inode->i_ino == nid) {
+ tdn.nid = nid;
+ if (!dn->inode_page_locked)
+ lock_page(dn->inode_page);
+ tdn.node_page = dn->inode_page;
+- tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++ tdn.ofs_in_node = ofs_in_node;
+ goto truncate_out;
+ } else if (dn->nid == nid) {
+- tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++ tdn.ofs_in_node = ofs_in_node;
+ goto truncate_out;
+ }
+
+@@ -698,6 +707,14 @@ retry_prev:
+ goto err;
+ }
+
++ if (f2fs_is_valid_blkaddr(sbi, dest,
++ DATA_GENERIC_ENHANCE_UPDATE)) {
++ f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u",
++ dest, inode->i_ino, dn.ofs_in_node);
++ err = -EFSCORRUPTED;
++ goto err;
++ }
++
+ /* write dummy data page */
+ f2fs_replace_block(sbi, &dn, src, dest,
+ ni.version, false, false);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 0de21f82d7bc8..84bad18ce13d5 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -476,7 +476,7 @@ do_sync:
+ mutex_lock(&sbi->flush_lock);
+
+ blk_start_plug(&plug);
+- f2fs_sync_dirty_inodes(sbi, FILE_INODE);
++ f2fs_sync_dirty_inodes(sbi, FILE_INODE, false);
+ blk_finish_plug(&plug);
+
+ mutex_unlock(&sbi->flush_lock);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 2451623c05a7a..5415c06d8246f 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -301,10 +301,10 @@ static void f2fs_destroy_casefold_cache(void) { }
+
+ static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
+ {
+- block_t limit = min((sbi->user_block_count << 1) / 1000,
++ block_t limit = min((sbi->user_block_count >> 3),
+ sbi->user_block_count - sbi->reserved_blocks);
+
+- /* limit is 0.2% */
++ /* limit is 12.5% */
+ if (test_opt(sbi, RESERVE_ROOT) &&
+ F2FS_OPTION(sbi).root_reserved_blocks > limit) {
+ F2FS_OPTION(sbi).root_reserved_blocks = limit;
+@@ -1666,9 +1666,8 @@ static int f2fs_freeze(struct super_block *sb)
+ if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY))
+ return -EINVAL;
+
+- /* ensure no checkpoint required */
+- if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
+- return -EINVAL;
++ /* Let's flush checkpoints and stop the thread. */
++ f2fs_flush_ckpt_thread(F2FS_SB(sb));
+
+ /* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
+ set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
+@@ -2181,6 +2180,9 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
+ f2fs_up_write(&sbi->gc_lock);
+
+ f2fs_sync_fs(sbi->sb, 1);
++
++ /* Let's ensure there's no pending checkpoint anymore */
++ f2fs_flush_ckpt_thread(sbi);
+ }
+
+ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+@@ -2346,6 +2348,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ f2fs_stop_ckpt_thread(sbi);
+ need_restart_ckpt = true;
+ } else {
++ /* Flush if the prevous checkpoint, if exists. */
++ f2fs_flush_ckpt_thread(sbi);
++
+ err = f2fs_start_ckpt_thread(sbi);
+ if (err) {
+ f2fs_err(sbi,
+diff --git a/fs/file_table.c b/fs/file_table.c
+index 99c6796c9f28a..dd88701e54a93 100644
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -324,12 +324,7 @@ static void __fput(struct file *file)
+ }
+ fops_put(file->f_op);
+ put_pid(file->f_owner.pid);
+- if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+- i_readcount_dec(inode);
+- if (mode & FMODE_WRITER) {
+- put_write_access(inode);
+- __mnt_drop_write(mnt);
+- }
++ put_file_access(file);
+ dput(dentry);
+ if (unlikely(mode & FMODE_NEED_UNMOUNT))
+ dissolve_on_fput(mnt);
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 08a1993ab7fd3..443f83382b9bd 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1718,9 +1718,14 @@ static int writeback_single_inode(struct inode *inode,
+ */
+ if (!(inode->i_state & I_DIRTY_ALL))
+ inode_cgwb_move_to_attached(inode, wb);
+- else if (!(inode->i_state & I_SYNC_QUEUED) &&
+- (inode->i_state & I_DIRTY))
+- redirty_tail_locked(inode, wb);
++ else if (!(inode->i_state & I_SYNC_QUEUED)) {
++ if ((inode->i_state & I_DIRTY))
++ redirty_tail_locked(inode, wb);
++ else if (inode->i_state & I_DIRTY_TIME) {
++ inode->dirtied_when = jiffies;
++ inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++ }
++ }
+
+ spin_unlock(&wb->list_lock);
+ inode_sync_complete(inode);
+@@ -2369,6 +2374,20 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ trace_writeback_mark_inode_dirty(inode, flags);
+
+ if (flags & I_DIRTY_INODE) {
++ /*
++ * Inode timestamp update will piggback on this dirtying.
++ * We tell ->dirty_inode callback that timestamps need to
++ * be updated by setting I_DIRTY_TIME in flags.
++ */
++ if (inode->i_state & I_DIRTY_TIME) {
++ spin_lock(&inode->i_lock);
++ if (inode->i_state & I_DIRTY_TIME) {
++ inode->i_state &= ~I_DIRTY_TIME;
++ flags |= I_DIRTY_TIME;
++ }
++ spin_unlock(&inode->i_lock);
++ }
++
+ /*
+ * Notify the filesystem about the inode being dirtied, so that
+ * (if needed) it can update on-disk fields and journal the
+@@ -2378,7 +2397,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ */
+ trace_writeback_dirty_inode_start(inode, flags);
+ if (sb->s_op->dirty_inode)
+- sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
++ sb->s_op->dirty_inode(inode,
++ flags & (I_DIRTY_INODE | I_DIRTY_TIME));
+ trace_writeback_dirty_inode(inode, flags);
+
+ /* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
+@@ -2399,21 +2419,15 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ */
+ smp_mb();
+
+- if (((inode->i_state & flags) == flags) ||
+- (dirtytime && (inode->i_state & I_DIRTY_INODE)))
++ if ((inode->i_state & flags) == flags)
+ return;
+
+ spin_lock(&inode->i_lock);
+- if (dirtytime && (inode->i_state & I_DIRTY_INODE))
+- goto out_unlock_inode;
+ if ((inode->i_state & flags) != flags) {
+ const int was_dirty = inode->i_state & I_DIRTY;
+
+ inode_attach_wb(inode, NULL);
+
+- /* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
+- if (flags & I_DIRTY_INODE)
+- inode->i_state &= ~I_DIRTY_TIME;
+ inode->i_state |= flags;
+
+ /*
+@@ -2486,7 +2500,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ out_unlock:
+ if (wb)
+ spin_unlock(&wb->list_lock);
+-out_unlock_inode:
+ spin_unlock(&inode->i_lock);
+ }
+ EXPORT_SYMBOL(__mark_inode_dirty);
+diff --git a/fs/internal.h b/fs/internal.h
+index 3e206d3e317c4..4372d67a37533 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -102,6 +102,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
+ extern struct file *alloc_empty_file(int, const struct cred *);
+ extern struct file *alloc_empty_file_noaccount(int, const struct cred *);
+
++static inline void put_file_access(struct file *file)
++{
++ if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
++ i_readcount_dec(file->f_inode);
++ } else if (file->f_mode & FMODE_WRITER) {
++ put_write_access(file->f_inode);
++ __mnt_drop_write(file->f_path.mnt);
++ }
++}
++
+ /*
+ * super.c
+ */
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index ca5c62901541e..77d59c159248d 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1421,7 +1421,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
+ if (!count)
+ folio_end_writeback(folio);
+ done:
+- mapping_set_error(folio->mapping, error);
++ mapping_set_error(inode->i_mapping, error);
+ return error;
+ }
+
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index b2b2bc9b88d9d..ec2b55879e3a9 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -570,7 +570,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
+ journal->j_running_transaction = NULL;
+ start_time = ktime_get();
+ commit_transaction->t_log_start = journal->j_head;
+- wake_up(&journal->j_wait_transaction_locked);
++ wake_up_all(&journal->j_wait_transaction_locked);
+ write_unlock(&journal->j_state_lock);
+
+ jbd2_debug(3, "JBD2: commit phase 2a\n");
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 6350d3857c896..7e08d416a5fd5 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -923,10 +923,16 @@ int jbd2_fc_wait_bufs(journal_t *journal, int num_blks)
+ for (i = j_fc_off - 1; i >= j_fc_off - num_blks; i--) {
+ bh = journal->j_fc_wbuf[i];
+ wait_on_buffer(bh);
++ /*
++ * Update j_fc_off so jbd2_fc_release_bufs can release remain
++ * buffer head.
++ */
++ if (unlikely(!buffer_uptodate(bh))) {
++ journal->j_fc_off = i + 1;
++ return -EIO;
++ }
+ put_bh(bh);
+ journal->j_fc_wbuf[i] = NULL;
+- if (unlikely(!buffer_uptodate(bh)))
+- return -EIO;
+ }
+
+ return 0;
+diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
+index f548479615c69..3688d16fe83b0 100644
+--- a/fs/jbd2/recovery.c
++++ b/fs/jbd2/recovery.c
+@@ -256,6 +256,7 @@ static int fc_do_one_pass(journal_t *journal,
+ err = journal->j_fc_replay_callback(journal, bh, pass,
+ next_fc_block - journal->j_fc_first,
+ expected_commit_id);
++ brelse(bh);
+ next_fc_block++;
+ if (err < 0 || err == JBD2_FC_REPLAY_STOP)
+ break;
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e1be93ccd81cb..6a404ac1c178f 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -168,7 +168,7 @@ static void wait_transaction_locked(journal_t *journal)
+ int need_to_start;
+ tid_t tid = journal->j_running_transaction->t_tid;
+
+- prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
++ prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait,
+ TASK_UNINTERRUPTIBLE);
+ need_to_start = !tid_geq(journal->j_commit_request, tid);
+ read_unlock(&journal->j_state_lock);
+@@ -194,7 +194,7 @@ static void wait_transaction_switching(journal_t *journal)
+ read_unlock(&journal->j_state_lock);
+ return;
+ }
+- prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
++ prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait,
+ TASK_UNINTERRUPTIBLE);
+ read_unlock(&journal->j_state_lock);
+ /*
+@@ -920,7 +920,7 @@ void jbd2_journal_unlock_updates (journal_t *journal)
+ write_lock(&journal->j_state_lock);
+ --journal->j_barrier_count;
+ write_unlock(&journal->j_state_lock);
+- wake_up(&journal->j_wait_transaction_locked);
++ wake_up_all(&journal->j_wait_transaction_locked);
+ }
+
+ static void warn_dirty_buffer(struct buffer_head *bh)
+diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c
+index ce42bff42ef9f..a0d635304754a 100644
+--- a/fs/ksmbd/server.c
++++ b/fs/ksmbd/server.c
+@@ -235,10 +235,8 @@ send:
+ if (work->sess && work->sess->enc && work->encrypted &&
+ conn->ops->encrypt_resp) {
+ rc = conn->ops->encrypt_resp(work);
+- if (rc < 0) {
++ if (rc < 0)
+ conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+- goto send;
+- }
+ }
+
+ ksmbd_conn_write(work);
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 19412ac701a65..7a9497a7b0a30 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -3808,11 +3808,6 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
+ return 0;
+ }
+
+-static void restart_ctx(struct dir_context *ctx)
+-{
+- ctx->pos = 0;
+-}
+-
+ static int verify_info_level(int info_level)
+ {
+ switch (info_level) {
+@@ -3921,7 +3916,6 @@ int smb2_query_dir(struct ksmbd_work *work)
+ if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
+ ksmbd_debug(SMB, "Restart directory scan\n");
+ generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
+- restart_ctx(&dir_fp->readdir_data.ctx);
+ }
+
+ memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
+@@ -3968,11 +3962,9 @@ int smb2_query_dir(struct ksmbd_work *work)
+ */
+ if (!d_info.out_buf_len && !d_info.num_entry)
+ goto no_buf_len;
+- if (rc == 0)
+- restart_ctx(&dir_fp->readdir_data.ctx);
+- if (rc == -ENOSPC)
++ if (rc > 0 || rc == -ENOSPC)
+ rc = 0;
+- if (rc)
++ else if (rc)
+ goto err_out;
+
+ d_info.wptr = d_info.rptr;
+@@ -4029,6 +4021,8 @@ err_out2:
+ rsp->hdr.Status = STATUS_NO_MEMORY;
+ else if (rc == -EFAULT)
+ rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
++ else if (rc == -EIO)
++ rsp->hdr.Status = STATUS_FILE_CORRUPT_ERROR;
+ if (!rsp->hdr.Status)
+ rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
+
+@@ -7643,11 +7637,16 @@ int smb2_ioctl(struct ksmbd_work *work)
+ goto out;
+ }
+
+- if (in_buf_len < sizeof(struct validate_negotiate_info_req))
+- return -EINVAL;
++ if (in_buf_len < offsetof(struct validate_negotiate_info_req,
++ Dialects)) {
++ ret = -EINVAL;
++ goto out;
++ }
+
+- if (out_buf_len < sizeof(struct validate_negotiate_info_rsp))
+- return -EINVAL;
++ if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) {
++ ret = -EINVAL;
++ goto out;
++ }
+
+ ret = fsctl_validate_negotiate_info(conn,
+ (struct validate_negotiate_info_req *)&req->Buffer[0],
+diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c
+index 7f8ab14fb8ec1..d96da872d70a1 100644
+--- a/fs/ksmbd/smb_common.c
++++ b/fs/ksmbd/smb_common.c
+@@ -4,6 +4,8 @@
+ * Copyright (C) 2018 Namjae Jeon <linkinjeon@kernel.org>
+ */
+
++#include <linux/user_namespace.h>
++
+ #include "smb_common.h"
+ #include "server.h"
+ #include "misc.h"
+@@ -625,8 +627,8 @@ int ksmbd_override_fsids(struct ksmbd_work *work)
+ if (!cred)
+ return -ENOMEM;
+
+- cred->fsuid = make_kuid(current_user_ns(), uid);
+- cred->fsgid = make_kgid(current_user_ns(), gid);
++ cred->fsuid = make_kuid(&init_user_ns, uid);
++ cred->fsgid = make_kgid(&init_user_ns, gid);
+
+ gi = groups_alloc(0);
+ if (!gi) {
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+index 47ccfcbe0a22e..e272ad738faff 100644
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -90,8 +90,14 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&entry->e_list);
+- /* Initial hash reference */
+- atomic_set(&entry->e_refcnt, 1);
++ /*
++ * We create entry with two references. One reference is kept by the
++ * hash table, the other reference is used to protect us from
++ * mb_cache_entry_delete_or_get() until the entry is fully setup. This
++ * avoids nesting of cache->c_list_lock into hash table bit locks which
++ * is problematic for RT.
++ */
++ atomic_set(&entry->e_refcnt, 2);
+ entry->e_key = key;
+ entry->e_value = value;
+ entry->e_reusable = reusable;
+@@ -106,15 +112,12 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ }
+ }
+ hlist_bl_add_head(&entry->e_hash_list, head);
+- /*
+- * Add entry to LRU list before it can be found by
+- * mb_cache_entry_delete() to avoid races
+- */
++ hlist_bl_unlock(head);
+ spin_lock(&cache->c_list_lock);
+ list_add_tail(&entry->e_list, &cache->c_list);
+ cache->c_entry_count++;
+ spin_unlock(&cache->c_list_lock);
+- hlist_bl_unlock(head);
++ mb_cache_entry_put(cache, entry);
+
+ return 0;
+ }
+diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
+index a41cca619338d..5b1e771238b35 100644
+--- a/fs/nfsd/nfs3proc.c
++++ b/fs/nfsd/nfs3proc.c
+@@ -150,7 +150,6 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
+ {
+ struct nfsd3_readargs *argp = rqstp->rq_argp;
+ struct nfsd3_readres *resp = rqstp->rq_resp;
+- u32 max_blocksize = svc_max_payload(rqstp);
+ unsigned int len;
+ int v;
+
+@@ -159,7 +158,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
+ (unsigned long) argp->count,
+ (unsigned long long) argp->offset);
+
+- argp->count = min_t(u32, argp->count, max_blocksize);
++ argp->count = min_t(u32, argp->count, svc_max_payload(rqstp));
++ argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
+ if (argp->offset > (u64)OFFSET_MAX)
+ argp->offset = (u64)OFFSET_MAX;
+ if (argp->offset + argp->count > (u64)OFFSET_MAX)
+@@ -563,13 +563,14 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp,
+ {
+ struct xdr_buf *buf = &resp->dirlist;
+ struct xdr_stream *xdr = &resp->xdr;
+-
+- count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
++ unsigned int sendbuf = min_t(unsigned int, rqstp->rq_res.buflen,
++ svc_max_payload(rqstp));
+
+ memset(buf, 0, sizeof(*buf));
+
+ /* Reserve room for the NULL ptr & eof flag (-2 words) */
+- buf->buflen = count - XDR_UNIT * 2;
++ buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), sendbuf);
++ buf->buflen -= XDR_UNIT * 2;
+ buf->pages = rqstp->rq_next_page;
+ rqstp->rq_next_page += (buf->buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index a72ab97f77efe..6ba25a5b76e17 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -2633,9 +2633,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
+ status = nfserr_minor_vers_mismatch;
+ if (nfsd_minorversion(nn, args->minorversion, NFSD_TEST) <= 0)
+ goto out;
+- status = nfserr_resource;
+- if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
+- goto out;
+
+ status = nfs41_check_op_ordering(args);
+ if (status) {
+@@ -2648,10 +2645,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
+
+ rqstp->rq_lease_breaker = (void **)&cstate->clp;
+
+- trace_nfsd_compound(rqstp, args->opcnt);
++ trace_nfsd_compound(rqstp, args->client_opcnt);
+ while (!status && resp->opcnt < args->opcnt) {
+ op = &args->ops[resp->opcnt++];
+
++ if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) {
++ /* If there are still more operations to process,
++ * stop here and report NFS4ERR_RESOURCE. */
++ if (cstate->minorversion == 0 &&
++ args->client_opcnt > resp->opcnt) {
++ op->status = nfserr_resource;
++ goto encode_op;
++ }
++ }
++
+ /*
+ * The XDR decode routines may have pre-set op->status;
+ * for example, if there is a miscellaneous XDR error
+@@ -2727,8 +2734,8 @@ encode_op:
+ status = op->status;
+ }
+
+- trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
+- nfsd4_op_name(op->opnum));
++ trace_nfsd_compound_status(args->client_opcnt, resp->opcnt,
++ status, nfsd4_op_name(op->opnum));
+
+ nfsd4_cstate_clear_replay(cstate);
+ nfsd4_increment_op_stats(op->opnum);
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index c634483d85d2a..8f24485e0f04f 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -815,8 +815,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
+ princhash.data = memdup_user(
+ &ci->cc_princhash.cp_data,
+ princhashlen);
+- if (IS_ERR_OR_NULL(princhash.data))
++ if (IS_ERR_OR_NULL(princhash.data)) {
++ kfree(name.data);
+ return -EFAULT;
++ }
+ princhash.len = princhashlen;
+ } else
+ princhash.len = 0;
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index c5d199d7e6b4e..0bc36472f8b7b 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1049,6 +1049,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
+
+ static void nfs4_free_deleg(struct nfs4_stid *stid)
+ {
++ WARN_ON(!list_empty(&stid->sc_cp_list));
+ kmem_cache_free(deleg_slab, stid);
+ atomic_long_dec(&num_delegations);
+ }
+@@ -1462,6 +1463,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
+ release_all_access(stp);
+ if (stp->st_stateowner)
+ nfs4_put_stateowner(stp->st_stateowner);
++ WARN_ON(!list_empty(&stid->sc_cp_list));
+ kmem_cache_free(stateid_slab, stid);
+ }
+
+@@ -6684,6 +6686,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
+ struct nfs4_client *clp = s->st_stid.sc_client;
+ bool unhashed;
+ LIST_HEAD(reaplist);
++ struct nfs4_ol_stateid *stp;
+
+ spin_lock(&clp->cl_lock);
+ unhashed = unhash_open_stateid(s, &reaplist);
+@@ -6692,6 +6695,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
+ if (unhashed)
+ put_ol_stateid_locked(s, &reaplist);
+ spin_unlock(&clp->cl_lock);
++ list_for_each_entry(stp, &reaplist, st_locks)
++ nfs4_free_cpntf_statelist(clp->net, &stp->st_stid);
+ free_ol_stateid_reaplist(&reaplist);
+ } else {
+ spin_unlock(&clp->cl_lock);
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 1e9690a061eca..2960d0a8e8f9a 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -2357,16 +2357,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
+
+ if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
+ return false;
+- if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
++ if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0)
+ return false;
+-
+- /*
+- * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
+- * here, so we return success at the xdr level so that
+- * nfsd4_proc can handle this is an NFS-level error.
+- */
+- if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
+- return true;
++ argp->opcnt = min_t(u32, argp->client_opcnt,
++ NFSD_MAX_OPS_PER_COMPOUND);
+
+ if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
+ argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
+@@ -3994,7 +3988,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
+ }
+ if (resp->xdr->buf->page_len && splice_ok) {
+ WARN_ON_ONCE(1);
+- return nfserr_resource;
++ return nfserr_serverfault;
+ }
+ xdr_commit_encode(xdr);
+
+diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
+index 7381972f16774..4b19cc727ea50 100644
+--- a/fs/nfsd/nfsproc.c
++++ b/fs/nfsd/nfsproc.c
+@@ -185,6 +185,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
+ argp->count, argp->offset);
+
+ argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2);
++ argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
+
+ v = 0;
+ len = argp->count;
+@@ -567,12 +568,11 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,
+ struct xdr_buf *buf = &resp->dirlist;
+ struct xdr_stream *xdr = &resp->xdr;
+
+- count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
+-
+ memset(buf, 0, sizeof(*buf));
+
+ /* Reserve room for the NULL ptr & eof flag (-2 words) */
+- buf->buflen = count - XDR_UNIT * 2;
++ buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), (u32)PAGE_SIZE);
++ buf->buflen -= XDR_UNIT * 2;
+ buf->pages = rqstp->rq_next_page;
+ rqstp->rq_next_page++;
+
+diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
+index 96267258e6291..466e2786fc976 100644
+--- a/fs/nfsd/xdr4.h
++++ b/fs/nfsd/xdr4.h
+@@ -717,9 +717,10 @@ struct nfsd4_compoundargs {
+ struct svcxdr_tmpbuf *to_free;
+ struct svc_rqst *rqstp;
+
+- u32 taglen;
+ char * tag;
++ u32 taglen;
+ u32 minorversion;
++ u32 client_opcnt;
+ u32 opcnt;
+ struct nfsd4_op *ops;
+ struct nfsd4_op iops[8];
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 51363d4e8636b..26a76ebfe58fc 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -1927,8 +1927,6 @@ const struct inode_operations ntfs_link_inode_operations = {
+ .setattr = ntfs3_setattr,
+ .listxattr = ntfs_listxattr,
+ .permission = ntfs_permission,
+- .get_acl = ntfs_get_acl,
+- .set_acl = ntfs_set_acl,
+ };
+
+ const struct address_space_operations ntfs_aops = {
+diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
+index 6ae1f56b7358f..7de8718c68a90 100644
+--- a/fs/ntfs3/xattr.c
++++ b/fs/ntfs3/xattr.c
+@@ -625,67 +625,6 @@ int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
+ return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false);
+ }
+
+-static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
+- struct inode *inode, int type, void *buffer,
+- size_t size)
+-{
+- struct posix_acl *acl;
+- int err;
+-
+- if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
+- ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
+- return -EOPNOTSUPP;
+- }
+-
+- acl = ntfs_get_acl(inode, type, false);
+- if (IS_ERR(acl))
+- return PTR_ERR(acl);
+-
+- if (!acl)
+- return -ENODATA;
+-
+- err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
+- posix_acl_release(acl);
+-
+- return err;
+-}
+-
+-static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
+- struct inode *inode, int type, const void *value,
+- size_t size)
+-{
+- struct posix_acl *acl;
+- int err;
+-
+- if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
+- ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
+- return -EOPNOTSUPP;
+- }
+-
+- if (!inode_owner_or_capable(mnt_userns, inode))
+- return -EPERM;
+-
+- if (!value) {
+- acl = NULL;
+- } else {
+- acl = posix_acl_from_xattr(&init_user_ns, value, size);
+- if (IS_ERR(acl))
+- return PTR_ERR(acl);
+-
+- if (acl) {
+- err = posix_acl_valid(&init_user_ns, acl);
+- if (err)
+- goto release_and_out;
+- }
+- }
+-
+- err = ntfs_set_acl(mnt_userns, inode, acl, type);
+-
+-release_and_out:
+- posix_acl_release(acl);
+- return err;
+-}
+-
+ /*
+ * ntfs_init_acl - Initialize the ACLs of a new inode.
+ *
+@@ -852,23 +791,6 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
+ goto out;
+ }
+
+-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
+- if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
+- !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
+- sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
+- (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
+- !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
+- sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
+- /* TODO: init_user_ns? */
+- err = ntfs_xattr_get_acl(
+- &init_user_ns, inode,
+- name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
+- ? ACL_TYPE_ACCESS
+- : ACL_TYPE_DEFAULT,
+- buffer, size);
+- goto out;
+- }
+-#endif
+ /* Deal with NTFS extended attribute. */
+ err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
+
+@@ -981,22 +903,6 @@ set_new_fa:
+ goto out;
+ }
+
+-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
+- if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
+- !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
+- sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
+- (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
+- !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
+- sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
+- err = ntfs_xattr_set_acl(
+- mnt_userns, inode,
+- name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
+- ? ACL_TYPE_ACCESS
+- : ACL_TYPE_DEFAULT,
+- value, size);
+- goto out;
+- }
+-#endif
+ /* Deal with NTFS extended attribute. */
+ err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
+
+@@ -1086,7 +992,7 @@ static bool ntfs_xattr_user_list(struct dentry *dentry)
+ }
+
+ // clang-format off
+-static const struct xattr_handler ntfs_xattr_handler = {
++static const struct xattr_handler ntfs_other_xattr_handler = {
+ .prefix = "",
+ .get = ntfs_getxattr,
+ .set = ntfs_setxattr,
+@@ -1094,7 +1000,11 @@ static const struct xattr_handler ntfs_xattr_handler = {
+ };
+
+ const struct xattr_handler *ntfs_xattr_handlers[] = {
+- &ntfs_xattr_handler,
++#ifdef CONFIG_NTFS3_FS_POSIX_ACL
++ &posix_acl_access_xattr_handler,
++ &posix_acl_default_xattr_handler,
++#endif
++ &ntfs_other_xattr_handler,
+ NULL,
+ };
+ // clang-format on
+diff --git a/fs/open.c b/fs/open.c
+index cf7e5c350a54b..a81319b6177f6 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -842,7 +842,9 @@ static int do_dentry_open(struct file *f,
+ return 0;
+ }
+
+- if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
++ if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
++ i_readcount_inc(inode);
++ } else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
+ error = get_write_access(inode);
+ if (unlikely(error))
+ goto cleanup_file;
+@@ -882,8 +884,6 @@ static int do_dentry_open(struct file *f,
+ goto cleanup_all;
+ }
+ f->f_mode |= FMODE_OPENED;
+- if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+- i_readcount_inc(inode);
+ if ((f->f_mode & FMODE_READ) &&
+ likely(f->f_op->read || f->f_op->read_iter))
+ f->f_mode |= FMODE_CAN_READ;
+@@ -937,10 +937,7 @@ cleanup_all:
+ if (WARN_ON_ONCE(error > 0))
+ error = -EINVAL;
+ fops_put(f->f_op);
+- if (f->f_mode & FMODE_WRITER) {
+- put_write_access(inode);
+- __mnt_drop_write(f->f_path.mnt);
+- }
++ put_file_access(f);
+ cleanup_file:
+ path_put(&f->f_path);
+ f->f_path.mnt = NULL;
+diff --git a/fs/posix_acl.c b/fs/posix_acl.c
+index 5af33800743e4..abe387700ba9d 100644
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -710,9 +710,9 @@ EXPORT_SYMBOL(posix_acl_update_mode);
+ /*
+ * Fix up the uids and gids in posix acl extended attributes in place.
+ */
+-static int posix_acl_fix_xattr_common(void *value, size_t size)
++static int posix_acl_fix_xattr_common(const void *value, size_t size)
+ {
+- struct posix_acl_xattr_header *header = value;
++ const struct posix_acl_xattr_header *header = value;
+ int count;
+
+ if (!header)
+@@ -720,13 +720,13 @@ static int posix_acl_fix_xattr_common(void *value, size_t size)
+ if (size < sizeof(struct posix_acl_xattr_header))
+ return -EINVAL;
+ if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
+- return -EINVAL;
++ return -EOPNOTSUPP;
+
+ count = posix_acl_xattr_count(size);
+ if (count < 0)
+ return -EINVAL;
+ if (count == 0)
+- return -EINVAL;
++ return 0;
+
+ return count;
+ }
+@@ -748,7 +748,7 @@ void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
+ return;
+
+ count = posix_acl_fix_xattr_common(value, size);
+- if (count < 0)
++ if (count <= 0)
+ return;
+
+ for (end = entry + count; entry != end; entry++) {
+@@ -788,7 +788,7 @@ void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
+ return;
+
+ count = posix_acl_fix_xattr_common(value, size);
+- if (count < 0)
++ if (count <= 0)
+ return;
+
+ for (end = entry + count; entry != end; entry++) {
+@@ -822,7 +822,7 @@ static void posix_acl_fix_xattr_userns(
+ kgid_t gid;
+
+ count = posix_acl_fix_xattr_common(value, size);
+- if (count < 0)
++ if (count <= 0)
+ return;
+
+ for (end = entry + count; entry != end; entry++) {
+@@ -870,16 +870,9 @@ posix_acl_from_xattr(struct user_namespace *user_ns,
+ struct posix_acl *acl;
+ struct posix_acl_entry *acl_e;
+
+- if (!value)
+- return NULL;
+- if (size < sizeof(struct posix_acl_xattr_header))
+- return ERR_PTR(-EINVAL);
+- if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
+- return ERR_PTR(-EOPNOTSUPP);
+-
+- count = posix_acl_xattr_count(size);
++ count = posix_acl_fix_xattr_common(value, size);
+ if (count < 0)
+- return ERR_PTR(-EINVAL);
++ return ERR_PTR(count);
+ if (count == 0)
+ return NULL;
+
+diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
+index 5f2405994280a..7e65d67de9f33 100644
+--- a/fs/quota/quota_tree.c
++++ b/fs/quota/quota_tree.c
+@@ -71,6 +71,35 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
+ return ret;
+ }
+
++static inline int do_check_range(struct super_block *sb, const char *val_name,
++ uint val, uint min_val, uint max_val)
++{
++ if (val < min_val || val > max_val) {
++ quota_error(sb, "Getting %s %u out of range %u-%u",
++ val_name, val, min_val, max_val);
++ return -EUCLEAN;
++ }
++
++ return 0;
++}
++
++static int check_dquot_block_header(struct qtree_mem_dqinfo *info,
++ struct qt_disk_dqdbheader *dh)
++{
++ int err = 0;
++
++ err = do_check_range(info->dqi_sb, "dqdh_next_free",
++ le32_to_cpu(dh->dqdh_next_free), 0,
++ info->dqi_blocks - 1);
++ if (err)
++ return err;
++ err = do_check_range(info->dqi_sb, "dqdh_prev_free",
++ le32_to_cpu(dh->dqdh_prev_free), 0,
++ info->dqi_blocks - 1);
++
++ return err;
++}
++
+ /* Remove empty block from list and return it */
+ static int get_free_dqblk(struct qtree_mem_dqinfo *info)
+ {
+@@ -85,6 +114,9 @@ static int get_free_dqblk(struct qtree_mem_dqinfo *info)
+ ret = read_blk(info, blk, buf);
+ if (ret < 0)
+ goto out_buf;
++ ret = check_dquot_block_header(info, dh);
++ if (ret)
++ goto out_buf;
+ info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
+ }
+ else {
+@@ -232,6 +264,9 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
+ *err = read_blk(info, blk, buf);
+ if (*err < 0)
+ goto out_buf;
++ *err = check_dquot_block_header(info, dh);
++ if (*err)
++ goto out_buf;
+ } else {
+ blk = get_free_dqblk(info);
+ if ((int)blk < 0) {
+@@ -424,6 +459,9 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
+ goto out_buf;
+ }
+ dh = (struct qt_disk_dqdbheader *)buf;
++ ret = check_dquot_block_header(info, dh);
++ if (ret)
++ goto out_buf;
+ le16_add_cpu(&dh->dqdh_entries, -1);
+ if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
+ ret = remove_free_dqentry(info, buf, blk);
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 175de70e3adfd..0c1d33c4f74c1 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -991,7 +991,7 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *new,
+ int fd;
+
+ fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new,
+- O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode);
++ O_RDONLY | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode);
+ if (fd < 0)
+ return fd;
+
+@@ -2094,7 +2094,7 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
+ mmgrab(ctx->mm);
+
+ fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx,
+- O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
++ O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
+ if (fd < 0) {
+ mmdrop(ctx->mm);
+ kmem_cache_free(userfaultfd_ctx_cachep, ctx);
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index 9ac59814bbb6c..f029c6702dda1 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -653,7 +653,7 @@ xfs_fs_destroy_inode(
+ static void
+ xfs_fs_dirty_inode(
+ struct inode *inode,
+- int flag)
++ int flags)
+ {
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+@@ -661,7 +661,13 @@ xfs_fs_dirty_inode(
+
+ if (!(inode->i_sb->s_flags & SB_LAZYTIME))
+ return;
+- if (flag != I_DIRTY_SYNC || !(inode->i_state & I_DIRTY_TIME))
++
++ /*
++ * Only do the timestamp update if the inode is dirty (I_DIRTY_SYNC)
++ * and has dirty timestamp (I_DIRTY_TIME). I_DIRTY_TIME can be passed
++ * in flags possibly together with I_DIRTY_SYNC.
++ */
++ if ((flags & ~I_DIRTY_TIME) != I_DIRTY_SYNC || !(flags & I_DIRTY_TIME))
+ return;
+
+ if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp))
+diff --git a/include/dt-bindings/clock/samsung,exynosautov9.h b/include/dt-bindings/clock/samsung,exynosautov9.h
+index ea9f91b4eb1a3..a7db6516593fe 100644
+--- a/include/dt-bindings/clock/samsung,exynosautov9.h
++++ b/include/dt-bindings/clock/samsung,exynosautov9.h
+@@ -226,21 +226,21 @@
+ #define CLK_GOUT_PERIC0_IPCLK_8 28
+ #define CLK_GOUT_PERIC0_IPCLK_9 29
+ #define CLK_GOUT_PERIC0_IPCLK_10 30
+-#define CLK_GOUT_PERIC0_IPCLK_11 30
+-#define CLK_GOUT_PERIC0_PCLK_0 31
+-#define CLK_GOUT_PERIC0_PCLK_1 32
+-#define CLK_GOUT_PERIC0_PCLK_2 33
+-#define CLK_GOUT_PERIC0_PCLK_3 34
+-#define CLK_GOUT_PERIC0_PCLK_4 35
+-#define CLK_GOUT_PERIC0_PCLK_5 36
+-#define CLK_GOUT_PERIC0_PCLK_6 37
+-#define CLK_GOUT_PERIC0_PCLK_7 38
+-#define CLK_GOUT_PERIC0_PCLK_8 39
+-#define CLK_GOUT_PERIC0_PCLK_9 40
+-#define CLK_GOUT_PERIC0_PCLK_10 41
+-#define CLK_GOUT_PERIC0_PCLK_11 42
++#define CLK_GOUT_PERIC0_IPCLK_11 31
++#define CLK_GOUT_PERIC0_PCLK_0 32
++#define CLK_GOUT_PERIC0_PCLK_1 33
++#define CLK_GOUT_PERIC0_PCLK_2 34
++#define CLK_GOUT_PERIC0_PCLK_3 35
++#define CLK_GOUT_PERIC0_PCLK_4 36
++#define CLK_GOUT_PERIC0_PCLK_5 37
++#define CLK_GOUT_PERIC0_PCLK_6 38
++#define CLK_GOUT_PERIC0_PCLK_7 39
++#define CLK_GOUT_PERIC0_PCLK_8 40
++#define CLK_GOUT_PERIC0_PCLK_9 41
++#define CLK_GOUT_PERIC0_PCLK_10 42
++#define CLK_GOUT_PERIC0_PCLK_11 43
+
+-#define PERIC0_NR_CLK 43
++#define PERIC0_NR_CLK 44
+
+ /* CMU_PERIC1 */
+ #define CLK_MOUT_PERIC1_BUS_USER 1
+@@ -272,21 +272,21 @@
+ #define CLK_GOUT_PERIC1_IPCLK_8 28
+ #define CLK_GOUT_PERIC1_IPCLK_9 29
+ #define CLK_GOUT_PERIC1_IPCLK_10 30
+-#define CLK_GOUT_PERIC1_IPCLK_11 30
+-#define CLK_GOUT_PERIC1_PCLK_0 31
+-#define CLK_GOUT_PERIC1_PCLK_1 32
+-#define CLK_GOUT_PERIC1_PCLK_2 33
+-#define CLK_GOUT_PERIC1_PCLK_3 34
+-#define CLK_GOUT_PERIC1_PCLK_4 35
+-#define CLK_GOUT_PERIC1_PCLK_5 36
+-#define CLK_GOUT_PERIC1_PCLK_6 37
+-#define CLK_GOUT_PERIC1_PCLK_7 38
+-#define CLK_GOUT_PERIC1_PCLK_8 39
+-#define CLK_GOUT_PERIC1_PCLK_9 40
+-#define CLK_GOUT_PERIC1_PCLK_10 41
+-#define CLK_GOUT_PERIC1_PCLK_11 42
++#define CLK_GOUT_PERIC1_IPCLK_11 31
++#define CLK_GOUT_PERIC1_PCLK_0 32
++#define CLK_GOUT_PERIC1_PCLK_1 33
++#define CLK_GOUT_PERIC1_PCLK_2 34
++#define CLK_GOUT_PERIC1_PCLK_3 35
++#define CLK_GOUT_PERIC1_PCLK_4 36
++#define CLK_GOUT_PERIC1_PCLK_5 37
++#define CLK_GOUT_PERIC1_PCLK_6 38
++#define CLK_GOUT_PERIC1_PCLK_7 39
++#define CLK_GOUT_PERIC1_PCLK_8 40
++#define CLK_GOUT_PERIC1_PCLK_9 41
++#define CLK_GOUT_PERIC1_PCLK_10 42
++#define CLK_GOUT_PERIC1_PCLK_11 43
+
+-#define PERIC1_NR_CLK 43
++#define PERIC1_NR_CLK 44
+
+ /* CMU_PERIS */
+ #define CLK_MOUT_PERIS_BUS_USER 1
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index 21292b5bbb550..e3050e153a716 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -566,6 +566,18 @@ struct ata_bmdma_prd {
+ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
+ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
+ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2)))
++#define ata_id_has_devslp(id) \
++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)))
++#define ata_id_has_ncq_autosense(id) \
++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)))
++#define ata_id_has_dipm(id) \
++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 3)))
+ #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
+ #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
+ #define ata_id_u32(id,n) \
+@@ -578,9 +590,6 @@ struct ata_bmdma_prd {
+
+ #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
+ #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
+-#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
+-#define ata_id_has_ncq_autosense(id) \
+- ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
+
+ static inline bool ata_id_has_hipm(const u16 *id)
+ {
+@@ -592,17 +601,6 @@ static inline bool ata_id_has_hipm(const u16 *id)
+ return val & (1 << 9);
+ }
+
+-static inline bool ata_id_has_dipm(const u16 *id)
+-{
+- u16 val = id[ATA_ID_FEATURE_SUPP];
+-
+- if (val == 0 || val == 0xffff)
+- return false;
+-
+- return val & (1 << 3);
+-}
+-
+-
+ static inline bool ata_id_has_fua(const u16 *id)
+ {
+ if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000)
+@@ -771,16 +769,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id)
+
+ static inline bool ata_id_has_sense_reporting(const u16 *id)
+ {
+- if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
++ if (!(id[ATA_ID_CFS_ENABLE_2] & BIT(15)))
++ return false;
++ if ((id[ATA_ID_COMMAND_SET_3] & (BIT(15) | BIT(14))) != BIT(14))
+ return false;
+- return id[ATA_ID_COMMAND_SET_3] & (1 << 6);
++ return id[ATA_ID_COMMAND_SET_3] & BIT(6);
+ }
+
+ static inline bool ata_id_sense_reporting_enabled(const u16 *id)
+ {
+- if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
++ if (!ata_id_has_sense_reporting(id))
++ return false;
++ /* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */
++ if ((id[ATA_ID_COMMAND_SET_4] & (BIT(15) | BIT(14))) != BIT(14))
+ return false;
+- return id[ATA_ID_COMMAND_SET_4] & (1 << 6);
++ return id[ATA_ID_COMMAND_SET_4] & BIT(6);
+ }
+
+ /**
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index ca22b06700a94..2c5806997bbf7 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -509,7 +509,7 @@ static inline void bio_set_dev(struct bio *bio, struct block_device *bdev)
+ {
+ bio_clear_flag(bio, BIO_REMAPPED);
+ if (bio->bi_bdev != bdev)
+- bio_clear_flag(bio, BIO_THROTTLED);
++ bio_clear_flag(bio, BIO_BPS_THROTTLED);
+ bio->bi_bdev = bdev;
+ bio_associate_blkg(bio);
+ }
+diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
+index 92294a5fb0836..1532cd07a5976 100644
+--- a/include/linux/blk-mq.h
++++ b/include/linux/blk-mq.h
+@@ -268,9 +268,16 @@ static inline void rq_list_move(struct request **src, struct request **dst,
+ rq_list_add(dst, rq);
+ }
+
++/**
++ * enum blk_eh_timer_return - How the timeout handler should proceed
++ * @BLK_EH_DONE: The block driver completed the command or will complete it at
++ * a later time.
++ * @BLK_EH_RESET_TIMER: Reset the request timer and continue waiting for the
++ * request to complete.
++ */
+ enum blk_eh_timer_return {
+- BLK_EH_DONE, /* drivers has completed the command */
+- BLK_EH_RESET_TIMER, /* reset timer and try again */
++ BLK_EH_DONE,
++ BLK_EH_RESET_TIMER,
+ };
+
+ #define BLK_TAG_ALLOC_FIFO 0 /* allocate starting from 0 */
+diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
+index 1ef99790f6ed3..41afb4cfb9b0d 100644
+--- a/include/linux/blk_types.h
++++ b/include/linux/blk_types.h
+@@ -325,7 +325,7 @@ enum {
+ BIO_QUIET, /* Make BIO Quiet */
+ BIO_CHAIN, /* chained bio, ->bi_remaining in effect */
+ BIO_REFFED, /* bio has elevated ->bi_cnt */
+- BIO_THROTTLED, /* This bio has already been subjected to
++ BIO_BPS_THROTTLED, /* This bio has already been subjected to
+ * throttling rules. Don't do it again. */
+ BIO_TRACE_COMPLETION, /* bio_endio() should trace the final completion
+ * of this bio. */
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 20c26aed78962..80fc8a88c610d 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -891,6 +891,7 @@ struct bpf_dispatcher {
+ struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
+ int num_progs;
+ void *image;
++ void *rw_image;
+ u32 image_off;
+ struct bpf_ksym ksym;
+ };
+@@ -909,7 +910,7 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampolin
+ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
++int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
+ #define BPF_DISPATCHER_INIT(_name) { \
+ .mutex = __MUTEX_INITIALIZER(_name.mutex), \
+ .func = &_name##_func, \
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 2e3bad8640dc4..1fdddbf3546b4 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -212,6 +212,17 @@ struct bpf_reference_state {
+ * is used purely to inform the user of a reference leak.
+ */
+ int insn_idx;
++ /* There can be a case like:
++ * main (frame 0)
++ * cb (frame 1)
++ * func (frame 3)
++ * cb (frame 4)
++ * Hence for frame 4, if callback_ref just stored boolean, it would be
++ * impossible to distinguish nested callback refs. Hence store the
++ * frameno and compare that to callback_ref in check_reference_leak when
++ * exiting a callback function.
++ */
++ int callback_ref;
+ };
+
+ /* state of the program:
+diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
+index dce631e678dd6..8d9eec5f6d8bb 100644
+--- a/include/linux/dynamic_debug.h
++++ b/include/linux/dynamic_debug.h
+@@ -55,9 +55,6 @@ struct _ddebug {
+
+ #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
+
+-/* exported for module authors to exercise >control */
+-int dynamic_debug_exec_queries(const char *query, const char *modname);
+-
+ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ const char *modname);
+ extern int ddebug_remove_module(const char *mod_name);
+@@ -201,7 +198,7 @@ static inline int ddebug_remove_module(const char *mod)
+ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ const char *modname)
+ {
+- if (strstr(param, "dyndbg")) {
++ if (!strcmp(param, "dyndbg")) {
+ /* avoid pr_warn(), which wants pr_fmt() fully defined */
+ printk(KERN_WARNING "dyndbg param is supported only in "
+ "CONFIG_DYNAMIC_DEBUG builds\n");
+@@ -221,12 +218,6 @@ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ rowsize, groupsize, buf, len, ascii); \
+ } while (0)
+
+-static inline int dynamic_debug_exec_queries(const char *query, const char *modname)
+-{
+- pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n");
+- return 0;
+-}
+-
+ #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
+
+ #endif
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 305d5f19093b9..30eb30d6909b0 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -46,7 +46,7 @@ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt);
+
+ static inline bool eventfd_signal_allowed(void)
+ {
+- return !current->in_eventfd_signal;
++ return !current->in_eventfd;
+ }
+
+ #else /* CONFIG_EVENTFD */
+diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h
+index c2b1d4fd59873..fe7e6ba918f10 100644
+--- a/include/linux/export-internal.h
++++ b/include/linux/export-internal.h
+@@ -10,8 +10,10 @@
+ #include <linux/compiler.h>
+ #include <linux/types.h>
+
+-/* __used is needed to keep __crc_* for LTO */
+ #define SYMBOL_CRC(sym, crc, sec) \
+- u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc
++ asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \
++ "__crc_" #sym ":" "\n" \
++ ".long " #crc "\n" \
++ ".previous" "\n")
+
+ #endif /* __LINUX_EXPORT_INTERNAL_H__ */
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index a5f21dc3c4327..f2c47df5ad2ad 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -1018,6 +1018,8 @@ extern long bpf_jit_limit_max;
+
+ typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
+
++void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
++
+ struct bpf_binary_header *
+ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
+ unsigned int alignment,
+@@ -1030,6 +1032,9 @@ void bpf_jit_free(struct bpf_prog *fp);
+ struct bpf_binary_header *
+ bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
+
++void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
++void bpf_prog_pack_free(struct bpf_binary_header *hdr);
++
+ static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
+ {
+ return list_empty(&fp->aux->ksym.lnode) ||
+diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
+index 3b401fa0f3746..fce2fb2fc9626 100644
+--- a/include/linux/fortify-string.h
++++ b/include/linux/fortify-string.h
+@@ -19,7 +19,8 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("
+ unsigned char *__p = (unsigned char *)(p); \
+ size_t __ret = (size_t)-1; \
+ size_t __p_size = __builtin_object_size(p, 1); \
+- if (__p_size != (size_t)-1) { \
++ if (__p_size != (size_t)-1 && \
++ __builtin_constant_p(*__p)) { \
+ size_t __p_len = __p_size - 1; \
+ if (__builtin_constant_p(__p[__p_len]) && \
+ __p[__p_len] == '\0') \
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 9eced4cc286ee..56a4b4b02477d 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2371,13 +2371,14 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
+ * don't have to write inode on fdatasync() when only
+ * e.g. the timestamps have changed.
+ * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean.
+- * I_DIRTY_TIME The inode itself only has dirty timestamps, and the
++ * I_DIRTY_TIME The inode itself has dirty timestamps, and the
+ * lazytime mount option is enabled. We keep track of this
+ * separately from I_DIRTY_SYNC in order to implement
+ * lazytime. This gets cleared if I_DIRTY_INODE
+- * (I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set. I.e.
+- * either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
+- * i_state, but not both. I_DIRTY_PAGES may still be set.
++ * (I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set. But
++ * I_DIRTY_TIME can still be set if I_DIRTY_SYNC is already
++ * in place because writeback might already be in progress
++ * and we don't want to lose the time update
+ * I_NEW Serves as both a mutex and completion notification.
+ * New inodes set I_NEW. If two processes both create
+ * the same inode, one of them will release its inode and
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 3ec981a0d8b3a..67c88b82fc32d 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -207,8 +207,8 @@ struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ struct page *follow_huge_pd(struct vm_area_struct *vma,
+ unsigned long address, hugepd_t hpd,
+ int flags, int pdshift);
+-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+- pmd_t *pmd, int flags);
++struct page *follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address,
++ int flags);
+ struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
+ pud_t *pud, int flags);
+ struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
+@@ -312,8 +312,8 @@ static inline struct page *follow_huge_pd(struct vm_area_struct *vma,
+ return NULL;
+ }
+
+-static inline struct page *follow_huge_pmd(struct mm_struct *mm,
+- unsigned long address, pmd_t *pmd, int flags)
++static inline struct page *follow_huge_pmd_pte(struct vm_area_struct *vma,
++ unsigned long address, int flags)
+ {
+ return NULL;
+ }
+diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
+index aa1d4da03538b..77c2885c4c130 100644
+--- a/include/linux/hw_random.h
++++ b/include/linux/hw_random.h
+@@ -50,6 +50,7 @@ struct hwrng {
+ struct list_head list;
+ struct kref ref;
+ struct completion cleanup_done;
++ struct completion dying;
+ };
+
+ struct device;
+@@ -61,4 +62,6 @@ extern int devm_hwrng_register(struct device *dev, struct hwrng *rng);
+ extern void hwrng_unregister(struct hwrng *rng);
+ extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
+
++extern long hwrng_msleep(struct hwrng *rng, unsigned int msecs);
++
+ #endif /* LINUX_HWRANDOM_H_ */
+diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h
+index 6b3586b3f952f..d1f8b30a7c8b7 100644
+--- a/include/linux/iio/iio-opaque.h
++++ b/include/linux/iio/iio-opaque.h
+@@ -11,6 +11,7 @@
+ * checked by device drivers but should be considered
+ * read-only as this is a core internal bit
+ * @driver_module: used to make it harder to undercut users
++ * @mlock_key: lockdep class for iio_dev lock
+ * @info_exist_lock: lock to prevent use during removal
+ * @trig_readonly: mark the current trigger immutable
+ * @event_interface: event chrdevs associated with interrupt lines
+@@ -42,6 +43,7 @@ struct iio_dev_opaque {
+ int currentmode;
+ int id;
+ struct module *driver_module;
++ struct lock_class_key mlock_key;
+ struct mutex info_exist_lock;
+ bool trig_readonly;
+ struct iio_event_interface *event_interface;
+diff --git a/include/linux/iova.h b/include/linux/iova.h
+index c6ba6d95d79c2..83c00fac2acb1 100644
+--- a/include/linux/iova.h
++++ b/include/linux/iova.h
+@@ -75,7 +75,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
+ return iova >> iova_shift(iovad);
+ }
+
+-#if IS_ENABLED(CONFIG_IOMMU_IOVA)
++#if IS_REACHABLE(CONFIG_IOMMU_IOVA)
+ int iova_cache_get(void);
+ void iova_cache_put(void);
+
+diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
+index 8a30de08e9139..c726ea7812552 100644
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -293,6 +293,7 @@ struct mmc_card {
+ #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
+ #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
+ #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */
++#define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */
+
+ bool reenable_cmdq; /* Re-enable Command Queue */
+
+diff --git a/include/linux/once.h b/include/linux/once.h
+index b14d8b309d52b..176ab75b42df7 100644
+--- a/include/linux/once.h
++++ b/include/linux/once.h
+@@ -5,10 +5,18 @@
+ #include <linux/types.h>
+ #include <linux/jump_label.h>
+
++/* Helpers used from arbitrary contexts.
++ * Hard irqs are blocked, be cautious.
++ */
+ bool __do_once_start(bool *done, unsigned long *flags);
+ void __do_once_done(bool *done, struct static_key_true *once_key,
+ unsigned long *flags, struct module *mod);
+
++/* Variant for process contexts only. */
++bool __do_once_slow_start(bool *done);
++void __do_once_slow_done(bool *done, struct static_key_true *once_key,
++ struct module *mod);
++
+ /* Call a function exactly once. The idea of DO_ONCE() is to perform
+ * a function call such as initialization of random seeds, etc, only
+ * once, where DO_ONCE() can live in the fast-path. After @func has
+@@ -52,7 +60,27 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
+ ___ret; \
+ })
+
++/* Variant of DO_ONCE() for process/sleepable contexts. */
++#define DO_ONCE_SLOW(func, ...) \
++ ({ \
++ bool ___ret = false; \
++ static bool __section(".data.once") ___done = false; \
++ static DEFINE_STATIC_KEY_TRUE(___once_key); \
++ if (static_branch_unlikely(&___once_key)) { \
++ ___ret = __do_once_slow_start(&___done); \
++ if (unlikely(___ret)) { \
++ func(__VA_ARGS__); \
++ __do_once_slow_done(&___done, &___once_key, \
++ THIS_MODULE); \
++ } \
++ } \
++ ___ret; \
++ })
++
+ #define get_random_once(buf, nbytes) \
+ DO_ONCE(get_random_bytes, (buf), (nbytes))
+
++#define get_random_slow_once(buf, nbytes) \
++ DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes))
++
+ #endif /* _LINUX_ONCE_H */
+diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
+index dac53fd3afea3..2504df9a0453e 100644
+--- a/include/linux/ring_buffer.h
++++ b/include/linux/ring_buffer.h
+@@ -101,7 +101,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
+ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ struct file *filp, poll_table *poll_table);
+-
++void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
+
+ #define RING_BUFFER_ALL_CPUS -1
+
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index e7b2f8a5c711c..8d82d6d326701 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -936,7 +936,7 @@ struct task_struct {
+ #endif
+ #ifdef CONFIG_EVENTFD
+ /* Recursion prevention for eventfd_signal() */
+- unsigned in_eventfd_signal:1;
++ unsigned in_eventfd:1;
+ #endif
+ #ifdef CONFIG_IOMMU_SVA
+ unsigned pasid_activated:1;
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index 8c7b793aa4d70..16e3d75a324c7 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -74,6 +74,7 @@ struct uart_8250_port;
+ struct uart_8250_ops {
+ int (*setup_irq)(struct uart_8250_port *);
+ void (*release_irq)(struct uart_8250_port *);
++ void (*setup_timer)(struct uart_8250_port *);
+ };
+
+ struct uart_8250_em485 {
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index 1eaea9fe44d8e..beb2ffd31feaf 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -422,7 +422,7 @@ struct uart_icount {
+ __u32 buf_overrun;
+ };
+
+-typedef unsigned int __bitwise upf_t;
++typedef u64 __bitwise upf_t;
+ typedef unsigned int __bitwise upstat_t;
+
+ struct uart_port {
+@@ -530,6 +530,7 @@ struct uart_port {
+ #define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
+ #define UPF_DEAD ((__force upf_t) (1 << 30))
+ #define UPF_IOREMAP ((__force upf_t) (1 << 31))
++#define UPF_FULL_PROBE ((__force upf_t) (1ULL << 32))
+
+ #define __UPF_CHANGE_MASK 0x17fff
+ #define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK)
+@@ -950,5 +951,4 @@ static inline int uart_handle_break(struct uart_port *port)
+ !((cflag) & CLOCAL))
+
+ int uart_get_rs485_mode(struct uart_port *port);
+-int uart_rs485_config(struct uart_port *port);
+ #endif /* LINUX_SERIAL_CORE_H */
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 18e163a3460dd..f02ef6e6171b3 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -796,6 +796,7 @@ typedef unsigned char *sk_buff_data_t;
+ * @csum_level: indicates the number of consecutive checksums found in
+ * the packet minus one that have been verified as
+ * CHECKSUM_UNNECESSARY (max 3)
++ * @scm_io_uring: SKB holds io_uring registered files
+ * @dst_pending_confirm: need to confirm neighbour
+ * @decrypted: Decrypted SKB
+ * @slow_gro: state present at GRO time, slower prepare step required
+@@ -975,6 +976,7 @@ struct sk_buff {
+ #endif
+ __u8 slow_gro:1;
+ __u8 csum_not_inet:1;
++ __u8 scm_io_uring:1;
+
+ #ifdef CONFIG_NET_SCHED
+ __u16 tc_index; /* traffic control index */
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index daecb009c05b5..0ca8a8ffb47e4 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -544,16 +544,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
+ }
+
+ /**
+- * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
++ * svcxdr_init_decode - Prepare an xdr_stream for Call decoding
+ * @rqstp: controlling server RPC transaction context
+ *
++ * This function currently assumes the RPC header in rq_arg has
++ * already been decoded. Upon return, xdr->p points to the
++ * location of the upper layer header.
+ */
+ static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
+ {
+ struct xdr_stream *xdr = &rqstp->rq_arg_stream;
+- struct kvec *argv = rqstp->rq_arg.head;
++ struct xdr_buf *buf = &rqstp->rq_arg;
++ struct kvec *argv = buf->head;
+
+- xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL);
++ /*
++ * svc_getnl() and friends do not keep the xdr_buf's ::len
++ * field up to date. Refresh that field before initializing
++ * the argument decoding stream.
++ */
++ buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len;
++
++ xdr_init_decode(xdr, buf, argv->iov_base, NULL);
+ xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
+ }
+
+@@ -576,7 +587,7 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
+ xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
+ buf->len = resv->iov_len;
+ xdr->page_ptr = buf->pages - 1;
+- buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages);
++ buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
+ buf->buflen -= rqstp->rq_auth_slack;
+ xdr->rqst = NULL;
+ }
+diff --git a/include/linux/tcp.h b/include/linux/tcp.h
+index a9fbe22732c3b..4791fd8019454 100644
+--- a/include/linux/tcp.h
++++ b/include/linux/tcp.h
+@@ -295,7 +295,7 @@ struct tcp_sock {
+ u32 packets_out; /* Packets which are "in flight" */
+ u32 retrans_out; /* Retransmitted packets out */
+ u32 max_packets_out; /* max packets_out in last window */
+- u32 max_packets_seq; /* right edge of max_packets_out flight */
++ u32 cwnd_usage_seq; /* right edge of cwnd usage tracking flight */
+
+ u16 urg_data; /* Saved octet of OOB data and control flags */
+ u8 ecn_flags; /* ECN status bits. */
+diff --git a/include/linux/trace.h b/include/linux/trace.h
+index bf169612ffe12..b5e16e438448f 100644
+--- a/include/linux/trace.h
++++ b/include/linux/trace.h
+@@ -2,8 +2,6 @@
+ #ifndef _LINUX_TRACE_H
+ #define _LINUX_TRACE_H
+
+-#ifdef CONFIG_TRACING
+-
+ #define TRACE_EXPORT_FUNCTION BIT(0)
+ #define TRACE_EXPORT_EVENT BIT(1)
+ #define TRACE_EXPORT_MARKER BIT(2)
+@@ -28,6 +26,8 @@ struct trace_export {
+ int flags;
+ };
+
++#ifdef CONFIG_TRACING
++
+ int register_ftrace_export(struct trace_export *export);
+ int unregister_ftrace_export(struct trace_export *export);
+
+@@ -48,6 +48,38 @@ void osnoise_arch_unregister(void);
+ void osnoise_trace_irq_entry(int id);
+ void osnoise_trace_irq_exit(int id, const char *desc);
+
++#else /* CONFIG_TRACING */
++static inline int register_ftrace_export(struct trace_export *export)
++{
++ return -EINVAL;
++}
++static inline int unregister_ftrace_export(struct trace_export *export)
++{
++ return 0;
++}
++static inline void trace_printk_init_buffers(void)
++{
++}
++static inline int trace_array_printk(struct trace_array *tr, unsigned long ip,
++ const char *fmt, ...)
++{
++ return 0;
++}
++static inline int trace_array_init_printk(struct trace_array *tr)
++{
++ return -EINVAL;
++}
++static inline void trace_array_put(struct trace_array *tr)
++{
++}
++static inline struct trace_array *trace_array_get_by_name(const char *name)
++{
++ return NULL;
++}
++static inline int trace_array_destroy(struct trace_array *tr)
++{
++ return 0;
++}
+ #endif /* CONFIG_TRACING */
+
+ #endif /* _LINUX_TRACE_H */
+diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
+index 8401dec93c155..20749bd9db718 100644
+--- a/include/linux/trace_events.h
++++ b/include/linux/trace_events.h
+@@ -92,6 +92,7 @@ struct trace_iterator {
+ unsigned int temp_size;
+ char *fmt; /* modified format holder */
+ unsigned int fmt_size;
++ long wait_index;
+
+ /* trace_seq for __print_flags() and __print_symbolic() etc. */
+ struct trace_seq tmp_seq;
+diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
+index a8994f307fc38..03b64bf876a46 100644
+--- a/include/net/ieee802154_netdev.h
++++ b/include/net/ieee802154_netdev.h
+@@ -185,21 +185,27 @@ static inline int
+ ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
+ {
+ struct ieee802154_addr_sa *sa;
++ int ret = 0;
+
+ sa = &daddr->addr;
+ if (len < IEEE802154_MIN_NAMELEN)
+ return -EINVAL;
+ switch (sa->addr_type) {
++ case IEEE802154_ADDR_NONE:
++ break;
+ case IEEE802154_ADDR_SHORT:
+ if (len < IEEE802154_NAMELEN_SHORT)
+- return -EINVAL;
++ ret = -EINVAL;
+ break;
+ case IEEE802154_ADDR_LONG:
+ if (len < IEEE802154_NAMELEN_LONG)
+- return -EINVAL;
++ ret = -EINVAL;
++ break;
++ default:
++ ret = -EINVAL;
+ break;
+ }
+- return 0;
++ return ret;
+ }
+
+ static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index d10962b9f0d0d..95c1d51393ac4 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1295,11 +1295,14 @@ static inline bool tcp_is_cwnd_limited(const struct sock *sk)
+ {
+ const struct tcp_sock *tp = tcp_sk(sk);
+
++ if (tp->is_cwnd_limited)
++ return true;
++
+ /* If in slow start, ensure cwnd grows to twice what was ACKed. */
+ if (tcp_in_slow_start(tp))
+ return tcp_snd_cwnd(tp) < 2 * tp->max_packets_out;
+
+- return tp->is_cwnd_limited;
++ return false;
+ }
+
+ /* BBR congestion control needs pacing.
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index 59a217ca2dfd3..4eff7fc7ae586 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -1233,7 +1233,7 @@ enum {
+
+ /* Query effective (directly attached + inherited from ancestor cgroups)
+ * programs that will be executed for events within a cgroup.
+- * attach_flags with this flag are returned only for directly attached programs.
++ * attach_flags with this flag are always returned 0.
+ */
+ #define BPF_F_QUERY_EFFECTIVE (1U << 0)
+
+@@ -1432,7 +1432,10 @@ union bpf_attr {
+ __u32 attach_flags;
+ __aligned_u64 prog_ids;
+ __u32 prog_cnt;
+- __aligned_u64 prog_attach_flags; /* output: per-program attach_flags */
++ /* output: per-program attach_flags.
++ * not allowed to be set during effective query.
++ */
++ __aligned_u64 prog_attach_flags;
+ } query;
+
+ struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
+diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
+index 86be4a92b67bf..a96b7d2770e15 100644
+--- a/include/uapi/rdma/mlx5-abi.h
++++ b/include/uapi/rdma/mlx5-abi.h
+@@ -104,6 +104,7 @@ enum mlx5_ib_alloc_ucontext_resp_mask {
+ MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE = 1UL << 2,
+ MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS = 1UL << 3,
+ MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS = 1UL << 4,
++ MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG = 1UL << 5,
+ };
+
+ enum mlx5_user_cmds_supp_uhw {
+diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c
+index b29e2d02216f2..2ddf321c94893 100644
+--- a/io_uring/fdinfo.c
++++ b/io_uring/fdinfo.c
+@@ -60,6 +60,7 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+ unsigned int cq_head = READ_ONCE(r->cq.head);
+ unsigned int cq_tail = READ_ONCE(r->cq.tail);
+ unsigned int cq_shift = 0;
++ unsigned int sq_shift = 0;
+ unsigned int sq_entries, cq_entries;
+ bool has_lock;
+ bool is_cqe32 = (ctx->flags & IORING_SETUP_CQE32);
+@@ -67,6 +68,8 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+
+ if (is_cqe32)
+ cq_shift = 1;
++ if (ctx->flags & IORING_SETUP_SQE128)
++ sq_shift = 1;
+
+ /*
+ * we may get imprecise sqe and cqe info if uring is actively running
+@@ -82,19 +85,36 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+ seq_printf(m, "CqHead:\t%u\n", cq_head);
+ seq_printf(m, "CqTail:\t%u\n", cq_tail);
+ seq_printf(m, "CachedCqTail:\t%u\n", ctx->cached_cq_tail);
+- seq_printf(m, "SQEs:\t%u\n", sq_tail - ctx->cached_sq_head);
++ seq_printf(m, "SQEs:\t%u\n", sq_tail - sq_head);
+ sq_entries = min(sq_tail - sq_head, ctx->sq_entries);
+ for (i = 0; i < sq_entries; i++) {
+ unsigned int entry = i + sq_head;
+- unsigned int sq_idx = READ_ONCE(ctx->sq_array[entry & sq_mask]);
+ struct io_uring_sqe *sqe;
++ unsigned int sq_idx;
+
++ sq_idx = READ_ONCE(ctx->sq_array[entry & sq_mask]);
+ if (sq_idx > sq_mask)
+ continue;
+- sqe = &ctx->sq_sqes[sq_idx];
+- seq_printf(m, "%5u: opcode:%d, fd:%d, flags:%x, user_data:%llu\n",
+- sq_idx, sqe->opcode, sqe->fd, sqe->flags,
+- sqe->user_data);
++ sqe = &ctx->sq_sqes[sq_idx << sq_shift];
++ seq_printf(m, "%5u: opcode:%s, fd:%d, flags:%x, off:%llu, "
++ "addr:0x%llx, rw_flags:0x%x, buf_index:%d "
++ "user_data:%llu",
++ sq_idx, io_uring_get_opcode(sqe->opcode), sqe->fd,
++ sqe->flags, (unsigned long long) sqe->off,
++ (unsigned long long) sqe->addr, sqe->rw_flags,
++ sqe->buf_index, sqe->user_data);
++ if (sq_shift) {
++ u64 *sqeb = (void *) (sqe + 1);
++ int size = sizeof(struct io_uring_sqe) / sizeof(u64);
++ int j;
++
++ for (j = 0; j < size; j++) {
++ seq_printf(m, ", e%d:0x%llx", j,
++ (unsigned long long) *sqeb);
++ sqeb++;
++ }
++ }
++ seq_printf(m, "\n");
+ }
+ seq_printf(m, "CQEs:\t%u\n", cq_tail - cq_head);
+ cq_entries = min(cq_tail - cq_head, ctx->cq_entries);
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 242d896c00f34..c5dd483a7de2f 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -567,7 +567,7 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force)
+
+ io_cq_lock(ctx);
+ while (!list_empty(&ctx->cq_overflow_list)) {
+- struct io_uring_cqe *cqe = io_get_cqe(ctx);
++ struct io_uring_cqe *cqe = io_get_cqe_overflow(ctx, true);
+ struct io_overflow_cqe *ocqe;
+
+ if (!cqe && !force)
+@@ -694,12 +694,19 @@ bool io_req_cqe_overflow(struct io_kiocb *req)
+ * control dependency is enough as we're using WRITE_ONCE to
+ * fill the cq entry
+ */
+-struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx)
++struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx, bool overflow)
+ {
+ struct io_rings *rings = ctx->rings;
+ unsigned int off = ctx->cached_cq_tail & (ctx->cq_entries - 1);
+ unsigned int free, queued, len;
+
++ /*
++ * Posting into the CQ when there are pending overflowed CQEs may break
++ * ordering guarantees, which will affect links, F_MORE users and more.
++ * Force overflow the completion.
++ */
++ if (!overflow && (ctx->check_cq & BIT(IO_CHECK_CQ_OVERFLOW_BIT)))
++ return NULL;
+
+ /* userspace may cheat modifying the tail, be safe and do min */
+ queued = min(__io_cqring_events(ctx), ctx->cq_entries);
+@@ -823,8 +830,12 @@ inline void __io_req_complete(struct io_kiocb *req, unsigned issue_flags)
+
+ void io_req_complete_failed(struct io_kiocb *req, s32 res)
+ {
++ const struct io_op_def *def = &io_op_defs[req->opcode];
++
+ req_set_fail(req);
+ io_req_set_res(req, res, io_put_kbuf(req, IO_URING_F_UNLOCKED));
++ if (def->fail)
++ def->fail(req);
+ io_req_complete_post(req);
+ }
+
+@@ -2228,6 +2239,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+
+ do {
+ io_cqring_overflow_flush(ctx);
++
+ if (io_cqring_events(ctx) >= min_events)
+ return 0;
+ if (!io_run_task_work())
+@@ -2418,12 +2430,6 @@ static void io_req_caches_free(struct io_ring_ctx *ctx)
+ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ {
+ io_sq_thread_finish(ctx);
+-
+- if (ctx->mm_account) {
+- mmdrop(ctx->mm_account);
+- ctx->mm_account = NULL;
+- }
+-
+ io_rsrc_refs_drop(ctx);
+ /* __io_rsrc_put_work() may need uring_lock to progress, wait w/o it */
+ io_wait_rsrc_data(ctx->buf_data);
+@@ -2466,6 +2472,10 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ WARN_ON_ONCE(!list_empty(&ctx->ltimeout_list));
+ WARN_ON_ONCE(ctx->notif_slots || ctx->nr_notif_slots);
+
++ if (ctx->mm_account) {
++ mmdrop(ctx->mm_account);
++ ctx->mm_account = NULL;
++ }
+ io_mem_free(ctx->rings);
+ io_mem_free(ctx->sq_sqes);
+
+@@ -3706,6 +3716,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
+ if (WARN_ON_ONCE(percpu_ref_is_dying(&ctx->refs)))
+ return -ENXIO;
+
++ if (ctx->submitter_task && ctx->submitter_task != current)
++ return -EEXIST;
++
+ if (ctx->restricted) {
+ if (opcode >= IORING_REGISTER_LAST)
+ return -EINVAL;
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 2f73f83af9604..45809ae6f64ef 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -24,7 +24,7 @@ enum {
+ IOU_STOP_MULTISHOT = -ECANCELED,
+ };
+
+-struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx);
++struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx, bool overflow);
+ bool io_req_cqe_overflow(struct io_kiocb *req);
+ int io_run_task_work_sig(void);
+ void io_req_complete_failed(struct io_kiocb *req, s32 res);
+@@ -91,7 +91,8 @@ static inline void io_cq_lock(struct io_ring_ctx *ctx)
+
+ void io_cq_unlock_post(struct io_ring_ctx *ctx);
+
+-static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
++static inline struct io_uring_cqe *io_get_cqe_overflow(struct io_ring_ctx *ctx,
++ bool overflow)
+ {
+ if (likely(ctx->cqe_cached < ctx->cqe_sentinel)) {
+ struct io_uring_cqe *cqe = ctx->cqe_cached;
+@@ -103,7 +104,12 @@ static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
+ return cqe;
+ }
+
+- return __io_get_cqe(ctx);
++ return __io_get_cqe(ctx, overflow);
++}
++
++static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
++{
++ return io_get_cqe_overflow(ctx, false);
+ }
+
+ static inline bool __io_fill_cqe_req(struct io_ring_ctx *ctx,
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 60e392f7f2dcd..4878bf40f8b1c 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -46,6 +46,7 @@ struct io_connect {
+ struct file *file;
+ struct sockaddr __user *addr;
+ int addr_len;
++ bool in_progress;
+ };
+
+ struct io_sr_msg {
+@@ -55,21 +56,13 @@ struct io_sr_msg {
+ struct user_msghdr __user *umsg;
+ void __user *buf;
+ };
++ unsigned len;
++ unsigned done_io;
+ unsigned msg_flags;
+- unsigned flags;
+- size_t len;
+- size_t done_io;
+-};
+-
+-struct io_sendzc {
+- struct file *file;
+- void __user *buf;
+- size_t len;
+- unsigned msg_flags;
+- unsigned flags;
+- unsigned addr_len;
++ u16 flags;
++ /* used only for sendzc */
++ u16 addr_len;
+ void __user *addr;
+- size_t done_io;
+ struct io_kiocb *notif;
+ };
+
+@@ -163,10 +156,13 @@ static int io_setup_async_msg(struct io_kiocb *req,
+ }
+ req->flags |= REQ_F_NEED_CLEANUP;
+ memcpy(async_msg, kmsg, sizeof(*kmsg));
+- async_msg->msg.msg_name = &async_msg->addr;
++ if (async_msg->msg.msg_name)
++ async_msg->msg.msg_name = &async_msg->addr;
+ /* if were using fast_iov, set it to the new one */
+- if (!async_msg->free_iov)
+- async_msg->msg.msg_iter.iov = async_msg->fast_iov;
++ if (!kmsg->free_iov) {
++ size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov;
++ async_msg->msg.msg_iter.iov = &async_msg->fast_iov[fast_idx];
++ }
+
+ return -EAGAIN;
+ }
+@@ -184,7 +180,7 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
+
+ int io_sendzc_prep_async(struct io_kiocb *req)
+ {
+- struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++ struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ struct io_async_msghdr *io;
+ int ret;
+
+@@ -879,18 +875,17 @@ out_free:
+ return ret;
+ }
+
+-void io_sendzc_cleanup(struct io_kiocb *req)
++void io_send_zc_cleanup(struct io_kiocb *req)
+ {
+- struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++ struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+
+- zc->notif->flags |= REQ_F_CQE_SKIP;
+ io_notif_flush(zc->notif);
+ zc->notif = NULL;
+ }
+
+-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
++int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+- struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++ struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ struct io_ring_ctx *ctx = req->ctx;
+ struct io_kiocb *notif;
+
+@@ -993,14 +988,14 @@ static int io_sg_from_iter(struct sock *sk, struct sk_buff *skb,
+ return ret;
+ }
+
+-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
++int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
+ {
+ struct sockaddr_storage __address, *addr = NULL;
+- struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++ struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ struct msghdr msg;
+ struct iovec iov;
+ struct socket *sock;
+- unsigned msg_flags, cflags;
++ unsigned msg_flags;
+ int ret, min_ret = 0;
+
+ sock = sock_from_file(req->file);
+@@ -1068,8 +1063,6 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
+ req->flags |= REQ_F_PARTIAL_IO;
+ return io_setup_async_addr(req, addr, issue_flags);
+ }
+- if (ret < 0 && !zc->done_io)
+- zc->notif->flags |= REQ_F_CQE_SKIP;
+ if (ret == -ERESTARTSYS)
+ ret = -EINTR;
+ req_set_fail(req);
+@@ -1080,13 +1073,38 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
+ else if (zc->done_io)
+ ret = zc->done_io;
+
+- io_notif_flush(zc->notif);
+- req->flags &= ~REQ_F_NEED_CLEANUP;
+- cflags = ret >= 0 ? IORING_CQE_F_MORE : 0;
+- io_req_set_res(req, ret, cflags);
++ /*
++ * If we're in io-wq we can't rely on tw ordering guarantees, defer
++ * flushing notif to io_send_zc_cleanup()
++ */
++ if (!(issue_flags & IO_URING_F_UNLOCKED)) {
++ io_notif_flush(zc->notif);
++ req->flags &= ~REQ_F_NEED_CLEANUP;
++ }
++ io_req_set_res(req, ret, IORING_CQE_F_MORE);
+ return IOU_OK;
+ }
+
++void io_sendrecv_fail(struct io_kiocb *req)
++{
++ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++ int res = req->cqe.res;
++
++ if (req->flags & REQ_F_PARTIAL_IO)
++ res = sr->done_io;
++ io_req_set_res(req, res, req->cqe.flags);
++}
++
++void io_send_zc_fail(struct io_kiocb *req)
++{
++ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++
++ if (req->flags & REQ_F_PARTIAL_IO)
++ req->cqe.res = sr->done_io;
++ if (req->flags & REQ_F_NEED_CLEANUP)
++ req->cqe.flags |= IORING_CQE_F_MORE;
++}
++
+ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+ struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
+@@ -1250,6 +1268,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+
+ conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ conn->addr_len = READ_ONCE(sqe->addr2);
++ conn->in_progress = false;
+ return 0;
+ }
+
+@@ -1261,6 +1280,16 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
+ int ret;
+ bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
+
++ if (connect->in_progress) {
++ struct socket *socket;
++
++ ret = -ENOTSOCK;
++ socket = sock_from_file(req->file);
++ if (socket)
++ ret = sock_error(socket->sk);
++ goto out;
++ }
++
+ if (req_has_async_data(req)) {
+ io = req->async_data;
+ } else {
+@@ -1277,13 +1306,17 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
+ ret = __sys_connect_file(req->file, &io->address,
+ connect->addr_len, file_flags);
+ if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
+- if (req_has_async_data(req))
+- return -EAGAIN;
+- if (io_alloc_async_data(req)) {
+- ret = -ENOMEM;
+- goto out;
++ if (ret == -EINPROGRESS) {
++ connect->in_progress = true;
++ } else {
++ if (req_has_async_data(req))
++ return -EAGAIN;
++ if (io_alloc_async_data(req)) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ memcpy(req->async_data, &__io, sizeof(__io));
+ }
+- memcpy(req->async_data, &__io, sizeof(__io));
+ return -EAGAIN;
+ }
+ if (ret == -ERESTARTSYS)
+diff --git a/io_uring/net.h b/io_uring/net.h
+index d744a0a874e75..4090d008fd55a 100644
+--- a/io_uring/net.h
++++ b/io_uring/net.h
+@@ -43,6 +43,8 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags);
+ int io_recv(struct io_kiocb *req, unsigned int issue_flags);
+
++void io_sendrecv_fail(struct io_kiocb *req);
++
+ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_accept(struct io_kiocb *req, unsigned int issue_flags);
+
+@@ -53,9 +55,10 @@ int io_connect_prep_async(struct io_kiocb *req);
+ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_connect(struct io_kiocb *req, unsigned int issue_flags);
+
+-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags);
+-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+-void io_sendzc_cleanup(struct io_kiocb *req);
++int io_send_zc(struct io_kiocb *req, unsigned int issue_flags);
++int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
++void io_send_zc_cleanup(struct io_kiocb *req);
++void io_send_zc_fail(struct io_kiocb *req);
+
+ void io_netmsg_cache_free(struct io_cache_entry *entry);
+ #else
+diff --git a/io_uring/opdef.c b/io_uring/opdef.c
+index c4dddd0fd7094..3b15cdb6dbbc5 100644
+--- a/io_uring/opdef.c
++++ b/io_uring/opdef.c
+@@ -69,6 +69,7 @@ const struct io_op_def io_op_defs[] = {
+ .issue = io_read,
+ .prep_async = io_readv_prep_async,
+ .cleanup = io_readv_writev_cleanup,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_WRITEV] = {
+ .needs_file = 1,
+@@ -85,6 +86,7 @@ const struct io_op_def io_op_defs[] = {
+ .issue = io_write,
+ .prep_async = io_writev_prep_async,
+ .cleanup = io_readv_writev_cleanup,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_FSYNC] = {
+ .needs_file = 1,
+@@ -105,6 +107,7 @@ const struct io_op_def io_op_defs[] = {
+ .name = "READ_FIXED",
+ .prep = io_prep_rw,
+ .issue = io_read,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_WRITE_FIXED] = {
+ .needs_file = 1,
+@@ -119,6 +122,7 @@ const struct io_op_def io_op_defs[] = {
+ .name = "WRITE_FIXED",
+ .prep = io_prep_rw,
+ .issue = io_write,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_POLL_ADD] = {
+ .needs_file = 1,
+@@ -153,6 +157,7 @@ const struct io_op_def io_op_defs[] = {
+ .issue = io_sendmsg,
+ .prep_async = io_sendmsg_prep_async,
+ .cleanup = io_sendmsg_recvmsg_cleanup,
++ .fail = io_sendrecv_fail,
+ #else
+ .prep = io_eopnotsupp_prep,
+ #endif
+@@ -170,6 +175,7 @@ const struct io_op_def io_op_defs[] = {
+ .issue = io_recvmsg,
+ .prep_async = io_recvmsg_prep_async,
+ .cleanup = io_sendmsg_recvmsg_cleanup,
++ .fail = io_sendrecv_fail,
+ #else
+ .prep = io_eopnotsupp_prep,
+ #endif
+@@ -273,6 +279,7 @@ const struct io_op_def io_op_defs[] = {
+ .name = "READ",
+ .prep = io_prep_rw,
+ .issue = io_read,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_WRITE] = {
+ .needs_file = 1,
+@@ -287,6 +294,7 @@ const struct io_op_def io_op_defs[] = {
+ .name = "WRITE",
+ .prep = io_prep_rw,
+ .issue = io_write,
++ .fail = io_rw_fail,
+ },
+ [IORING_OP_FADVISE] = {
+ .needs_file = 1,
+@@ -310,6 +318,7 @@ const struct io_op_def io_op_defs[] = {
+ #if defined(CONFIG_NET)
+ .prep = io_sendmsg_prep,
+ .issue = io_send,
++ .fail = io_sendrecv_fail,
+ #else
+ .prep = io_eopnotsupp_prep,
+ #endif
+@@ -325,6 +334,7 @@ const struct io_op_def io_op_defs[] = {
+ #if defined(CONFIG_NET)
+ .prep = io_recvmsg_prep,
+ .issue = io_recv,
++ .fail = io_sendrecv_fail,
+ #else
+ .prep = io_eopnotsupp_prep,
+ #endif
+@@ -480,10 +490,11 @@ const struct io_op_def io_op_defs[] = {
+ .manual_alloc = 1,
+ #if defined(CONFIG_NET)
+ .async_size = sizeof(struct io_async_msghdr),
+- .prep = io_sendzc_prep,
+- .issue = io_sendzc,
++ .prep = io_send_zc_prep,
++ .issue = io_send_zc,
+ .prep_async = io_sendzc_prep_async,
+- .cleanup = io_sendzc_cleanup,
++ .cleanup = io_send_zc_cleanup,
++ .fail = io_send_zc_fail,
+ #else
+ .prep = io_eopnotsupp_prep,
+ #endif
+diff --git a/io_uring/opdef.h b/io_uring/opdef.h
+index 763c6e54e2ee5..3efe06d25473a 100644
+--- a/io_uring/opdef.h
++++ b/io_uring/opdef.h
+@@ -36,6 +36,7 @@ struct io_op_def {
+ int (*issue)(struct io_kiocb *, unsigned int);
+ int (*prep_async)(struct io_kiocb *);
+ void (*cleanup)(struct io_kiocb *);
++ void (*fail)(struct io_kiocb *);
+ };
+
+ extern const struct io_op_def io_op_defs[];
+diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
+index cf32721132141..50721c17c6cb3 100644
+--- a/io_uring/rsrc.c
++++ b/io_uring/rsrc.c
+@@ -855,6 +855,7 @@ int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file)
+
+ UNIXCB(skb).fp = fpl;
+ skb->sk = sk;
++ skb->scm_io_uring = 1;
+ skb->destructor = unix_destruct_scm;
+ refcount_add(skb->truesize, &sk->sk_wmem_alloc);
+ }
+diff --git a/io_uring/rw.c b/io_uring/rw.c
+index 76ebcfebc9a6e..60c08a944e2fb 100644
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -184,19 +184,34 @@ static void kiocb_end_write(struct io_kiocb *req)
+ }
+ }
+
+-static bool __io_complete_rw_common(struct io_kiocb *req, long res)
++/*
++ * Trigger the notifications after having done some IO, and finish the write
++ * accounting, if any.
++ */
++static void io_req_io_end(struct io_kiocb *req)
+ {
+ struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+
++ WARN_ON(!in_task());
++
+ if (rw->kiocb.ki_flags & IOCB_WRITE) {
+ kiocb_end_write(req);
+ fsnotify_modify(req->file);
+ } else {
+ fsnotify_access(req->file);
+ }
++}
++
++static bool __io_complete_rw_common(struct io_kiocb *req, long res)
++{
+ if (unlikely(res != req->cqe.res)) {
+ if ((res == -EAGAIN || res == -EOPNOTSUPP) &&
+ io_rw_should_reissue(req)) {
++ /*
++ * Reissue will start accounting again, finish the
++ * current cycle.
++ */
++ io_req_io_end(req);
+ req->flags |= REQ_F_REISSUE | REQ_F_PARTIAL_IO;
+ return true;
+ }
+@@ -220,6 +235,12 @@ static inline int io_fixup_rw_res(struct io_kiocb *req, long res)
+ return res;
+ }
+
++static void io_req_rw_complete(struct io_kiocb *req, bool *locked)
++{
++ io_req_io_end(req);
++ io_req_task_complete(req, locked);
++}
++
+ static void io_complete_rw(struct kiocb *kiocb, long res)
+ {
+ struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
+@@ -228,7 +249,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res)
+ if (__io_complete_rw_common(req, res))
+ return;
+ io_req_set_res(req, io_fixup_rw_res(req, res), 0);
+- req->io_task_work.func = io_req_task_complete;
++ req->io_task_work.func = io_req_rw_complete;
+ io_req_task_work_add(req);
+ }
+
+@@ -261,6 +282,11 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,
+ req->file->f_pos = rw->kiocb.ki_pos;
+ if (ret >= 0 && (rw->kiocb.ki_complete == io_complete_rw)) {
+ if (!__io_complete_rw_common(req, ret)) {
++ /*
++ * Safe to call io_end from here as we're inline
++ * from the submission path.
++ */
++ io_req_io_end(req);
+ io_req_set_res(req, final_ret,
+ io_put_kbuf(req, issue_flags));
+ return IOU_OK;
+@@ -794,10 +820,12 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
+ iov_iter_restore(&s->iter, &s->iter_state);
+
+ ret2 = io_setup_async_rw(req, iovec, s, true);
+- if (ret2)
+- return ret2;
+-
+ iovec = NULL;
++ if (ret2) {
++ ret = ret > 0 ? ret : ret2;
++ goto done;
++ }
++
+ io = req->async_data;
+ s = &io->s;
+ /*
+@@ -823,6 +851,7 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
+ return -EAGAIN;
+ }
+
++ req->cqe.res = iov_iter_count(&s->iter);
+ /*
+ * Now retry read with the IOCB_WAITQ parts set in the iocb. If
+ * we get -EIOCBQUEUED, then we'll get a notification when the
+@@ -984,6 +1013,14 @@ static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx)
+ io_cqring_wake(ctx);
+ }
+
++void io_rw_fail(struct io_kiocb *req)
++{
++ int res;
++
++ res = io_fixup_rw_res(req, req->cqe.res);
++ io_req_set_res(req, res, req->cqe.flags);
++}
++
+ int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin)
+ {
+ struct io_wq_work_node *pos, *start, *prev;
+diff --git a/io_uring/rw.h b/io_uring/rw.h
+index 0204c3fcafa51..3b733f4b610ac 100644
+--- a/io_uring/rw.h
++++ b/io_uring/rw.h
+@@ -21,3 +21,4 @@ int io_readv_prep_async(struct io_kiocb *req);
+ int io_write(struct io_kiocb *req, unsigned int issue_flags);
+ int io_writev_prep_async(struct io_kiocb *req);
+ void io_readv_writev_cleanup(struct io_kiocb *req);
++void io_rw_fail(struct io_kiocb *req);
+diff --git a/ipc/mqueue.c b/ipc/mqueue.c
+index f98de32aeea17..9cf314b3f079f 100644
+--- a/ipc/mqueue.c
++++ b/ipc/mqueue.c
+@@ -1746,6 +1746,7 @@ out_filesystem:
+ unregister_filesystem(&mqueue_fs_type);
+ out_sysctl:
+ kmem_cache_destroy(mqueue_inode_cachep);
++ retire_mq_sysctls(&init_ipc_ns);
+ return error;
+ }
+
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c
+index 79a5da1bc5bb6..63a6fe99aa3a8 100644
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -1016,7 +1016,6 @@ static void audit_reset_context(struct audit_context *ctx)
+ WARN_ON(!list_empty(&ctx->killed_trees));
+ audit_free_module(ctx);
+ ctx->fds[0] = -1;
+- audit_proctitle_free(ctx);
+ ctx->type = 0; /* reset last for audit_free_*() */
+ }
+
+@@ -1077,6 +1076,7 @@ static inline void audit_free_context(struct audit_context *context)
+ {
+ /* resetting is extra work, but it is likely just noise */
+ audit_reset_context(context);
++ audit_proctitle_free(context);
+ free_tree_refs(context);
+ kfree(context->filterkey);
+ kfree(context);
+@@ -2069,7 +2069,7 @@ void __audit_syscall_exit(int success, long return_code)
+ /* run through both filters to ensure we set the filterkey properly */
+ audit_filter_syscall(current, context);
+ audit_filter_inodes(current, context);
+- if (context->current_state < AUDIT_STATE_RECORD)
++ if (context->current_state != AUDIT_STATE_RECORD)
+ goto out;
+
+ audit_log_exit();
+diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
+index 8ce40fd869f6a..d13ffb00e9813 100644
+--- a/kernel/bpf/bpf_local_storage.c
++++ b/kernel/bpf/bpf_local_storage.c
+@@ -555,11 +555,11 @@ void bpf_local_storage_map_free(struct bpf_local_storage_map *smap,
+ struct bpf_local_storage_elem, map_node))) {
+ if (busy_counter) {
+ migrate_disable();
+- __this_cpu_inc(*busy_counter);
++ this_cpu_inc(*busy_counter);
+ }
+ bpf_selem_unlink(selem, false);
+ if (busy_counter) {
+- __this_cpu_dec(*busy_counter);
++ this_cpu_dec(*busy_counter);
+ migrate_enable();
+ }
+ cond_resched_rcu();
+diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
+index fa71d58b7deda..832a0e48a2a16 100644
+--- a/kernel/bpf/bpf_lsm.c
++++ b/kernel/bpf/bpf_lsm.c
+@@ -41,17 +41,21 @@ BTF_SET_END(bpf_lsm_hooks)
+ */
+ BTF_SET_START(bpf_lsm_current_hooks)
+ /* operate on freshly allocated sk without any cgroup association */
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_sk_alloc_security)
+ BTF_ID(func, bpf_lsm_sk_free_security)
++#endif
+ BTF_SET_END(bpf_lsm_current_hooks)
+
+ /* List of LSM hooks that trigger while the socket is properly locked.
+ */
+ BTF_SET_START(bpf_lsm_locked_sockopt_hooks)
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_socket_sock_rcv_skb)
+ BTF_ID(func, bpf_lsm_sock_graft)
+ BTF_ID(func, bpf_lsm_inet_csk_clone)
+ BTF_ID(func, bpf_lsm_inet_conn_established)
++#endif
+ BTF_SET_END(bpf_lsm_locked_sockopt_hooks)
+
+ /* List of LSM hooks that trigger while the socket is _not_ locked,
+@@ -59,8 +63,10 @@ BTF_SET_END(bpf_lsm_locked_sockopt_hooks)
+ * in the early init phase.
+ */
+ BTF_SET_START(bpf_lsm_unlocked_sockopt_hooks)
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_socket_post_create)
+ BTF_ID(func, bpf_lsm_socket_socketpair)
++#endif
+ BTF_SET_END(bpf_lsm_unlocked_sockopt_hooks)
+
+ #ifdef CONFIG_CGROUP_BPF
+diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
+index e9014dc626820..6f290623347e0 100644
+--- a/kernel/bpf/bpf_task_storage.c
++++ b/kernel/bpf/bpf_task_storage.c
+@@ -26,20 +26,20 @@ static DEFINE_PER_CPU(int, bpf_task_storage_busy);
+ static void bpf_task_storage_lock(void)
+ {
+ migrate_disable();
+- __this_cpu_inc(bpf_task_storage_busy);
++ this_cpu_inc(bpf_task_storage_busy);
+ }
+
+ static void bpf_task_storage_unlock(void)
+ {
+- __this_cpu_dec(bpf_task_storage_busy);
++ this_cpu_dec(bpf_task_storage_busy);
+ migrate_enable();
+ }
+
+ static bool bpf_task_storage_trylock(void)
+ {
+ migrate_disable();
+- if (unlikely(__this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
+- __this_cpu_dec(bpf_task_storage_busy);
++ if (unlikely(this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
++ this_cpu_dec(bpf_task_storage_busy);
+ migrate_enable();
+ return false;
+ }
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 7e64447659f3d..36fd4b509294a 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env,
+ if (v->next_member) {
+ const struct btf_type *last_member_type;
+ const struct btf_member *last_member;
+- u16 last_member_type_id;
++ u32 last_member_type_id;
+
+ last_member = btf_type_member(v->t) + v->next_member - 1;
+ last_member_type_id = last_member->type;
+diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
+index 4a400cd637316..22888aaa68b66 100644
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1020,6 +1020,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ union bpf_attr __user *uattr)
+ {
+ __u32 __user *prog_attach_flags = u64_to_user_ptr(attr->query.prog_attach_flags);
++ bool effective_query = attr->query.query_flags & BPF_F_QUERY_EFFECTIVE;
+ __u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
+ enum bpf_attach_type type = attr->query.attach_type;
+ enum cgroup_bpf_attach_type from_atype, to_atype;
+@@ -1029,8 +1030,12 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ int total_cnt = 0;
+ u32 flags;
+
++ if (effective_query && prog_attach_flags)
++ return -EINVAL;
++
+ if (type == BPF_LSM_CGROUP) {
+- if (attr->query.prog_cnt && prog_ids && !prog_attach_flags)
++ if (!effective_query && attr->query.prog_cnt &&
++ prog_ids && !prog_attach_flags)
+ return -EINVAL;
+
+ from_atype = CGROUP_LSM_START;
+@@ -1045,7 +1050,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ }
+
+ for (atype = from_atype; atype <= to_atype; atype++) {
+- if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
++ if (effective_query) {
+ effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
+ lockdep_is_held(&cgroup_mutex));
+ total_cnt += bpf_prog_array_length(effective);
+@@ -1054,6 +1059,8 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ }
+ }
+
++ /* always output uattr->query.attach_flags as 0 during effective query */
++ flags = effective_query ? 0 : flags;
+ if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
+ return -EFAULT;
+ if (copy_to_user(&uattr->query.prog_cnt, &total_cnt, sizeof(total_cnt)))
+@@ -1068,7 +1075,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ }
+
+ for (atype = from_atype; atype <= to_atype && total_cnt; atype++) {
+- if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
++ if (effective_query) {
+ effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
+ lockdep_is_held(&cgroup_mutex));
+ cnt = min_t(int, bpf_prog_array_length(effective), total_cnt);
+@@ -1090,15 +1097,16 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ if (++i == cnt)
+ break;
+ }
+- }
+
+- if (prog_attach_flags) {
+- flags = cgrp->bpf.flags[atype];
++ if (prog_attach_flags) {
++ flags = cgrp->bpf.flags[atype];
+
+- for (i = 0; i < cnt; i++)
+- if (copy_to_user(prog_attach_flags + i, &flags, sizeof(flags)))
+- return -EFAULT;
+- prog_attach_flags += cnt;
++ for (i = 0; i < cnt; i++)
++ if (copy_to_user(prog_attach_flags + i,
++ &flags, sizeof(flags)))
++ return -EFAULT;
++ prog_attach_flags += cnt;
++ }
+ }
+
+ prog_ids += cnt;
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 3d9eb3ae334ce..c4600a5781de1 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -825,6 +825,11 @@ struct bpf_prog_pack {
+ unsigned long bitmap[];
+ };
+
++void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
++{
++ memset(area, 0, size);
++}
++
+ #define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
+
+ static DEFINE_MUTEX(pack_mutex);
+@@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
+ return pack;
+ }
+
+-static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
++void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
+ {
+ unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
+ struct bpf_prog_pack *pack;
+@@ -905,7 +910,7 @@ out:
+ return ptr;
+ }
+
+-static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
++void bpf_prog_pack_free(struct bpf_binary_header *hdr)
+ {
+ struct bpf_prog_pack *pack = NULL, *tmp;
+ unsigned int nbits;
+diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
+index 2444bd15cc2d0..fa64b80b8bcab 100644
+--- a/kernel/bpf/dispatcher.c
++++ b/kernel/bpf/dispatcher.c
+@@ -85,12 +85,12 @@ static bool bpf_dispatcher_remove_prog(struct bpf_dispatcher *d,
+ return false;
+ }
+
+-int __weak arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
++int __weak arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
+ {
+ return -ENOTSUPP;
+ }
+
+-static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
++static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *buf)
+ {
+ s64 ips[BPF_DISPATCHER_MAX] = {}, *ipsp = &ips[0];
+ int i;
+@@ -99,12 +99,12 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
+ if (d->progs[i].prog)
+ *ipsp++ = (s64)(uintptr_t)d->progs[i].prog->bpf_func;
+ }
+- return arch_prepare_bpf_dispatcher(image, &ips[0], d->num_progs);
++ return arch_prepare_bpf_dispatcher(image, buf, &ips[0], d->num_progs);
+ }
+
+ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ {
+- void *old, *new;
++ void *old, *new, *tmp;
+ u32 noff;
+ int err;
+
+@@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ }
+
+ new = d->num_progs ? d->image + noff : NULL;
++ tmp = d->num_progs ? d->rw_image + noff : NULL;
+ if (new) {
+- if (bpf_dispatcher_prepare(d, new))
++ /* Prepare the dispatcher in d->rw_image. Then use
++ * bpf_arch_text_copy to update d->image, which is RO+X.
++ */
++ if (bpf_dispatcher_prepare(d, new, tmp))
++ return;
++ if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
+ return;
+ }
+
+@@ -140,9 +146,18 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+
+ mutex_lock(&d->mutex);
+ if (!d->image) {
+- d->image = bpf_jit_alloc_exec_page();
++ d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
+ if (!d->image)
+ goto out;
++ d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
++ if (!d->rw_image) {
++ u32 size = PAGE_SIZE;
++
++ bpf_arch_text_copy(d->image, &size, sizeof(size));
++ bpf_prog_pack_free((struct bpf_binary_header *)d->image);
++ d->image = NULL;
++ goto out;
++ }
+ bpf_image_ksym_add(d->image, &d->ksym);
+ }
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 6c530a5e560a4..75f77df910dcc 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -162,17 +162,25 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab,
+ unsigned long *pflags)
+ {
+ unsigned long flags;
++ bool use_raw_lock;
+
+ hash = hash & HASHTAB_MAP_LOCK_MASK;
+
+- migrate_disable();
++ use_raw_lock = htab_use_raw_lock(htab);
++ if (use_raw_lock)
++ preempt_disable();
++ else
++ migrate_disable();
+ if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) {
+ __this_cpu_dec(*(htab->map_locked[hash]));
+- migrate_enable();
++ if (use_raw_lock)
++ preempt_enable();
++ else
++ migrate_enable();
+ return -EBUSY;
+ }
+
+- if (htab_use_raw_lock(htab))
++ if (use_raw_lock)
+ raw_spin_lock_irqsave(&b->raw_lock, flags);
+ else
+ spin_lock_irqsave(&b->lock, flags);
+@@ -185,13 +193,18 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab,
+ struct bucket *b, u32 hash,
+ unsigned long flags)
+ {
++ bool use_raw_lock = htab_use_raw_lock(htab);
++
+ hash = hash & HASHTAB_MAP_LOCK_MASK;
+- if (htab_use_raw_lock(htab))
++ if (use_raw_lock)
+ raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+ else
+ spin_unlock_irqrestore(&b->lock, flags);
+ __this_cpu_dec(*(htab->map_locked[hash]));
+- migrate_enable();
++ if (use_raw_lock)
++ preempt_enable();
++ else
++ migrate_enable();
+ }
+
+ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node);
+@@ -1691,8 +1704,11 @@ again_nocopy:
+ /* do not grab the lock unless need it (bucket_cnt > 0). */
+ if (locked) {
+ ret = htab_lock_bucket(htab, b, batch, &flags);
+- if (ret)
+- goto next_batch;
++ if (ret) {
++ rcu_read_unlock();
++ bpf_enable_instrumentation();
++ goto after_loop;
++ }
+ }
+
+ bucket_cnt = 0;
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 3814b0fd3a2c5..ed7649b047041 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1468,6 +1468,8 @@ BPF_CALL_4(bpf_dynptr_from_mem, void *, data, u32, size, u64, flags, struct bpf_
+ {
+ int err;
+
++ BTF_TYPE_EMIT(struct bpf_dynptr);
++
+ err = bpf_dynptr_check_size(size);
+ if (err)
+ goto error;
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index f798acd43a280..22e7a805c6723 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -4395,7 +4395,9 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
+ if (attr->task_fd_query.flags != 0)
+ return -EINVAL;
+
++ rcu_read_lock();
+ task = get_pid_task(find_vpid(pid), PIDTYPE_PID);
++ rcu_read_unlock();
+ if (!task)
+ return -ENOENT;
+
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index ff87e38af8a7a..ad76940b02ccf 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -895,7 +895,7 @@ u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *ru
+
+ run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx);
+
+- if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1)) {
++ if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+ inc_misses_counter(prog);
+ return 0;
+ }
+@@ -930,7 +930,7 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_
+ bpf_reset_run_ctx(run_ctx->saved_run_ctx);
+
+ update_prog_stats(prog, start);
+- __this_cpu_dec(*(prog->active));
++ this_cpu_dec(*(prog->active));
+ migrate_enable();
+ rcu_read_unlock();
+ }
+@@ -966,7 +966,7 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r
+ migrate_disable();
+ might_fault();
+
+- if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1)) {
++ if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+ inc_misses_counter(prog);
+ return 0;
+ }
+@@ -982,7 +982,7 @@ void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start,
+ bpf_reset_run_ctx(run_ctx->saved_run_ctx);
+
+ update_prog_stats(prog, start);
+- __this_cpu_dec(*(prog->active));
++ this_cpu_dec(*(prog->active));
+ migrate_enable();
+ rcu_read_unlock_trace();
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 3eadb14e090b7..8b5ea7f6b5365 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -467,25 +467,11 @@ static bool type_is_rdonly_mem(u32 type)
+ return type & MEM_RDONLY;
+ }
+
+-static bool arg_type_may_be_refcounted(enum bpf_arg_type type)
+-{
+- return type == ARG_PTR_TO_SOCK_COMMON;
+-}
+-
+ static bool type_may_be_null(u32 type)
+ {
+ return type & PTR_MAYBE_NULL;
+ }
+
+-static bool may_be_acquire_function(enum bpf_func_id func_id)
+-{
+- return func_id == BPF_FUNC_sk_lookup_tcp ||
+- func_id == BPF_FUNC_sk_lookup_udp ||
+- func_id == BPF_FUNC_skc_lookup_tcp ||
+- func_id == BPF_FUNC_map_lookup_elem ||
+- func_id == BPF_FUNC_ringbuf_reserve;
+-}
+-
+ static bool is_acquire_function(enum bpf_func_id func_id,
+ const struct bpf_map *map)
+ {
+@@ -518,6 +504,26 @@ static bool is_ptr_cast_function(enum bpf_func_id func_id)
+ func_id == BPF_FUNC_skc_to_tcp_request_sock;
+ }
+
++static bool is_dynptr_ref_function(enum bpf_func_id func_id)
++{
++ return func_id == BPF_FUNC_dynptr_data;
++}
++
++static bool helper_multiple_ref_obj_use(enum bpf_func_id func_id,
++ const struct bpf_map *map)
++{
++ int ref_obj_uses = 0;
++
++ if (is_ptr_cast_function(func_id))
++ ref_obj_uses++;
++ if (is_acquire_function(func_id, map))
++ ref_obj_uses++;
++ if (is_dynptr_ref_function(func_id))
++ ref_obj_uses++;
++
++ return ref_obj_uses > 1;
++}
++
+ static bool is_cmpxchg_insn(const struct bpf_insn *insn)
+ {
+ return BPF_CLASS(insn->code) == BPF_STX &&
+@@ -1086,6 +1092,7 @@ static int acquire_reference_state(struct bpf_verifier_env *env, int insn_idx)
+ id = ++env->id_gen;
+ state->refs[new_ofs].id = id;
+ state->refs[new_ofs].insn_idx = insn_idx;
++ state->refs[new_ofs].callback_ref = state->in_callback_fn ? state->frameno : 0;
+
+ return id;
+ }
+@@ -1098,6 +1105,9 @@ static int release_reference_state(struct bpf_func_state *state, int ptr_id)
+ last_idx = state->acquired_refs - 1;
+ for (i = 0; i < state->acquired_refs; i++) {
+ if (state->refs[i].id == ptr_id) {
++ /* Cannot release caller references in callbacks */
++ if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno)
++ return -EINVAL;
+ if (last_idx && i != last_idx)
+ memcpy(&state->refs[i], &state->refs[last_idx],
+ sizeof(*state->refs));
+@@ -6456,33 +6466,6 @@ static bool check_arg_pair_ok(const struct bpf_func_proto *fn)
+ return true;
+ }
+
+-static bool check_refcount_ok(const struct bpf_func_proto *fn, int func_id)
+-{
+- int count = 0;
+-
+- if (arg_type_may_be_refcounted(fn->arg1_type))
+- count++;
+- if (arg_type_may_be_refcounted(fn->arg2_type))
+- count++;
+- if (arg_type_may_be_refcounted(fn->arg3_type))
+- count++;
+- if (arg_type_may_be_refcounted(fn->arg4_type))
+- count++;
+- if (arg_type_may_be_refcounted(fn->arg5_type))
+- count++;
+-
+- /* A reference acquiring function cannot acquire
+- * another refcounted ptr.
+- */
+- if (may_be_acquire_function(func_id) && count)
+- return false;
+-
+- /* We only support one arg being unreferenced at the moment,
+- * which is sufficient for the helper functions we have right now.
+- */
+- return count <= 1;
+-}
+-
+ static bool check_btf_id_ok(const struct bpf_func_proto *fn)
+ {
+ int i;
+@@ -6506,8 +6489,7 @@ static int check_func_proto(const struct bpf_func_proto *fn, int func_id,
+ {
+ return check_raw_mode_ok(fn) &&
+ check_arg_pair_ok(fn) &&
+- check_btf_id_ok(fn) &&
+- check_refcount_ok(fn, func_id) ? 0 : -EINVAL;
++ check_btf_id_ok(fn) ? 0 : -EINVAL;
+ }
+
+ /* Packet data might have moved, any old PTR_TO_PACKET[_META,_END]
+@@ -6941,10 +6923,17 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ caller->regs[BPF_REG_0] = *r0;
+ }
+
+- /* Transfer references to the caller */
+- err = copy_reference_state(caller, callee);
+- if (err)
+- return err;
++ /* callback_fn frame should have released its own additions to parent's
++ * reference state at this point, or check_reference_leak would
++ * complain, hence it must be the same as the caller. There is no need
++ * to copy it back.
++ */
++ if (!callee->in_callback_fn) {
++ /* Transfer references to the caller */
++ err = copy_reference_state(caller, callee);
++ if (err)
++ return err;
++ }
+
+ *insn_idx = callee->callsite + 1;
+ if (env->log.level & BPF_LOG_LEVEL) {
+@@ -7066,13 +7055,20 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
+ static int check_reference_leak(struct bpf_verifier_env *env)
+ {
+ struct bpf_func_state *state = cur_func(env);
++ bool refs_lingering = false;
+ int i;
+
++ if (state->frameno && !state->in_callback_fn)
++ return 0;
++
+ for (i = 0; i < state->acquired_refs; i++) {
++ if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno)
++ continue;
+ verbose(env, "Unreleased reference id=%d alloc_insn=%d\n",
+ state->refs[i].id, state->refs[i].insn_idx);
++ refs_lingering = true;
+ }
+- return state->acquired_refs ? -EINVAL : 0;
++ return refs_lingering ? -EINVAL : 0;
+ }
+
+ static int check_bpf_snprintf_call(struct bpf_verifier_env *env,
+@@ -7344,6 +7340,23 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ }
+ }
+ break;
++ case BPF_FUNC_dynptr_data:
++ for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) {
++ if (arg_type_is_dynptr(fn->arg_type[i])) {
++ if (meta.ref_obj_id) {
++ verbose(env, "verifier internal error: meta.ref_obj_id already set\n");
++ return -EFAULT;
++ }
++ /* Find the id of the dynptr we're tracking the reference of */
++ meta.ref_obj_id = stack_slot_get_id(env, ®s[BPF_REG_1 + i]);
++ break;
++ }
++ }
++ if (i == MAX_BPF_FUNC_REG_ARGS) {
++ verbose(env, "verifier internal error: no dynptr in bpf_dynptr_data()\n");
++ return -EFAULT;
++ }
++ break;
+ }
+
+ if (err)
+@@ -7460,7 +7473,13 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ if (type_may_be_null(regs[BPF_REG_0].type))
+ regs[BPF_REG_0].id = ++env->id_gen;
+
+- if (is_ptr_cast_function(func_id)) {
++ if (helper_multiple_ref_obj_use(func_id, meta.map_ptr)) {
++ verbose(env, "verifier internal error: func %s#%d sets ref_obj_id more than once\n",
++ func_id_name(func_id), func_id);
++ return -EFAULT;
++ }
++
++ if (is_ptr_cast_function(func_id) || is_dynptr_ref_function(func_id)) {
+ /* For release_reference() */
+ regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
+ } else if (is_acquire_function(func_id, meta.map_ptr)) {
+@@ -7472,21 +7491,6 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ regs[BPF_REG_0].id = id;
+ /* For release_reference() */
+ regs[BPF_REG_0].ref_obj_id = id;
+- } else if (func_id == BPF_FUNC_dynptr_data) {
+- int dynptr_id = 0, i;
+-
+- /* Find the id of the dynptr we're acquiring a reference to */
+- for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) {
+- if (arg_type_is_dynptr(fn->arg_type[i])) {
+- if (dynptr_id) {
+- verbose(env, "verifier internal error: multiple dynptr args in func\n");
+- return -EFAULT;
+- }
+- dynptr_id = stack_slot_get_id(env, ®s[BPF_REG_1 + i]);
+- }
+- }
+- /* For release_reference() */
+- regs[BPF_REG_0].ref_obj_id = dynptr_id;
+ }
+
+ do_refine_retval_range(regs, fn->ret_type, func_id, &meta);
+@@ -12333,6 +12337,16 @@ static int do_check(struct bpf_verifier_env *env)
+ return -EINVAL;
+ }
+
++ /* We must do check_reference_leak here before
++ * prepare_func_exit to handle the case when
++ * state->curframe > 0, it may be a callback
++ * function, for which reference_state must
++ * match caller reference state when it exits.
++ */
++ err = check_reference_leak(env);
++ if (err)
++ return err;
++
+ if (state->curframe) {
+ /* exit from nested function */
+ err = prepare_func_exit(env, &env->insn_idx);
+@@ -12342,10 +12356,6 @@ static int do_check(struct bpf_verifier_env *env)
+ continue;
+ }
+
+- err = check_reference_leak(env);
+- if (err)
+- return err;
+-
+ err = check_return_code(env);
+ if (err)
+ return err;
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index 5f2090d051acb..29296a6374efa 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -6638,8 +6638,12 @@ struct cgroup *cgroup_get_from_path(const char *path)
+ {
+ struct kernfs_node *kn;
+ struct cgroup *cgrp = ERR_PTR(-ENOENT);
++ struct cgroup *root_cgrp;
+
+- kn = kernfs_walk_and_get(cgrp_dfl_root.cgrp.kn, path);
++ spin_lock_irq(&css_set_lock);
++ root_cgrp = current_cgns_cgroup_from_root(&cgrp_dfl_root);
++ kn = kernfs_walk_and_get(root_cgrp->kn, path);
++ spin_unlock_irq(&css_set_lock);
+ if (!kn)
+ goto out;
+
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 1f3a55297f39d..50bf837571ac8 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -33,6 +33,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/kmod.h>
++#include <linux/kthread.h>
+ #include <linux/list.h>
+ #include <linux/mempolicy.h>
+ #include <linux/mm.h>
+@@ -1127,10 +1128,18 @@ static void update_tasks_cpumask(struct cpuset *cs)
+ {
+ struct css_task_iter it;
+ struct task_struct *task;
++ bool top_cs = cs == &top_cpuset;
+
+ css_task_iter_start(&cs->css, 0, &it);
+- while ((task = css_task_iter_next(&it)))
++ while ((task = css_task_iter_next(&it))) {
++ /*
++ * Percpu kthreads in top_cpuset are ignored
++ */
++ if (top_cs && (task->flags & PF_KTHREAD) &&
++ kthread_is_per_cpu(task))
++ continue;
+ set_cpus_allowed_ptr(task, cs->effective_cpus);
++ }
+ css_task_iter_end(&it);
+ }
+
+@@ -2092,12 +2101,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
+ update_flag(CS_CPU_EXCLUSIVE, cs, 0);
+ }
+
+- /*
+- * Update cpumask of parent's tasks except when it is the top
+- * cpuset as some system daemons cannot be mapped to other CPUs.
+- */
+- if (parent != &top_cpuset)
+- update_tasks_cpumask(parent);
++ update_tasks_cpumask(parent);
+
+ if (parent->child_ecpus_count)
+ update_sibling_cpumasks(parent, cs, &tmpmask);
+diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
+index 5d03a2ad10661..30187b1d82759 100644
+--- a/kernel/livepatch/transition.c
++++ b/kernel/livepatch/transition.c
+@@ -610,9 +610,23 @@ void klp_reverse_transition(void)
+ /* Called from copy_process() during fork */
+ void klp_copy_process(struct task_struct *child)
+ {
+- child->patch_state = current->patch_state;
+
+- /* TIF_PATCH_PENDING gets copied in setup_thread_stack() */
++ /*
++ * The parent process may have gone through a KLP transition since
++ * the thread flag was copied in setup_thread_stack earlier. Bring
++ * the task flag up to date with the parent here.
++ *
++ * The operation is serialized against all klp_*_transition()
++ * operations by the tasklist_lock. The only exception is
++ * klp_update_patch_state(current), but we cannot race with
++ * that because we are current.
++ */
++ if (test_tsk_thread_flag(current, TIF_PATCH_PENDING))
++ set_tsk_thread_flag(child, TIF_PATCH_PENDING);
++ else
++ clear_tsk_thread_flag(child, TIF_PATCH_PENDING);
++
++ child->patch_state = current->patch_state;
+ }
+
+ /*
+diff --git a/kernel/module/tracking.c b/kernel/module/tracking.c
+index 7f8133044d092..af52cabfe6321 100644
+--- a/kernel/module/tracking.c
++++ b/kernel/module/tracking.c
+@@ -21,6 +21,9 @@ int try_add_tainted_module(struct module *mod)
+
+ module_assert_mutex_or_preempt();
+
++ if (!mod->taints)
++ goto out;
++
+ list_for_each_entry_rcu(mod_taint, &unloaded_tainted_modules, list,
+ lockdep_is_held(&module_mutex)) {
+ if (!strcmp(mod_taint->name, mod->name) &&
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index 83c7e6620d403..f5bf6fb430dab 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -560,7 +560,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
+ static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
+ {
+ /* Complain if the scheduler has not started. */
+- RCU_LOCKDEP_WARN(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
++ WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
+ "synchronize_rcu_tasks called too soon");
+
+ // If the grace-period kthread is running, use it.
+@@ -1500,6 +1500,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)
+ if (rcu_tasks_trace_pertask_prep(t, true))
+ trc_add_holdout(t, hop);
+ rcu_read_unlock();
++ cond_resched_tasks_rcu_qs();
+ }
+
+ // Only after all running tasks have been accounted for is it
+@@ -1520,6 +1521,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)
+ raw_spin_lock_irqsave_rcu_node(rtpcp, flags);
+ }
+ raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags);
++ cond_resched_tasks_rcu_qs();
+ }
+
+ // Re-enable CPU hotplug now that the holdout list is populated.
+@@ -1619,6 +1621,7 @@ static void check_all_holdout_tasks_trace(struct list_head *hop,
+ trc_del_holdout(t);
+ else if (needreport)
+ show_stalled_task_trace(t, firstreport);
++ cond_resched_tasks_rcu_qs();
+ }
+
+ // Re-enable CPU hotplug now that the holdout list scan has completed.
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 79aea7df4345e..eb435941e92fd 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -3183,15 +3183,16 @@ static void fill_page_cache_func(struct work_struct *work)
+ bnode = (struct kvfree_rcu_bulk_data *)
+ __get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+
+- if (bnode) {
+- raw_spin_lock_irqsave(&krcp->lock, flags);
+- pushed = put_cached_bnode(krcp, bnode);
+- raw_spin_unlock_irqrestore(&krcp->lock, flags);
++ if (!bnode)
++ break;
+
+- if (!pushed) {
+- free_page((unsigned long) bnode);
+- break;
+- }
++ raw_spin_lock_irqsave(&krcp->lock, flags);
++ pushed = put_cached_bnode(krcp, bnode);
++ raw_spin_unlock_irqrestore(&krcp->lock, flags);
++
++ if (!pushed) {
++ free_page((unsigned long) bnode);
++ break;
+ }
+ }
+
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
+index 438ecae6bd7e7..49468b4d1b43f 100644
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -641,7 +641,8 @@ static void rcu_read_unlock_special(struct task_struct *t)
+
+ expboost = (t->rcu_blocked_node && READ_ONCE(t->rcu_blocked_node->exp_tasks)) ||
+ (rdp->grpmask & READ_ONCE(rnp->expmask)) ||
+- IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) ||
++ (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) &&
++ ((rdp->grpmask & READ_ONCE(rnp->qsmask)) || t->rcu_blocked_node)) ||
+ (IS_ENABLED(CONFIG_RCU_BOOST) && irqs_were_disabled &&
+ t->rcu_blocked_node);
+ // Need to defer quiescent state until everything is enabled.
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 68e5cdd24cef8..b1daf7c9b895a 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -1026,6 +1026,22 @@ static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = {
+ .arg1_type = ARG_PTR_TO_CTX,
+ };
+
++#ifdef CONFIG_X86_KERNEL_IBT
++static unsigned long get_entry_ip(unsigned long fentry_ip)
++{
++ u32 instr;
++
++ /* Being extra safe in here in case entry ip is on the page-edge. */
++ if (get_kernel_nofault(instr, (u32 *) fentry_ip - 1))
++ return fentry_ip;
++ if (is_endbr(instr))
++ fentry_ip -= ENDBR_INSN_SIZE;
++ return fentry_ip;
++}
++#else
++#define get_entry_ip(fentry_ip) fentry_ip
++#endif
++
+ BPF_CALL_1(bpf_get_func_ip_kprobe, struct pt_regs *, regs)
+ {
+ struct kprobe *kp = kprobe_running();
+@@ -2414,13 +2430,13 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
+ }
+
+ static void
+-kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
++kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
+ struct pt_regs *regs)
+ {
+ struct bpf_kprobe_multi_link *link;
+
+ link = container_of(fp, struct bpf_kprobe_multi_link, fp);
+- kprobe_multi_link_prog_run(link, entry_ip, regs);
++ kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs);
+ }
+
+ static int symbols_cmp_r(const void *a, const void *b, const void *priv)
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 439e2ab6905ee..83362a1557916 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1644,6 +1644,18 @@ ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_ex
+ static struct ftrace_ops *
+ ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
+
++static bool skip_record(struct dyn_ftrace *rec)
++{
++ /*
++ * At boot up, weak functions are set to disable. Function tracing
++ * can be enabled before they are, and they still need to be disabled now.
++ * If the record is disabled, still continue if it is marked as already
++ * enabled (this is needed to keep the accounting working).
++ */
++ return rec->flags & FTRACE_FL_DISABLED &&
++ !(rec->flags & FTRACE_FL_ENABLED);
++}
++
+ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
+ int filter_hash,
+ bool inc)
+@@ -1693,7 +1705,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
+ int in_hash = 0;
+ int match = 0;
+
+- if (rec->flags & FTRACE_FL_DISABLED)
++ if (skip_record(rec))
+ continue;
+
+ if (all) {
+@@ -2126,7 +2138,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
+
+ ftrace_bug_type = FTRACE_BUG_UNKNOWN;
+
+- if (rec->flags & FTRACE_FL_DISABLED)
++ if (skip_record(rec))
+ return FTRACE_UPDATE_IGNORE;
+
+ /*
+@@ -2241,7 +2253,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
+ if (update) {
+ /* If there's no more users, clear all flags */
+ if (!ftrace_rec_count(rec))
+- rec->flags = 0;
++ rec->flags &= FTRACE_FL_DISABLED;
+ else
+ /*
+ * Just disable the record, but keep the ops TRAMP
+@@ -2634,7 +2646,7 @@ void __weak ftrace_replace_code(int mod_flags)
+
+ do_for_each_ftrace_rec(pg, rec) {
+
+- if (rec->flags & FTRACE_FL_DISABLED)
++ if (skip_record(rec))
+ continue;
+
+ failed = __ftrace_replace_code(rec, enable);
+@@ -5427,6 +5439,8 @@ static struct ftrace_ops stub_ops = {
+ * it is safe to modify the ftrace record, where it should be
+ * currently calling @old_addr directly, to call @new_addr.
+ *
++ * This is called with direct_mutex locked.
++ *
+ * Safety checks should be made to make sure that the code at
+ * @rec->ip is currently calling @old_addr. And this must
+ * also update entry->direct to @new_addr.
+@@ -5439,6 +5453,8 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
+ unsigned long ip = rec->ip;
+ int ret;
+
++ lockdep_assert_held(&direct_mutex);
++
+ /*
+ * The ftrace_lock was used to determine if the record
+ * had more than one registered user to it. If it did,
+@@ -5461,7 +5477,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
+ if (ret)
+ goto out_lock;
+
+- ret = register_ftrace_function(&stub_ops);
++ ret = register_ftrace_function_nolock(&stub_ops);
+ if (ret) {
+ ftrace_set_filter_ip(&stub_ops, ip, 1, 0);
+ goto out_lock;
+@@ -6081,8 +6097,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
+
+ if (filter_hash) {
+ orig_hash = &iter->ops->func_hash->filter_hash;
+- if (iter->tr && !list_empty(&iter->tr->mod_trace))
+- iter->hash->flags |= FTRACE_HASH_FL_MOD;
++ if (iter->tr) {
++ if (list_empty(&iter->tr->mod_trace))
++ iter->hash->flags &= ~FTRACE_HASH_FL_MOD;
++ else
++ iter->hash->flags |= FTRACE_HASH_FL_MOD;
++ }
+ } else
+ orig_hash = &iter->ops->func_hash->notrace_hash;
+
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index 18b0f1cbb947f..80e04a1e19772 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -35,6 +35,45 @@
+ static struct trace_event_file *gen_kprobe_test;
+ static struct trace_event_file *gen_kretprobe_test;
+
++#define KPROBE_GEN_TEST_FUNC "do_sys_open"
++
++/* X86 */
++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
++#define KPROBE_GEN_TEST_ARG0 "dfd=%ax"
++#define KPROBE_GEN_TEST_ARG1 "filename=%dx"
++#define KPROBE_GEN_TEST_ARG2 "flags=%cx"
++#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)"
++
++/* ARM64 */
++#elif defined(CONFIG_ARM64)
++#define KPROBE_GEN_TEST_ARG0 "dfd=%x0"
++#define KPROBE_GEN_TEST_ARG1 "filename=%x1"
++#define KPROBE_GEN_TEST_ARG2 "flags=%x2"
++#define KPROBE_GEN_TEST_ARG3 "mode=%x3"
++
++/* ARM */
++#elif defined(CONFIG_ARM)
++#define KPROBE_GEN_TEST_ARG0 "dfd=%r0"
++#define KPROBE_GEN_TEST_ARG1 "filename=%r1"
++#define KPROBE_GEN_TEST_ARG2 "flags=%r2"
++#define KPROBE_GEN_TEST_ARG3 "mode=%r3"
++
++/* RISCV */
++#elif defined(CONFIG_RISCV)
++#define KPROBE_GEN_TEST_ARG0 "dfd=%a0"
++#define KPROBE_GEN_TEST_ARG1 "filename=%a1"
++#define KPROBE_GEN_TEST_ARG2 "flags=%a2"
++#define KPROBE_GEN_TEST_ARG3 "mode=%a3"
++
++/* others */
++#else
++#define KPROBE_GEN_TEST_ARG0 NULL
++#define KPROBE_GEN_TEST_ARG1 NULL
++#define KPROBE_GEN_TEST_ARG2 NULL
++#define KPROBE_GEN_TEST_ARG3 NULL
++#endif
++
++
+ /*
+ * Test to make sure we can create a kprobe event, then add more
+ * fields.
+@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void)
+ * fields.
+ */
+ ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
+- "do_sys_open",
+- "dfd=%ax", "filename=%dx");
++ KPROBE_GEN_TEST_FUNC,
++ KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
+ if (ret)
+ goto free;
+
+ /* Use kprobe_event_add_fields to add the rest of the fields */
+
+- ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");
++ ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
+ if (ret)
+ goto free;
+
+@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void)
+ * Define the kretprobe event.
+ */
+ ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
+- "do_sys_open",
++ KPROBE_GEN_TEST_FUNC,
+ "$retval");
+ if (ret)
+ goto free;
+@@ -206,7 +245,7 @@ static void __exit kprobe_event_gen_test_exit(void)
+ WARN_ON(kprobe_event_delete("gen_kprobe_test"));
+
+ /* Disable the event or you can't remove it */
+- WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
++ WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+ "kprobes",
+ "gen_kretprobe_test", false));
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index d59b6a328b7fe..c3f354cfc5ba1 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -413,6 +413,7 @@ struct rb_irq_work {
+ struct irq_work work;
+ wait_queue_head_t waiters;
+ wait_queue_head_t full_waiters;
++ long wait_index;
+ bool waiters_pending;
+ bool full_waiters_pending;
+ bool wakeup_full;
+@@ -917,12 +918,44 @@ static void rb_wake_up_waiters(struct irq_work *work)
+ struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work);
+
+ wake_up_all(&rbwork->waiters);
+- if (rbwork->wakeup_full) {
++ if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
+ rbwork->wakeup_full = false;
++ rbwork->full_waiters_pending = false;
+ wake_up_all(&rbwork->full_waiters);
+ }
+ }
+
++/**
++ * ring_buffer_wake_waiters - wake up any waiters on this ring buffer
++ * @buffer: The ring buffer to wake waiters on
++ *
++ * In the case of a file that represents a ring buffer is closing,
++ * it is prudent to wake up any waiters that are on this.
++ */
++void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
++{
++ struct ring_buffer_per_cpu *cpu_buffer;
++ struct rb_irq_work *rbwork;
++
++ if (cpu == RING_BUFFER_ALL_CPUS) {
++
++ /* Wake up individual ones too. One level recursion */
++ for_each_buffer_cpu(buffer, cpu)
++ ring_buffer_wake_waiters(buffer, cpu);
++
++ rbwork = &buffer->irq_work;
++ } else {
++ cpu_buffer = buffer->buffers[cpu];
++ rbwork = &cpu_buffer->irq_work;
++ }
++
++ rbwork->wait_index++;
++ /* make sure the waiters see the new index */
++ smp_wmb();
++
++ rb_wake_up_waiters(&rbwork->work);
++}
++
+ /**
+ * ring_buffer_wait - wait for input to the ring buffer
+ * @buffer: buffer to wait on
+@@ -938,6 +971,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ struct ring_buffer_per_cpu *cpu_buffer;
+ DEFINE_WAIT(wait);
+ struct rb_irq_work *work;
++ long wait_index;
+ int ret = 0;
+
+ /*
+@@ -956,6 +990,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ work = &cpu_buffer->irq_work;
+ }
+
++ wait_index = READ_ONCE(work->wait_index);
+
+ while (true) {
+ if (full)
+@@ -1011,7 +1046,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ nr_pages = cpu_buffer->nr_pages;
+ dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
+ if (!cpu_buffer->shortest_full ||
+- cpu_buffer->shortest_full < full)
++ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ if (!pagebusy &&
+@@ -1020,6 +1055,11 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ }
+
+ schedule();
++
++ /* Make sure to see the new wait index */
++ smp_rmb();
++ if (wait_index != work->wait_index)
++ break;
+ }
+
+ if (full)
+@@ -2608,6 +2648,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
+ /* Mark the rest of the page with padding */
+ rb_event_set_padding(event);
+
++ /* Make sure the padding is visible before the write update */
++ smp_wmb();
++
+ /* Set the write back to the previous setting */
+ local_sub(length, &tail_page->write);
+ return;
+@@ -2619,6 +2662,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
+ /* time delta must be non zero */
+ event->time_delta = 1;
+
++ /* Make sure the padding is visible before the tail_page->write update */
++ smp_wmb();
++
+ /* Set write to end of buffer */
+ length = (tail + length) - BUF_PAGE_SIZE;
+ local_sub(length, &tail_page->write);
+@@ -4587,6 +4633,33 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+ arch_spin_unlock(&cpu_buffer->lock);
+ local_irq_restore(flags);
+
++ /*
++ * The writer has preempt disable, wait for it. But not forever
++ * Although, 1 second is pretty much "forever"
++ */
++#define USECS_WAIT 1000000
++ for (nr_loops = 0; nr_loops < USECS_WAIT; nr_loops++) {
++ /* If the write is past the end of page, a writer is still updating it */
++ if (likely(!reader || rb_page_write(reader) <= BUF_PAGE_SIZE))
++ break;
++
++ udelay(1);
++
++ /* Get the latest version of the reader write value */
++ smp_rmb();
++ }
++
++ /* The writer is not moving forward? Something is wrong */
++ if (RB_WARN_ON(cpu_buffer, nr_loops == USECS_WAIT))
++ reader = NULL;
++
++ /*
++ * Make sure we see any padding after the write update
++ * (see rb_reset_tail())
++ */
++ smp_rmb();
++
++
+ return reader;
+ }
+
+@@ -5616,7 +5689,15 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
+ unsigned int pos = 0;
+ unsigned int size;
+
+- if (full)
++ /*
++ * If a full page is expected, this can still be returned
++ * if there's been a previous partial read and the
++ * rest of the page can be read and the commit page is off
++ * the reader page.
++ */
++ if (full &&
++ (!read || (len < (commit - read)) ||
++ cpu_buffer->reader_page == cpu_buffer->commit_page))
+ goto out_unlock;
+
+ if (len > (commit - read))
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index d3005279165d9..cc65887b31bd9 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1193,12 +1193,14 @@ void *tracing_cond_snapshot_data(struct trace_array *tr)
+ {
+ void *cond_data = NULL;
+
++ local_irq_disable();
+ arch_spin_lock(&tr->max_lock);
+
+ if (tr->cond_snapshot)
+ cond_data = tr->cond_snapshot->cond_data;
+
+ arch_spin_unlock(&tr->max_lock);
++ local_irq_enable();
+
+ return cond_data;
+ }
+@@ -1334,9 +1336,11 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data,
+ goto fail_unlock;
+ }
+
++ local_irq_disable();
+ arch_spin_lock(&tr->max_lock);
+ tr->cond_snapshot = cond_snapshot;
+ arch_spin_unlock(&tr->max_lock);
++ local_irq_enable();
+
+ mutex_unlock(&trace_types_lock);
+
+@@ -1363,6 +1367,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ {
+ int ret = 0;
+
++ local_irq_disable();
+ arch_spin_lock(&tr->max_lock);
+
+ if (!tr->cond_snapshot)
+@@ -1373,6 +1378,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ }
+
+ arch_spin_unlock(&tr->max_lock);
++ local_irq_enable();
+
+ return ret;
+ }
+@@ -2200,6 +2206,11 @@ static size_t tgid_map_max;
+
+ #define SAVED_CMDLINES_DEFAULT 128
+ #define NO_CMDLINE_MAP UINT_MAX
++/*
++ * Preemption must be disabled before acquiring trace_cmdline_lock.
++ * The various trace_arrays' max_lock must be acquired in a context
++ * where interrupt is disabled.
++ */
+ static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+ struct saved_cmdlines_buffer {
+ unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
+@@ -2412,7 +2423,11 @@ static int trace_save_cmdline(struct task_struct *tsk)
+ * the lock, but we also don't want to spin
+ * nor do we want to disable interrupts,
+ * so if we miss here, then better luck next time.
++ *
++ * This is called within the scheduler and wake up, so interrupts
++ * had better been disabled and run queue lock been held.
+ */
++ lockdep_assert_preemption_disabled();
+ if (!arch_spin_trylock(&trace_cmdline_lock))
+ return 0;
+
+@@ -5890,9 +5905,11 @@ tracing_saved_cmdlines_size_read(struct file *filp, char __user *ubuf,
+ char buf[64];
+ int r;
+
++ preempt_disable();
+ arch_spin_lock(&trace_cmdline_lock);
+ r = scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num);
+ arch_spin_unlock(&trace_cmdline_lock);
++ preempt_enable();
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+ }
+@@ -5917,10 +5934,12 @@ static int tracing_resize_saved_cmdlines(unsigned int val)
+ return -ENOMEM;
+ }
+
++ preempt_disable();
+ arch_spin_lock(&trace_cmdline_lock);
+ savedcmd_temp = savedcmd;
+ savedcmd = s;
+ arch_spin_unlock(&trace_cmdline_lock);
++ preempt_enable();
+ free_saved_cmdlines_buffer(savedcmd_temp);
+
+ return 0;
+@@ -6373,10 +6392,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+
+ #ifdef CONFIG_TRACER_SNAPSHOT
+ if (t->use_max_tr) {
++ local_irq_disable();
+ arch_spin_lock(&tr->max_lock);
+ if (tr->cond_snapshot)
+ ret = -EBUSY;
+ arch_spin_unlock(&tr->max_lock);
++ local_irq_enable();
+ if (ret)
+ goto out;
+ }
+@@ -6407,12 +6428,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+ if (tr->current_trace->reset)
+ tr->current_trace->reset(tr);
+
++#ifdef CONFIG_TRACER_MAX_TRACE
++ had_max_tr = tr->current_trace->use_max_tr;
++
+ /* Current trace needs to be nop_trace before synchronize_rcu */
+ tr->current_trace = &nop_trace;
+
+-#ifdef CONFIG_TRACER_MAX_TRACE
+- had_max_tr = tr->allocated_snapshot;
+-
+ if (had_max_tr && !t->use_max_tr) {
+ /*
+ * We need to make sure that the update_max_tr sees that
+@@ -6425,11 +6446,13 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+ free_snapshot(tr);
+ }
+
+- if (t->use_max_tr && !had_max_tr) {
++ if (t->use_max_tr && !tr->allocated_snapshot) {
+ ret = tracing_alloc_snapshot_instance(tr);
+ if (ret < 0)
+ goto out;
+ }
++#else
++ tr->current_trace = &nop_trace;
+ #endif
+
+ if (t->init) {
+@@ -7436,10 +7459,12 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ goto out;
+ }
+
++ local_irq_disable();
+ arch_spin_lock(&tr->max_lock);
+ if (tr->cond_snapshot)
+ ret = -EBUSY;
+ arch_spin_unlock(&tr->max_lock);
++ local_irq_enable();
+ if (ret)
+ goto out;
+
+@@ -8137,6 +8162,12 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
+
+ __trace_array_put(iter->tr);
+
++ iter->wait_index++;
++ /* Make sure the waiters see the new wait_index */
++ smp_wmb();
++
++ ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
++
+ if (info->spare)
+ ring_buffer_free_read_page(iter->array_buffer->buffer,
+ info->spare_cpu, info->spare);
+@@ -8290,6 +8321,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+
+ /* did we read anything? */
+ if (!spd.nr_pages) {
++ long wait_index;
++
+ if (ret)
+ goto out;
+
+@@ -8297,10 +8330,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+ if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
+ goto out;
+
++ wait_index = READ_ONCE(iter->wait_index);
++
+ ret = wait_on_pipe(iter, iter->tr->buffer_percent);
+ if (ret)
+ goto out;
+
++ /* No need to wait after waking up when tracing is off */
++ if (!tracer_tracing_is_on(iter->tr))
++ goto out;
++
++ /* Make sure we see the new wait_index */
++ smp_rmb();
++ if (wait_index != iter->wait_index)
++ goto out;
++
+ goto again;
+ }
+
+@@ -8311,12 +8355,34 @@ out:
+ return ret;
+ }
+
++/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */
++static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ struct ftrace_buffer_info *info = file->private_data;
++ struct trace_iterator *iter = &info->iter;
++
++ if (cmd)
++ return -ENOIOCTLCMD;
++
++ mutex_lock(&trace_types_lock);
++
++ iter->wait_index++;
++ /* Make sure the waiters see the new wait_index */
++ smp_wmb();
++
++ ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
++
++ mutex_unlock(&trace_types_lock);
++ return 0;
++}
++
+ static const struct file_operations tracing_buffers_fops = {
+ .open = tracing_buffers_open,
+ .read = tracing_buffers_read,
+ .poll = tracing_buffers_poll,
+ .release = tracing_buffers_release,
+ .splice_read = tracing_buffers_splice_read,
++ .unlocked_ioctl = tracing_buffers_ioctl,
+ .llseek = no_llseek,
+ };
+
+@@ -9005,6 +9071,8 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
+ tracer_tracing_off(tr);
+ if (tr->current_trace->stop)
+ tr->current_trace->stop(tr);
++ /* Wake up any waiters */
++ ring_buffer_wake_waiters(buffer, RING_BUFFER_ALL_CPUS);
+ }
+ mutex_unlock(&trace_types_lock);
+ }
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 1783e34789124..860f5fb9514d7 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -16,6 +16,7 @@
+ #include "trace_dynevent.h"
+ #include "trace_probe.h"
+ #include "trace_probe_tmpl.h"
++#include "trace_probe_kernel.h"
+
+ #define EPROBE_EVENT_SYSTEM "eprobes"
+
+@@ -453,29 +454,14 @@ NOKPROBE_SYMBOL(process_fetch_insn)
+ static nokprobe_inline int
+ fetch_store_strlen_user(unsigned long addr)
+ {
+- const void __user *uaddr = (__force const void __user *)addr;
+-
+- return strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++ return kern_fetch_store_strlen_user(addr);
+ }
+
+ /* Return the length of string -- including null terminal byte */
+ static nokprobe_inline int
+ fetch_store_strlen(unsigned long addr)
+ {
+- int ret, len = 0;
+- u8 c;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+- if (addr < TASK_SIZE)
+- return fetch_store_strlen_user(addr);
+-#endif
+-
+- do {
+- ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
+- len++;
+- } while (c && ret == 0 && len < MAX_STRING_SIZE);
+-
+- return (ret < 0) ? ret : len;
++ return kern_fetch_store_strlen(addr);
+ }
+
+ /*
+@@ -485,21 +471,7 @@ fetch_store_strlen(unsigned long addr)
+ static nokprobe_inline int
+ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ {
+- const void __user *uaddr = (__force const void __user *)addr;
+- int maxlen = get_loc_len(*(u32 *)dest);
+- void *__dest;
+- long ret;
+-
+- if (unlikely(!maxlen))
+- return -ENOMEM;
+-
+- __dest = get_loc_data(dest, base);
+-
+- ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
+- if (ret >= 0)
+- *(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+- return ret;
++ return kern_fetch_store_string_user(addr, dest, base);
+ }
+
+ /*
+@@ -509,29 +481,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ static nokprobe_inline int
+ fetch_store_string(unsigned long addr, void *dest, void *base)
+ {
+- int maxlen = get_loc_len(*(u32 *)dest);
+- void *__dest;
+- long ret;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+- if ((unsigned long)addr < TASK_SIZE)
+- return fetch_store_string_user(addr, dest, base);
+-#endif
+-
+- if (unlikely(!maxlen))
+- return -ENOMEM;
+-
+- __dest = get_loc_data(dest, base);
+-
+- /*
+- * Try to get string again, since the string can be changed while
+- * probing.
+- */
+- ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
+- if (ret >= 0)
+- *(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+- return ret;
++ return kern_fetch_store_string(addr, dest, base);
+ }
+
+ static nokprobe_inline int
+@@ -968,8 +918,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
+ }
+
+ if (!event) {
+- strscpy(buf1, argv[1], MAX_EVENT_NAME_LEN);
+- sanitize_event_name(buf1);
++ strscpy(buf1, sys_event, MAX_EVENT_NAME_LEN);
+ event = buf1;
+ }
+
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 5e8c07aef071b..e310052dc83ce 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -17,6 +17,8 @@
+ /* for gfp flag names */
+ #include <linux/trace_events.h>
+ #include <trace/events/mmflags.h>
++#include "trace_probe.h"
++#include "trace_probe_kernel.h"
+
+ #include "trace_synth.h"
+
+@@ -409,6 +411,7 @@ static unsigned int trace_string(struct synth_trace_event *entry,
+ {
+ unsigned int len = 0;
+ char *str_field;
++ int ret;
+
+ if (is_dynamic) {
+ u32 data_offset;
+@@ -417,19 +420,27 @@ static unsigned int trace_string(struct synth_trace_event *entry,
+ data_offset += event->n_u64 * sizeof(u64);
+ data_offset += data_size;
+
+- str_field = (char *)entry + data_offset;
+-
+- len = strlen(str_val) + 1;
+- strscpy(str_field, str_val, len);
++ len = kern_fetch_store_strlen((unsigned long)str_val);
+
+ data_offset |= len << 16;
+ *(u32 *)&entry->fields[*n_u64] = data_offset;
+
++ ret = kern_fetch_store_string((unsigned long)str_val, &entry->fields[*n_u64], entry);
++
+ (*n_u64)++;
+ } else {
+ str_field = (char *)&entry->fields[*n_u64];
+
+- strscpy(str_field, str_val, STR_VAR_LEN_MAX);
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++ if ((unsigned long)str_val < TASK_SIZE)
++ ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX);
++ else
++#endif
++ ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX);
++
++ if (ret < 0)
++ strcpy(str_field, FAULT_STRING);
++
+ (*n_u64) += STR_VAR_LEN_MAX / sizeof(u64);
+ }
+
+@@ -462,7 +473,7 @@ static notrace void trace_event_raw_event_synth(void *__data,
+ val_idx = var_ref_idx[field_pos];
+ str_val = (char *)(long)var_ref_vals[val_idx];
+
+- len = strlen(str_val) + 1;
++ len = kern_fetch_store_strlen((unsigned long)str_val);
+
+ fields_size += len;
+ }
+diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
+index 23f7f0ec4f4cf..5a75b039e5860 100644
+--- a/kernel/trace/trace_kprobe.c
++++ b/kernel/trace/trace_kprobe.c
+@@ -20,6 +20,7 @@
+ #include "trace_kprobe_selftest.h"
+ #include "trace_probe.h"
+ #include "trace_probe_tmpl.h"
++#include "trace_probe_kernel.h"
+
+ #define KPROBE_EVENT_SYSTEM "kprobes"
+ #define KRETPROBE_MAXACTIVE_MAX 4096
+@@ -1223,29 +1224,14 @@ static const struct file_operations kprobe_profile_ops = {
+ static nokprobe_inline int
+ fetch_store_strlen_user(unsigned long addr)
+ {
+- const void __user *uaddr = (__force const void __user *)addr;
+-
+- return strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++ return kern_fetch_store_strlen_user(addr);
+ }
+
+ /* Return the length of string -- including null terminal byte */
+ static nokprobe_inline int
+ fetch_store_strlen(unsigned long addr)
+ {
+- int ret, len = 0;
+- u8 c;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+- if (addr < TASK_SIZE)
+- return fetch_store_strlen_user(addr);
+-#endif
+-
+- do {
+- ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
+- len++;
+- } while (c && ret == 0 && len < MAX_STRING_SIZE);
+-
+- return (ret < 0) ? ret : len;
++ return kern_fetch_store_strlen(addr);
+ }
+
+ /*
+@@ -1255,21 +1241,7 @@ fetch_store_strlen(unsigned long addr)
+ static nokprobe_inline int
+ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ {
+- const void __user *uaddr = (__force const void __user *)addr;
+- int maxlen = get_loc_len(*(u32 *)dest);
+- void *__dest;
+- long ret;
+-
+- if (unlikely(!maxlen))
+- return -ENOMEM;
+-
+- __dest = get_loc_data(dest, base);
+-
+- ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
+- if (ret >= 0)
+- *(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+- return ret;
++ return kern_fetch_store_string_user(addr, dest, base);
+ }
+
+ /*
+@@ -1279,29 +1251,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ static nokprobe_inline int
+ fetch_store_string(unsigned long addr, void *dest, void *base)
+ {
+- int maxlen = get_loc_len(*(u32 *)dest);
+- void *__dest;
+- long ret;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+- if ((unsigned long)addr < TASK_SIZE)
+- return fetch_store_string_user(addr, dest, base);
+-#endif
+-
+- if (unlikely(!maxlen))
+- return -ENOMEM;
+-
+- __dest = get_loc_data(dest, base);
+-
+- /*
+- * Try to get string again, since the string can be changed while
+- * probing.
+- */
+- ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
+- if (ret >= 0)
+- *(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+- return ret;
++ return kern_fetch_store_string(addr, dest, base);
+ }
+
+ static nokprobe_inline int
+diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
+index 313439920a8ce..78d536d3ff3db 100644
+--- a/kernel/trace/trace_osnoise.c
++++ b/kernel/trace/trace_osnoise.c
+@@ -1786,8 +1786,9 @@ static int start_per_cpu_kthreads(void)
+ for_each_cpu(cpu, current_mask) {
+ retval = start_kthread(cpu);
+ if (retval) {
++ cpus_read_unlock();
+ stop_per_cpu_kthreads();
+- break;
++ return retval;
+ }
+ }
+
+diff --git a/kernel/trace/trace_probe_kernel.h b/kernel/trace/trace_probe_kernel.h
+new file mode 100644
+index 0000000000000..77dbd9ff97826
+--- /dev/null
++++ b/kernel/trace/trace_probe_kernel.h
+@@ -0,0 +1,115 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __TRACE_PROBE_KERNEL_H_
++#define __TRACE_PROBE_KERNEL_H_
++
++#define FAULT_STRING "(fault)"
++
++/*
++ * This depends on trace_probe.h, but can not include it due to
++ * the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c.
++ * Which means that any other user must include trace_probe.h before including
++ * this file.
++ */
++/* Return the length of string -- including null terminal byte */
++static nokprobe_inline int
++kern_fetch_store_strlen_user(unsigned long addr)
++{
++ const void __user *uaddr = (__force const void __user *)addr;
++ int ret;
++
++ ret = strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++ /*
++ * strnlen_user_nofault returns zero on fault, insert the
++ * FAULT_STRING when that occurs.
++ */
++ if (ret <= 0)
++ return strlen(FAULT_STRING) + 1;
++ return ret;
++}
++
++/* Return the length of string -- including null terminal byte */
++static nokprobe_inline int
++kern_fetch_store_strlen(unsigned long addr)
++{
++ int ret, len = 0;
++ u8 c;
++
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++ if (addr < TASK_SIZE)
++ return kern_fetch_store_strlen_user(addr);
++#endif
++
++ do {
++ ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
++ len++;
++ } while (c && ret == 0 && len < MAX_STRING_SIZE);
++
++ /* For faults, return enough to hold the FAULT_STRING */
++ return (ret < 0) ? strlen(FAULT_STRING) + 1 : len;
++}
++
++static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void *base, int len)
++{
++ if (ret >= 0) {
++ *(u32 *)dest = make_data_loc(ret, __dest - base);
++ } else {
++ strscpy(__dest, FAULT_STRING, len);
++ ret = strlen(__dest) + 1;
++ }
++}
++
++/*
++ * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf
++ * with max length and relative data location.
++ */
++static nokprobe_inline int
++kern_fetch_store_string_user(unsigned long addr, void *dest, void *base)
++{
++ const void __user *uaddr = (__force const void __user *)addr;
++ int maxlen = get_loc_len(*(u32 *)dest);
++ void *__dest;
++ long ret;
++
++ if (unlikely(!maxlen))
++ return -ENOMEM;
++
++ __dest = get_loc_data(dest, base);
++
++ ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
++ set_data_loc(ret, dest, __dest, base, maxlen);
++
++ return ret;
++}
++
++/*
++ * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
++ * length and relative data location.
++ */
++static nokprobe_inline int
++kern_fetch_store_string(unsigned long addr, void *dest, void *base)
++{
++ int maxlen = get_loc_len(*(u32 *)dest);
++ void *__dest;
++ long ret;
++
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++ if ((unsigned long)addr < TASK_SIZE)
++ return kern_fetch_store_string_user(addr, dest, base);
++#endif
++
++ if (unlikely(!maxlen))
++ return -ENOMEM;
++
++ __dest = get_loc_data(dest, base);
++
++ /*
++ * Try to get string again, since the string can be changed while
++ * probing.
++ */
++ ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
++ set_data_loc(ret, dest, __dest, base, maxlen);
++
++ return ret;
++}
++
++#endif /* __TRACE_PROBE_KERNEL_H_ */
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index d3e5f36bb01e0..cb131fad117cc 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -231,6 +231,11 @@ config DEBUG_INFO
+ in the "Debug information" choice below, indicating that debug
+ information will be generated for build targets.
+
++# Clang is known to generate .{s,u}leb128 with symbol deltas with DWARF5, which
++# some targets may not support: https://sourceware.org/bugzilla/show_bug.cgi?id=27215
++config AS_HAS_NON_CONST_LEB128
++ def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:)
++
+ choice
+ prompt "Debug information"
+ depends on DEBUG_KERNEL
+@@ -253,6 +258,7 @@ config DEBUG_INFO_NONE
+ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
+ bool "Rely on the toolchain's implicit default DWARF version"
+ select DEBUG_INFO
++ depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128)
+ help
+ The implicit default version of DWARF debug info produced by a
+ toolchain changes over time.
+@@ -264,7 +270,7 @@ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
+ config DEBUG_INFO_DWARF4
+ bool "Generate DWARF Version 4 debuginfo"
+ select DEBUG_INFO
+- depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
++ depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)
+ help
+ Generate DWARF v4 debug info. This requires gcc 4.5+, binutils 2.35.2
+ if using clang without clang's integrated assembler, and gdb 7.0+.
+@@ -276,7 +282,7 @@ config DEBUG_INFO_DWARF4
+ config DEBUG_INFO_DWARF5
+ bool "Generate DWARF Version 5 debuginfo"
+ select DEBUG_INFO
+- depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
++ depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128)
+ help
+ Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
+ 5.0+ accepts the -gdwarf-5 flag but only had partial support for some
+diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
+index dd7f56af9aed3..c9b3d9e5d470f 100644
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -211,10 +211,11 @@ static int ddebug_change(const struct ddebug_query *query,
+ continue;
+ #ifdef CONFIG_JUMP_LABEL
+ if (dp->flags & _DPRINTK_FLAGS_PRINT) {
+- if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
++ if (!(newflags & _DPRINTK_FLAGS_PRINT))
+ static_branch_disable(&dp->key.dd_key_true);
+- } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
++ } else if (newflags & _DPRINTK_FLAGS_PRINT) {
+ static_branch_enable(&dp->key.dd_key_true);
++ }
+ #endif
+ dp->flags = newflags;
+ v4pr_info("changed %s:%d [%s]%s =%s\n",
+@@ -383,10 +384,6 @@ static int ddebug_parse_query(char *words[], int nwords,
+ return -EINVAL;
+ }
+
+- if (modname)
+- /* support $modname.dyndbg=<multiple queries> */
+- query->module = modname;
+-
+ for (i = 0; i < nwords; i += 2) {
+ char *keyword = words[i];
+ char *arg = words[i+1];
+@@ -427,6 +424,13 @@ static int ddebug_parse_query(char *words[], int nwords,
+ if (rc)
+ return rc;
+ }
++ if (!query->module && modname)
++ /*
++ * support $modname.dyndbg=<multiple queries>, when
++ * not given in the query itself
++ */
++ query->module = modname;
++
+ vpr_info_dq(query, "parsed");
+ return 0;
+ }
+@@ -553,35 +557,6 @@ static int ddebug_exec_queries(char *query, const char *modname)
+ return nfound;
+ }
+
+-/**
+- * dynamic_debug_exec_queries - select and change dynamic-debug prints
+- * @query: query-string described in admin-guide/dynamic-debug-howto
+- * @modname: string containing module name, usually &module.mod_name
+- *
+- * This uses the >/proc/dynamic_debug/control reader, allowing module
+- * authors to modify their dynamic-debug callsites. The modname is
+- * canonically struct module.mod_name, but can also be null or a
+- * module-wildcard, for example: "drm*".
+- */
+-int dynamic_debug_exec_queries(const char *query, const char *modname)
+-{
+- int rc;
+- char *qry; /* writable copy of query */
+-
+- if (!query) {
+- pr_err("non-null query/command string expected\n");
+- return -EINVAL;
+- }
+- qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
+- if (!qry)
+- return -ENOMEM;
+-
+- rc = ddebug_exec_queries(qry, modname);
+- kfree(qry);
+- return rc;
+-}
+-EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
+-
+ #define PREFIX_SIZE 64
+
+ static int remaining(int wrote)
+diff --git a/lib/once.c b/lib/once.c
+index 59149bf3bfb4a..351f66aad310a 100644
+--- a/lib/once.c
++++ b/lib/once.c
+@@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
+ once_disable_jump(once_key, mod);
+ }
+ EXPORT_SYMBOL(__do_once_done);
++
++static DEFINE_MUTEX(once_mutex);
++
++bool __do_once_slow_start(bool *done)
++ __acquires(once_mutex)
++{
++ mutex_lock(&once_mutex);
++ if (*done) {
++ mutex_unlock(&once_mutex);
++ /* Keep sparse happy by restoring an even lock count on
++ * this mutex. In case we return here, we don't call into
++ * __do_once_done but return early in the DO_ONCE_SLOW() macro.
++ */
++ __acquire(once_mutex);
++ return false;
++ }
++
++ return true;
++}
++EXPORT_SYMBOL(__do_once_slow_start);
++
++void __do_once_slow_done(bool *done, struct static_key_true *once_key,
++ struct module *mod)
++ __releases(once_mutex)
++{
++ *done = true;
++ mutex_unlock(&once_mutex);
++ once_disable_jump(once_key, mod);
++}
++EXPORT_SYMBOL(__do_once_slow_done);
+diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
+index 3c7b9d6dca95d..1d16c6c796386 100644
+--- a/mm/damon/vaddr.c
++++ b/mm/damon/vaddr.c
+@@ -304,6 +304,11 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr,
+
+ if (pmd_huge(*pmd)) {
+ ptl = pmd_lock(walk->mm, pmd);
++ if (!pmd_present(*pmd)) {
++ spin_unlock(ptl);
++ return 0;
++ }
++
+ if (pmd_huge(*pmd)) {
+ damon_pmdp_mkold(pmd, walk->mm, addr);
+ spin_unlock(ptl);
+@@ -431,6 +436,11 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ if (pmd_huge(*pmd)) {
+ ptl = pmd_lock(walk->mm, pmd);
++ if (!pmd_present(*pmd)) {
++ spin_unlock(ptl);
++ return 0;
++ }
++
+ if (!pmd_huge(*pmd)) {
+ spin_unlock(ptl);
+ goto regular_page;
+diff --git a/mm/gup.c b/mm/gup.c
+index 00926abb44263..251cb6a10bc0d 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -530,6 +530,18 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ (FOLL_PIN | FOLL_GET)))
+ return ERR_PTR(-EINVAL);
++
++ /*
++ * Considering PTE level hugetlb, like continuous-PTE hugetlb on
++ * ARM64 architecture.
++ */
++ if (is_vm_hugetlb_page(vma)) {
++ page = follow_huge_pmd_pte(vma, address, flags);
++ if (page)
++ return page;
++ return no_page_table(vma, flags);
++ }
++
+ retry:
+ if (unlikely(pmd_bad(*pmd)))
+ return no_page_table(vma, flags);
+@@ -662,7 +674,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
+ if (pmd_none(pmdval))
+ return no_page_table(vma, flags);
+ if (pmd_huge(pmdval) && is_vm_hugetlb_page(vma)) {
+- page = follow_huge_pmd(mm, address, pmd, flags);
++ page = follow_huge_pmd_pte(vma, address, flags);
+ if (page)
+ return page;
+ return no_page_table(vma, flags);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 0bdfc7e1c933f..513b523ba75b3 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5059,6 +5059,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ * unmapped and its refcount is dropped, so just clear pte here.
+ */
+ if (unlikely(!pte_present(pte))) {
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ /*
+ * If the pte was wr-protected by uffd-wp in any of the
+ * swap forms, meanwhile the caller does not want to
+@@ -5070,6 +5071,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ set_huge_pte_at(mm, address, ptep,
+ make_pte_marker(PTE_MARKER_UFFD_WP));
+ else
++#endif
+ huge_pte_clear(mm, address, ptep, sz);
+ spin_unlock(ptl);
+ continue;
+@@ -5098,11 +5100,13 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ tlb_remove_huge_tlb_entry(h, tlb, ptep, address);
+ if (huge_pte_dirty(pte))
+ set_page_dirty(page);
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ /* Leave a uffd-wp pte marker if needed */
+ if (huge_pte_uffd_wp(pte) &&
+ !(zap_flags & ZAP_FLAG_DROP_MARKER))
+ set_huge_pte_at(mm, address, ptep,
+ make_pte_marker(PTE_MARKER_UFFD_WP));
++#endif
+ hugetlb_count_sub(pages_per_huge_page(h), mm);
+ page_remove_rmap(page, vma, true);
+
+@@ -5478,7 +5482,6 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long reason)
+ {
+- vm_fault_t ret;
+ u32 hash;
+ struct vm_fault vmf = {
+ .vma = vma,
+@@ -5496,18 +5499,14 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma,
+ };
+
+ /*
+- * hugetlb_fault_mutex and i_mmap_rwsem must be
+- * dropped before handling userfault. Reacquire
+- * after handling fault to make calling code simpler.
++ * vma_lock and hugetlb_fault_mutex must be dropped before handling
++ * userfault. Also mmap_lock will be dropped during handling
++ * userfault, any vma operation should be careful from here.
+ */
+ hash = hugetlb_fault_mutex_hash(mapping, idx);
+ mutex_unlock(&hugetlb_fault_mutex_table[hash]);
+ i_mmap_unlock_read(mapping);
+- ret = handle_userfault(&vmf, reason);
+- i_mmap_lock_read(mapping);
+- mutex_lock(&hugetlb_fault_mutex_table[hash]);
+-
+- return ret;
++ return handle_userfault(&vmf, reason);
+ }
+
+ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+@@ -5525,6 +5524,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+ spinlock_t *ptl;
+ unsigned long haddr = address & huge_page_mask(h);
+ bool new_page, new_pagecache_page = false;
++ u32 hash = hugetlb_fault_mutex_hash(mapping, idx);
+
+ /*
+ * Currently, we are forced to kill the process in the event the
+@@ -5535,7 +5535,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+ if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) {
+ pr_warn_ratelimited("PID %d killed due to inadequate hugepage pool\n",
+ current->pid);
+- return ret;
++ goto out;
+ }
+
+ /*
+@@ -5552,12 +5552,10 @@ retry:
+ page = find_lock_page(mapping, idx);
+ if (!page) {
+ /* Check for page in userfault range */
+- if (userfaultfd_missing(vma)) {
+- ret = hugetlb_handle_userfault(vma, mapping, idx,
++ if (userfaultfd_missing(vma))
++ return hugetlb_handle_userfault(vma, mapping, idx,
+ flags, haddr, address,
+ VM_UFFD_MISSING);
+- goto out;
+- }
+
+ page = alloc_huge_page(vma, haddr, 0);
+ if (IS_ERR(page)) {
+@@ -5617,10 +5615,9 @@ retry:
+ if (userfaultfd_minor(vma)) {
+ unlock_page(page);
+ put_page(page);
+- ret = hugetlb_handle_userfault(vma, mapping, idx,
++ return hugetlb_handle_userfault(vma, mapping, idx,
+ flags, haddr, address,
+ VM_UFFD_MINOR);
+- goto out;
+ }
+ }
+
+@@ -5678,6 +5675,8 @@ retry:
+
+ unlock_page(page);
+ out:
++ mutex_unlock(&hugetlb_fault_mutex_table[hash]);
++ i_mmap_unlock_read(mapping);
+ return ret;
+
+ backout:
+@@ -5776,11 +5775,13 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+
+ entry = huge_ptep_get(ptep);
+ /* PTE markers should be handled the same way as none pte */
+- if (huge_pte_none_mostly(entry)) {
+- ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep,
++ if (huge_pte_none_mostly(entry))
++ /*
++ * hugetlb_no_page will drop vma lock and hugetlb fault
++ * mutex internally, which make us return immediately.
++ */
++ return hugetlb_no_page(mm, vma, mapping, idx, address, ptep,
+ entry, flags);
+- goto out_mutex;
+- }
+
+ ret = 0;
+
+@@ -6946,12 +6947,13 @@ follow_huge_pd(struct vm_area_struct *vma,
+ }
+
+ struct page * __weak
+-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+- pmd_t *pmd, int flags)
++follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address, int flags)
+ {
++ struct hstate *h = hstate_vma(vma);
++ struct mm_struct *mm = vma->vm_mm;
+ struct page *page = NULL;
+ spinlock_t *ptl;
+- pte_t pte;
++ pte_t *ptep, pte;
+
+ /*
+ * FOLL_PIN is not supported for follow_page(). Ordinary GUP goes via
+@@ -6961,17 +6963,15 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ return NULL;
+
+ retry:
+- ptl = pmd_lockptr(mm, pmd);
+- spin_lock(ptl);
+- /*
+- * make sure that the address range covered by this pmd is not
+- * unmapped from other threads.
+- */
+- if (!pmd_huge(*pmd))
+- goto out;
+- pte = huge_ptep_get((pte_t *)pmd);
++ ptep = huge_pte_offset(mm, address, huge_page_size(h));
++ if (!ptep)
++ return NULL;
++
++ ptl = huge_pte_lock(h, mm, ptep);
++ pte = huge_ptep_get(ptep);
+ if (pte_present(pte)) {
+- page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
++ page = pte_page(pte) +
++ ((address & ~huge_page_mask(h)) >> PAGE_SHIFT);
+ /*
+ * try_grab_page() should always succeed here, because: a) we
+ * hold the pmd (ptl) lock, and b) we've just checked that the
+@@ -6987,7 +6987,7 @@ retry:
+ } else {
+ if (is_hugetlb_entry_migration(pte)) {
+ spin_unlock(ptl);
+- __migration_entry_wait_huge((pte_t *)pmd, ptl);
++ __migration_entry_wait_huge(ptep, ptl);
+ goto retry;
+ }
+ /*
+diff --git a/mm/memory.c b/mm/memory.c
+index a78814413ac03..de0dbe09b013f 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1393,10 +1393,12 @@ zap_install_uffd_wp_if_needed(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *pte,
+ struct zap_details *details, pte_t pteval)
+ {
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ if (zap_drop_file_uffd_wp(details))
+ return;
+
+ pte_install_uffd_wp_if_needed(vma, addr, pte, pteval);
++#endif
+ }
+
+ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 9d780f415be3c..36c08e2c78da7 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1797,7 +1797,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+ if (!arch_validate_flags(vma->vm_flags)) {
+ error = -EINVAL;
+ if (file)
+- goto unmap_and_free_vma;
++ goto close_and_free_vma;
+ else
+ goto free_vma;
+ }
+@@ -1844,6 +1844,9 @@ out:
+
+ return addr;
+
++close_and_free_vma:
++ if (vma->vm_ops && vma->vm_ops->close)
++ vma->vm_ops->close(vma);
+ unmap_and_free_vma:
+ fput(vma->vm_file);
+ vma->vm_file = NULL;
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index bc6bddd156ca6..51e7dbd26b6ad 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -260,6 +260,7 @@ static unsigned long change_pte_range(struct mmu_gather *tlb,
+ } else {
+ /* It must be an none page, or what else?.. */
+ WARN_ON_ONCE(!pte_none(oldpte));
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ if (unlikely(uffd_wp && !vma_is_anonymous(vma))) {
+ /*
+ * For file-backed mem, we need to be able to
+@@ -271,6 +272,7 @@ static unsigned long change_pte_range(struct mmu_gather *tlb,
+ make_pte_marker(PTE_MARKER_UFFD_WP));
+ pages++;
+ }
++#endif
+ }
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 9873d2e679885..6ae5aa5c0927b 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2400,6 +2400,10 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
+ container_of(nb, struct hci_dev, suspend_notifier);
+ int ret = 0;
+
++ /* Userspace has full control of this device. Do nothing. */
++ if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
++ return NOTIFY_DONE;
++
+ if (action == PM_SUSPEND_PREPARE)
+ ret = hci_suspend_dev(hdev);
+ else if (action == PM_POST_SUSPEND)
+@@ -3478,15 +3482,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
+ return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
+ }
+
+-static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
++static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
+ {
+- if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+- /* ACL tx timeout must be longer than maximum
+- * link supervision timeout (40.9 seconds) */
+- if (!cnt && time_after(jiffies, hdev->acl_last_tx +
+- HCI_ACL_TX_TIMEOUT))
+- hci_link_tx_to(hdev, ACL_LINK);
++ unsigned long last_tx;
++
++ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
++ return;
++
++ switch (type) {
++ case LE_LINK:
++ last_tx = hdev->le_last_tx;
++ break;
++ default:
++ last_tx = hdev->acl_last_tx;
++ break;
+ }
++
++ /* tx timeout must be longer than maximum link supervision timeout
++ * (40.9 seconds)
++ */
++ if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
++ hci_link_tx_to(hdev, type);
+ }
+
+ /* Schedule SCO */
+@@ -3544,7 +3560,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+ struct sk_buff *skb;
+ int quote;
+
+- __check_timeout(hdev, cnt);
++ __check_timeout(hdev, cnt, ACL_LINK);
+
+ while (hdev->acl_cnt &&
+ (chan = hci_chan_sent(hdev, ACL_LINK, "e))) {
+@@ -3587,8 +3603,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+ int quote;
+ u8 type;
+
+- __check_timeout(hdev, cnt);
+-
+ BT_DBG("%s", hdev->name);
+
+ if (hdev->dev_type == HCI_AMP)
+@@ -3596,6 +3610,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+ else
+ type = ACL_LINK;
+
++ __check_timeout(hdev, cnt, type);
++
+ while (hdev->block_cnt > 0 &&
+ (chan = hci_chan_sent(hdev, type, "e))) {
+ u32 priority = (skb_peek(&chan->data_q))->priority;
+@@ -3669,7 +3685,7 @@ static void hci_sched_le(struct hci_dev *hdev)
+
+ cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
+
+- __check_timeout(hdev, cnt);
++ __check_timeout(hdev, cnt, LE_LINK);
+
+ tmp = cnt;
+ while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) {
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index d6f0e6ca0e7e0..ab79a978deb5b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6778,6 +6778,13 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ goto unlock;
+ }
+
++ if (conn->type != ISO_LINK) {
++ bt_dev_err(hdev,
++ "Invalid connection link type handle 0x%4.4x",
++ handle);
++ goto unlock;
++ }
++
+ if (conn->role == HCI_ROLE_SLAVE) {
+ __le32 interval;
+
+@@ -6898,6 +6905,13 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
+ if (!conn)
+ goto unlock;
+
++ if (conn->type != ISO_LINK) {
++ bt_dev_err(hdev,
++ "Invalid connection link type handle 0x%2.2x",
++ ev->handle);
++ goto unlock;
++ }
++
+ if (ev->num_bis)
+ conn->handle = __le16_to_cpu(ev->bis_handle[0]);
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 0d015d4a8e414..bd8358b44aa4c 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -887,7 +887,6 @@ static int hci_sock_release(struct socket *sock)
+ */
+ hci_dev_do_close(hdev);
+ hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+- hci_register_suspend_notifier(hdev);
+ mgmt_index_added(hdev);
+ }
+
+@@ -1216,7 +1215,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+ }
+
+ mgmt_index_removed(hdev);
+- hci_unregister_suspend_notifier(hdev);
+
+ err = hci_dev_open(hdev->id);
+ if (err) {
+@@ -1231,7 +1229,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+ err = 0;
+ } else {
+ hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+- hci_register_suspend_notifier(hdev);
+ mgmt_index_added(hdev);
+ hci_dev_put(hdev);
+ goto done;
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index fbd5613eebfc2..f70798589bf51 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -4355,6 +4355,7 @@ int hci_dev_open_sync(struct hci_dev *hdev)
+ hci_dev_test_flag(hdev, HCI_MGMT) &&
+ hdev->dev_type == HCI_PRIMARY) {
+ ret = hci_powered_update_sync(hdev);
++ mgmt_power_on(hdev, ret);
+ }
+ } else {
+ /* Init failed, cleanup */
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
+index 4e3e0451b08c1..08542dfc2dc53 100644
+--- a/net/bluetooth/hci_sysfs.c
++++ b/net/bluetooth/hci_sysfs.c
+@@ -48,6 +48,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
+
+ BT_DBG("conn %p", conn);
+
++ if (device_is_registered(&conn->dev))
++ return;
++
+ dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
+
+ if (device_add(&conn->dev) < 0) {
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 2c9de67daadcf..1f34b82ca0ec9 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -61,6 +61,9 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
+
+ static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ struct sk_buff_head *skbs, u8 event);
++static void l2cap_retrans_timeout(struct work_struct *work);
++static void l2cap_monitor_timeout(struct work_struct *work);
++static void l2cap_ack_timeout(struct work_struct *work);
+
+ static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type)
+ {
+@@ -476,6 +479,9 @@ struct l2cap_chan *l2cap_chan_create(void)
+ write_unlock(&chan_list_lock);
+
+ INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
++ INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
++ INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
++ INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
+
+ chan->state = BT_OPEN;
+
+@@ -3320,10 +3326,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
+ chan->rx_state = L2CAP_RX_STATE_RECV;
+ chan->tx_state = L2CAP_TX_STATE_XMIT;
+
+- INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
+- INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
+- INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
+-
+ skb_queue_head_init(&chan->srej_q);
+
+ err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
+@@ -4307,6 +4309,12 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
+ }
+ }
+
++ chan = l2cap_chan_hold_unless_zero(chan);
++ if (!chan) {
++ err = -EBADSLT;
++ goto unlock;
++ }
++
+ err = 0;
+
+ l2cap_chan_lock(chan);
+@@ -4336,6 +4344,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
+ }
+
+ l2cap_chan_unlock(chan);
++ l2cap_chan_put(chan);
+
+ unlock:
+ mutex_unlock(&conn->chan_lock);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 72e6595a71cc0..3d1cd06669688 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1050,7 +1050,7 @@ static void discov_off(struct work_struct *work)
+
+ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
+ {
+- if (hci_dev_test_and_set_flag(hdev, HCI_MGMT))
++ if (hci_dev_test_flag(hdev, HCI_MGMT))
+ return;
+
+ BT_INFO("MGMT ver %d.%d", MGMT_VERSION, MGMT_REVISION);
+@@ -1065,6 +1065,8 @@ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
+ * it
+ */
+ hci_dev_clear_flag(hdev, HCI_BONDABLE);
++
++ hci_dev_set_flag(hdev, HCI_MGMT);
+ }
+
+ static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index 4bf4ea6cbb5ee..21e24da4847f0 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -902,7 +902,10 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
+ lock_sock(sk);
+ if (!sk->sk_shutdown) {
+ sk->sk_shutdown = SHUTDOWN_MASK;
++
++ release_sock(sk);
+ __rfcomm_sock_close(sk);
++ lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+ !(current->flags & PF_EXITING))
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index e60161bec850a..f16271a7ae2e8 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -274,6 +274,7 @@ static void bcm_can_tx(struct bcm_op *op)
+ struct sk_buff *skb;
+ struct net_device *dev;
+ struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe;
++ int err;
+
+ /* no target device? => exit */
+ if (!op->ifindex)
+@@ -298,11 +299,11 @@ static void bcm_can_tx(struct bcm_op *op)
+ /* send with loopback */
+ skb->dev = dev;
+ can_skb_set_owner(skb, op->sk);
+- can_send(skb, 1);
++ err = can_send(skb, 1);
++ if (!err)
++ op->frames_abs++;
+
+- /* update statistics */
+ op->currframe++;
+- op->frames_abs++;
+
+ /* reached last frame? */
+ if (op->currframe >= op->nframes)
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 5dc3860e9fc7e..7105529abb0f6 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -1173,8 +1173,8 @@ proto_again:
+ nhoff += sizeof(*vlan);
+ }
+
+- if (dissector_uses_key(flow_dissector,
+- FLOW_DISSECTOR_KEY_NUM_OF_VLANS)) {
++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_NUM_OF_VLANS) &&
++ !(key_control->flags & FLOW_DIS_ENCAPSULATION)) {
+ struct flow_dissector_key_num_of_vlans *key_nvs;
+
+ key_nvs = skb_flow_dissector_target(flow_dissector,
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 188f8558d27d1..ca70525621c71 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -434,8 +434,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ if (copied + copy > len)
+ copy = len - copied;
+ copy = copy_page_to_iter(page, sge->offset, copy, iter);
+- if (!copy)
+- return copied ? copied : -EFAULT;
++ if (!copy) {
++ copied = copied ? copied : -EFAULT;
++ goto out;
++ }
+
+ copied += copy;
+ if (likely(!peek)) {
+@@ -455,7 +457,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ * didn't copy the entire length lets just break.
+ */
+ if (copy != sge->length)
+- return copied;
++ goto out;
+ sk_msg_iter_var_next(i);
+ }
+
+@@ -477,7 +479,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ }
+ msg_rx = sk_psock_peek_msg(psock);
+ }
+-
++out:
++ if (psock->work_state.skb && copied > 0)
++ schedule_work(&psock->work);
+ return copied;
+ }
+ EXPORT_SYMBOL_GPL(sk_msg_recvmsg);
+diff --git a/net/core/stream.c b/net/core/stream.c
+index ccc083cdef232..1105057ce00a5 100644
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -159,7 +159,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
+ *timeo_p = current_timeo;
+ }
+ out:
+- remove_wait_queue(sk_sleep(sk), &wait);
++ if (!sock_flag(sk, SOCK_DEAD))
++ remove_wait_queue(sk_sleep(sk), &wait);
+ return err;
+
+ do_error:
+diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
+index 7889e1ef7fad6..6e55fae4c6860 100644
+--- a/net/ieee802154/socket.c
++++ b/net/ieee802154/socket.c
+@@ -272,6 +272,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
+ err = -EMSGSIZE;
+ goto out_dev;
+ }
++ if (!size) {
++ err = 0;
++ goto out_dev;
++ }
+
+ hlen = LL_RESERVED_SPACE(dev);
+ tlen = dev->needed_tailroom;
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index ffd57523331fd..405a8c2aea641 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -42,6 +42,8 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
+ oif = inet->mc_index;
+ if (!saddr)
+ saddr = inet->mc_addr;
++ } else if (!oif) {
++ oif = inet->uc_index;
+ }
+ fl4 = &inet->cork.fl.u.ip4;
+ rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr, oif,
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index 935026f4c807e..170152772d332 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -110,7 +110,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
+ struct sk_buff *skb,
+ netdev_features_t features)
+ {
+- return skb_eth_gso_segment(skb, features, htons(ETH_P_IP));
++ __be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6)
++ : htons(ETH_P_IP);
++
++ return skb_eth_gso_segment(skb, features, type);
+ }
+
+ static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index b9d995b5ce24c..f5950a7172d61 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -729,8 +729,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ if (likely(remaining > 1))
+ remaining &= ~1U;
+
+- net_get_random_once(table_perturb,
+- INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
++ get_random_slow_once(table_perturb,
++ INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
+ index = port_offset & (INET_TABLE_PERTURB_SIZE - 1);
+
+ offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32);
+diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c
+index b75cac69bd7e6..7ade04ff972d7 100644
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -83,6 +83,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ else
+ oif = NULL;
+
++ if (priv->flags & NFTA_FIB_F_IIF)
++ fl4.flowi4_oif = l3mdev_master_ifindex_rcu(oif);
++
+ if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
+ nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
+ nft_fib_store_result(dest, priv, nft_in(pkt));
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index e373dde1f46f7..5f1d84d901c71 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3137,6 +3137,8 @@ int tcp_disconnect(struct sock *sk, int flags)
+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+ tcp_snd_cwnd_set(tp, TCP_INIT_CWND);
+ tp->snd_cwnd_cnt = 0;
++ tp->is_cwnd_limited = 0;
++ tp->max_packets_out = 0;
+ tp->window_clamp = 0;
+ tp->delivered = 0;
+ tp->delivered_ce = 0;
+@@ -4442,12 +4444,16 @@ static void __tcp_alloc_md5sig_pool(void)
+ * to memory. See smp_rmb() in tcp_get_md5sig_pool()
+ */
+ smp_wmb();
+- tcp_md5sig_pool_populated = true;
++ /* Paired with READ_ONCE() from tcp_alloc_md5sig_pool()
++ * and tcp_get_md5sig_pool().
++ */
++ WRITE_ONCE(tcp_md5sig_pool_populated, true);
+ }
+
+ bool tcp_alloc_md5sig_pool(void)
+ {
+- if (unlikely(!tcp_md5sig_pool_populated)) {
++ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++ if (unlikely(!READ_ONCE(tcp_md5sig_pool_populated))) {
+ mutex_lock(&tcp_md5sig_mutex);
+
+ if (!tcp_md5sig_pool_populated) {
+@@ -4458,7 +4464,8 @@ bool tcp_alloc_md5sig_pool(void)
+
+ mutex_unlock(&tcp_md5sig_mutex);
+ }
+- return tcp_md5sig_pool_populated;
++ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++ return READ_ONCE(tcp_md5sig_pool_populated);
+ }
+ EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
+
+@@ -4474,7 +4481,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
+ {
+ local_bh_disable();
+
+- if (tcp_md5sig_pool_populated) {
++ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++ if (READ_ONCE(tcp_md5sig_pool_populated)) {
+ /* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */
+ smp_rmb();
+ return this_cpu_ptr(&tcp_md5sig_pool);
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 290019de766dc..c69f4d966024c 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1875,15 +1875,20 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)
+ const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
+ struct tcp_sock *tp = tcp_sk(sk);
+
+- /* Track the maximum number of outstanding packets in each
+- * window, and remember whether we were cwnd-limited then.
++ /* Track the strongest available signal of the degree to which the cwnd
++ * is fully utilized. If cwnd-limited then remember that fact for the
++ * current window. If not cwnd-limited then track the maximum number of
++ * outstanding packets in the current window. (If cwnd-limited then we
++ * chose to not update tp->max_packets_out to avoid an extra else
++ * clause with no functional impact.)
+ */
+- if (!before(tp->snd_una, tp->max_packets_seq) ||
+- tp->packets_out > tp->max_packets_out ||
+- is_cwnd_limited) {
+- tp->max_packets_out = tp->packets_out;
+- tp->max_packets_seq = tp->snd_nxt;
++ if (!before(tp->snd_una, tp->cwnd_usage_seq) ||
++ is_cwnd_limited ||
++ (!tp->is_cwnd_limited &&
++ tp->packets_out > tp->max_packets_out)) {
+ tp->is_cwnd_limited = is_cwnd_limited;
++ tp->max_packets_out = tp->packets_out;
++ tp->cwnd_usage_seq = tp->snd_nxt;
+ }
+
+ if (tcp_is_cwnd_limited(sk)) {
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 3a293838a91db..79d43548279cb 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -145,7 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
+ struct sk_buff *skb,
+ netdev_features_t features)
+ {
+- return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6));
++ __be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP)
++ : htons(ETH_P_IPV6);
++
++ return skb_eth_gso_segment(skb, features, type);
+ }
+
+ static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index 8970d0b4faeb4..1d7e520d9966c 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -41,6 +41,9 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
+ if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
+ lookup_flags |= RT6_LOOKUP_F_IFACE;
+ fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
++ } else if ((priv->flags & NFTA_FIB_F_IIF) &&
++ (netif_is_l3_master(dev) || netif_is_l3_slave(dev))) {
++ fl6->flowi6_oif = dev->ifindex;
+ }
+
+ if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
+@@ -197,7 +200,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL))
+ goto put_rt_err;
+
+- if (oif && oif != rt->rt6i_idev->dev)
++ if (oif && oif != rt->rt6i_idev->dev &&
++ l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex)
+ goto put_rt_err;
+
+ nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index a4f6971b7a190..65f34945a7678 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1610,6 +1610,18 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
+ rcu_dereference_protected(sta->link[link_id],
+ lockdep_is_held(&local->sta_mtx));
+
++ /*
++ * If there are no changes, then accept a link that doesn't exist,
++ * unless it's a new link.
++ */
++ if (params->link_id < 0 && !new_link &&
++ !params->link_mac && !params->txpwr_set &&
++ !params->supported_rates_len &&
++ !params->ht_capa && !params->vht_capa &&
++ !params->he_capa && !params->eht_capa &&
++ !params->opmode_notif_used)
++ return 0;
++
+ if (!link || !link_sta)
+ return -EINVAL;
+
+@@ -1625,6 +1637,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
+ params->link_mac)) {
+ return -EINVAL;
+ }
++ } else if (new_link) {
++ return -EINVAL;
+ }
+
+ if (params->txpwr_set) {
+@@ -3597,9 +3611,6 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ case NL80211_IFTYPE_MESH_POINT: {
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+
+- if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
+- return -EINVAL;
+-
+ /* changes into another band are not supported */
+ if (sdata->vif.bss_conf.chandef.chan->band !=
+ params->chandef.chan->band)
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index fc764984d687f..654414caeb71e 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1220,14 +1220,21 @@ static void ieee80211_assoc_add_ml_elem(struct ieee80211_sub_if_data *sdata,
+ ml_elem = skb_put(skb, sizeof(*ml_elem));
+ ml_elem->control =
+ cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC |
+- IEEE80211_MLC_BASIC_PRES_EML_CAPA |
+ IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP);
+ common = skb_put(skb, sizeof(*common));
+ common->len = sizeof(*common) +
+- 2 + /* EML capabilities */
+ 2; /* MLD capa/ops */
+ memcpy(common->mld_mac_addr, sdata->vif.addr, ETH_ALEN);
+- skb_put_data(skb, &eml_capa, sizeof(eml_capa));
++
++ /* add EML_CAPA only if needed, see Draft P802.11be_D2.1, 35.3.17 */
++ if (eml_capa &
++ cpu_to_le16((IEEE80211_EML_CAP_EMLSR_SUPP |
++ IEEE80211_EML_CAP_EMLMR_SUPPORT))) {
++ common->len += 2; /* EML capabilities */
++ ml_elem->control |=
++ cpu_to_le16(IEEE80211_MLC_BASIC_PRES_EML_CAPA);
++ skb_put_data(skb, &eml_capa, sizeof(eml_capa));
++ }
+ /* need indication from userspace to support this */
+ mld_capa_ops &= ~cpu_to_le16(IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP);
+ skb_put_data(skb, &mld_capa_ops, sizeof(mld_capa_ops));
+@@ -5122,7 +5129,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ resp.req_ies = ifmgd->assoc_req_ies;
+ resp.req_ies_len = ifmgd->assoc_req_ies_len;
+ if (sdata->vif.valid_links)
+- resp.ap_mld_addr = assoc_data->ap_addr;
++ resp.ap_mld_addr = sdata->vif.cfg.ap_addr;
+ cfg80211_rx_assoc_resp(sdata->dev, &resp);
+ notify_driver:
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
+@@ -6284,6 +6291,8 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)
+ if (sdata->u.mgd.assoc_data)
+ ether_addr_copy(link->conf->addr,
+ sdata->u.mgd.assoc_data->link[link_id].addr);
++ else if (!is_valid_ether_addr(link->conf->addr))
++ eth_random_addr(link->conf->addr);
+ }
+
+ /* scan finished notification */
+@@ -6371,9 +6380,6 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
+ goto out_err;
+ }
+
+- if (mlo && !is_valid_ether_addr(link->conf->addr))
+- eth_random_addr(link->conf->addr);
+-
+ if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) {
+ err = -EINVAL;
+ goto out_err;
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 58998d8217784..9d7b238a67372 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2799,6 +2799,7 @@ hash:
+ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
+ {
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
++ u16 old_links = sta->sta.valid_links;
+
+ lockdep_assert_held(&sdata->local->sta_mtx);
+
+@@ -2806,8 +2807,7 @@ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
+
+ if (test_sta_flag(sta, WLAN_STA_INSERTED))
+ drv_change_sta_links(sdata->local, sdata, &sta->sta,
+- sta->sta.valid_links,
+- sta->sta.valid_links & ~BIT(link_id));
++ old_links, sta->sta.valid_links);
+
+ sta_remove_link(sta, link_id, true);
+ }
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 1357a2729a4ba..8f261cd5b3a50 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -67,6 +67,7 @@ struct conntrack_gc_work {
+ struct delayed_work dwork;
+ u32 next_bucket;
+ u32 avg_timeout;
++ u32 count;
+ u32 start_time;
+ bool exiting;
+ bool early_drop;
+@@ -85,10 +86,12 @@ static DEFINE_MUTEX(nf_conntrack_mutex);
+ /* clamp timeouts to this value (TCP unacked) */
+ #define GC_SCAN_INTERVAL_CLAMP (300ul * HZ)
+
+-/* large initial bias so that we don't scan often just because we have
+- * three entries with a 1s timeout.
++/* Initial bias pretending we have 100 entries at the upper bound so we don't
++ * wakeup often just because we have three entries with a 1s timeout while still
++ * allowing non-idle machines to wakeup more often when needed.
+ */
+-#define GC_SCAN_INTERVAL_INIT INT_MAX
++#define GC_SCAN_INITIAL_COUNT 100
++#define GC_SCAN_INTERVAL_INIT GC_SCAN_INTERVAL_MAX
+
+ #define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)
+ #define GC_SCAN_EXPIRED_MAX (64000u / HZ)
+@@ -1466,6 +1469,7 @@ static void gc_worker(struct work_struct *work)
+ unsigned int expired_count = 0;
+ unsigned long next_run;
+ s32 delta_time;
++ long count;
+
+ gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
+
+@@ -1475,10 +1479,12 @@ static void gc_worker(struct work_struct *work)
+
+ if (i == 0) {
+ gc_work->avg_timeout = GC_SCAN_INTERVAL_INIT;
++ gc_work->count = GC_SCAN_INITIAL_COUNT;
+ gc_work->start_time = start_time;
+ }
+
+ next_run = gc_work->avg_timeout;
++ count = gc_work->count;
+
+ end_time = start_time + GC_SCAN_MAX_DURATION;
+
+@@ -1498,8 +1504,8 @@ static void gc_worker(struct work_struct *work)
+
+ hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) {
+ struct nf_conntrack_net *cnet;
+- unsigned long expires;
+ struct net *net;
++ long expires;
+
+ tmp = nf_ct_tuplehash_to_ctrack(h);
+
+@@ -1513,6 +1519,7 @@ static void gc_worker(struct work_struct *work)
+
+ gc_work->next_bucket = i;
+ gc_work->avg_timeout = next_run;
++ gc_work->count = count;
+
+ delta_time = nfct_time_stamp - gc_work->start_time;
+
+@@ -1528,8 +1535,8 @@ static void gc_worker(struct work_struct *work)
+ }
+
+ expires = clamp(nf_ct_expires(tmp), GC_SCAN_INTERVAL_MIN, GC_SCAN_INTERVAL_CLAMP);
++ expires = (expires - (long)next_run) / ++count;
+ next_run += expires;
+- next_run /= 2u;
+
+ if (nf_conntrack_max95 == 0 || gc_worker_skip_ct(tmp))
+ continue;
+@@ -1570,6 +1577,7 @@ static void gc_worker(struct work_struct *work)
+ delta_time = nfct_time_stamp - end_time;
+ if (delta_time > 0 && i < hashsz) {
+ gc_work->avg_timeout = next_run;
++ gc_work->count = count;
+ gc_work->next_bucket = i;
+ next_run = 0;
+ goto early_exit;
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 6c9d153afbeee..93c596e3b22b9 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -252,10 +252,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
+
+ upcall.mru = OVS_CB(skb)->mru;
+ error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
+- if (unlikely(error))
+- kfree_skb(skb);
+- else
++ switch (error) {
++ case 0:
++ case -EAGAIN:
++ case -ERESTARTSYS:
++ case -EINTR:
+ consume_skb(skb);
++ break;
++ default:
++ kfree_skb(skb);
++ break;
++ }
+ stats_counter = &stats->n_missed;
+ goto out;
+ }
+@@ -551,8 +558,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
+ out:
+ if (err)
+ skb_tx_error(skb);
+- kfree_skb(user_skb);
+- kfree_skb(nskb);
++ consume_skb(user_skb);
++ consume_skb(nskb);
++
+ return err;
+ }
+
+diff --git a/net/rds/tcp.c b/net/rds/tcp.c
+index 73ee2771093d6..d0ff413f697c3 100644
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -166,10 +166,10 @@ void rds_tcp_reset_callbacks(struct socket *sock,
+ */
+ atomic_set(&cp->cp_state, RDS_CONN_RESETTING);
+ wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags));
+- lock_sock(osock->sk);
+ /* reset receive side state for rds_tcp_data_recv() for osock */
+ cancel_delayed_work_sync(&cp->cp_send_w);
+ cancel_delayed_work_sync(&cp->cp_recv_w);
++ lock_sock(osock->sk);
+ if (tc->t_tinc) {
+ rds_inc_put(&tc->t_tinc->ti_inc);
+ tc->t_tinc = NULL;
+diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
+index 4d27300c287c4..5f33472aad360 100644
+--- a/net/sched/cls_u32.c
++++ b/net/sched/cls_u32.c
+@@ -1040,7 +1040,11 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
+ }
+ #endif
+
+- memcpy(&n->sel, s, sel_size);
++ unsafe_memcpy(&n->sel, s, sel_size,
++ /* A composite flex-array structure destination,
++ * which was correctly sized with struct_size(),
++ * bounds-checked against nla_len(), and allocated
++ * above. */);
+ RCU_INIT_POINTER(n->ht_up, ht);
+ n->handle = handle;
+ n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
+diff --git a/net/sctp/auth.c b/net/sctp/auth.c
+index db6b7373d16c3..34964145514e6 100644
+--- a/net/sctp/auth.c
++++ b/net/sctp/auth.c
+@@ -863,12 +863,17 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
+ }
+
+ list_del_init(&shkey->key_list);
+- sctp_auth_shkey_release(shkey);
+ list_add(&cur_key->key_list, sh_keys);
+
+- if (asoc && asoc->active_key_id == auth_key->sca_keynumber)
+- sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
++ if (asoc && asoc->active_key_id == auth_key->sca_keynumber &&
++ sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
++ list_del_init(&cur_key->key_list);
++ sctp_auth_shkey_release(cur_key);
++ list_add(&shkey->key_list, sh_keys);
++ return -ENOMEM;
++ }
+
++ sctp_auth_shkey_release(shkey);
+ return 0;
+ }
+
+@@ -902,8 +907,13 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+ return -EINVAL;
+
+ if (asoc) {
++ __u16 active_key_id = asoc->active_key_id;
++
+ asoc->active_key_id = key_id;
+- sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
++ if (sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
++ asoc->active_key_id = active_key_id;
++ return -ENOMEM;
++ }
+ } else
+ ep->active_key_id = key_id;
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index bf338b782fc4c..d686804119c99 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -569,12 +569,6 @@ static void unix_sock_destructor(struct sock *sk)
+
+ skb_queue_purge(&sk->sk_receive_queue);
+
+-#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+- if (u->oob_skb) {
+- kfree_skb(u->oob_skb);
+- u->oob_skb = NULL;
+- }
+-#endif
+ DEBUG_NET_WARN_ON_ONCE(refcount_read(&sk->sk_wmem_alloc));
+ DEBUG_NET_WARN_ON_ONCE(!sk_unhashed(sk));
+ DEBUG_NET_WARN_ON_ONCE(sk->sk_socket);
+@@ -620,6 +614,13 @@ static void unix_release_sock(struct sock *sk, int embrion)
+
+ unix_state_unlock(sk);
+
++#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
++ if (u->oob_skb) {
++ kfree_skb(u->oob_skb);
++ u->oob_skb = NULL;
++ }
++#endif
++
+ wake_up_interruptible_all(&u->peer_wait);
+
+ if (skpair != NULL) {
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index d45d5366115a7..dc27635403932 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -204,6 +204,7 @@ void wait_for_unix_gc(void)
+ /* The external entry point: unix_gc() */
+ void unix_gc(void)
+ {
++ struct sk_buff *next_skb, *skb;
+ struct unix_sock *u;
+ struct unix_sock *next;
+ struct sk_buff_head hitlist;
+@@ -297,11 +298,30 @@ void unix_gc(void)
+
+ spin_unlock(&unix_gc_lock);
+
++ /* We need io_uring to clean its registered files, ignore all io_uring
++ * originated skbs. It's fine as io_uring doesn't keep references to
++ * other io_uring instances and so killing all other files in the cycle
++ * will put all io_uring references forcing it to go through normal
++ * release.path eventually putting registered files.
++ */
++ skb_queue_walk_safe(&hitlist, skb, next_skb) {
++ if (skb->scm_io_uring) {
++ __skb_unlink(skb, &hitlist);
++ skb_queue_tail(&skb->sk->sk_receive_queue, skb);
++ }
++ }
++
+ /* Here we are. Hitlist is filled. Die. */
+ __skb_queue_purge(&hitlist);
+
+ spin_lock(&unix_gc_lock);
+
++ /* There could be io_uring registered files, just push them back to
++ * the inflight list
++ */
++ list_for_each_entry_safe(u, next, &gc_candidates, link)
++ list_move_tail(&u->link, &gc_inflight_list);
++
+ /* All candidates should have been detached by now. */
+ BUG_ON(!list_empty(&gc_candidates));
+
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index ec2c2afbf0d06..3a12aee33e92f 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);
+
+ void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt)
+ {
+- kfree(pkt->buf);
++ kvfree(pkt->buf);
+ kfree(pkt);
+ }
+ EXPORT_SYMBOL_GPL(virtio_transport_free_pkt);
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index c7383ede794fc..d5c7a5aa68532 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2389,6 +2389,10 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
++ if (!wdev->links[link].ap.beacon_interval)
++ continue;
++ chandef = wdev->links[link].ap.chandef;
++ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!wdev->u.mesh.beacon_interval)
+ continue;
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 7bada4e8460ba..9f0561b67c12e 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -355,16 +355,15 @@ static u32 xsk_tx_peek_release_fallback(struct xsk_buff_pool *pool, u32 max_entr
+ return nb_pkts;
+ }
+
+-u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
++u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 nb_pkts)
+ {
+ struct xdp_sock *xs;
+- u32 nb_pkts;
+
+ rcu_read_lock();
+ if (!list_is_singular(&pool->xsk_tx_list)) {
+ /* Fallback to the non-batched version */
+ rcu_read_unlock();
+- return xsk_tx_peek_release_fallback(pool, max_entries);
++ return xsk_tx_peek_release_fallback(pool, nb_pkts);
+ }
+
+ xs = list_first_or_null_rcu(&pool->xsk_tx_list, struct xdp_sock, tx_list);
+@@ -373,12 +372,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
+ goto out;
+ }
+
+- max_entries = xskq_cons_nb_entries(xs->tx, max_entries);
+- nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries);
+- if (!nb_pkts) {
+- xs->tx->queue_empty_descs++;
+- goto out;
+- }
++ nb_pkts = xskq_cons_nb_entries(xs->tx, nb_pkts);
+
+ /* This is the backpressure mechanism for the Tx path. Try to
+ * reserve space in the completion queue for all packets, but
+@@ -386,12 +380,18 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
+ * packets. This avoids having to implement any buffering in
+ * the Tx path.
+ */
+- nb_pkts = xskq_prod_reserve_addr_batch(pool->cq, pool->tx_descs, nb_pkts);
++ nb_pkts = xskq_prod_nb_free(pool->cq, nb_pkts);
+ if (!nb_pkts)
+ goto out;
+
+- xskq_cons_release_n(xs->tx, max_entries);
++ nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, nb_pkts);
++ if (!nb_pkts) {
++ xs->tx->queue_empty_descs++;
++ goto out;
++ }
++
+ __xskq_cons_release(xs->tx);
++ xskq_prod_write_addr_batch(pool->cq, pool->tx_descs, nb_pkts);
+ xs->sk.sk_write_space(&xs->sk);
+
+ out:
+diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
+index fb20bf7207cfb..c6fb6b7636582 100644
+--- a/net/xdp/xsk_queue.h
++++ b/net/xdp/xsk_queue.h
+@@ -205,6 +205,11 @@ static inline bool xskq_cons_read_desc(struct xsk_queue *q,
+ return false;
+ }
+
++static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt)
++{
++ q->cached_cons += cnt;
++}
++
+ static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool,
+ u32 max)
+ {
+@@ -226,6 +231,8 @@ static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff
+ cached_cons++;
+ }
+
++ /* Release valid plus any invalid entries */
++ xskq_cons_release_n(q, cached_cons - q->cached_cons);
+ return nb_entries;
+ }
+
+@@ -291,11 +298,6 @@ static inline void xskq_cons_release(struct xsk_queue *q)
+ q->cached_cons++;
+ }
+
+-static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt)
+-{
+- q->cached_cons += cnt;
+-}
+-
+ static inline u32 xskq_cons_present_entries(struct xsk_queue *q)
+ {
+ /* No barriers needed since data is not accessed */
+@@ -350,21 +352,17 @@ static inline int xskq_prod_reserve_addr(struct xsk_queue *q, u64 addr)
+ return 0;
+ }
+
+-static inline u32 xskq_prod_reserve_addr_batch(struct xsk_queue *q, struct xdp_desc *descs,
+- u32 max)
++static inline void xskq_prod_write_addr_batch(struct xsk_queue *q, struct xdp_desc *descs,
++ u32 nb_entries)
+ {
+ struct xdp_umem_ring *ring = (struct xdp_umem_ring *)q->ring;
+- u32 nb_entries, i, cached_prod;
+-
+- nb_entries = xskq_prod_nb_free(q, max);
++ u32 i, cached_prod;
+
+ /* A, matches D */
+ cached_prod = q->cached_prod;
+ for (i = 0; i < nb_entries; i++)
+ ring->desc[cached_prod++ & q->ring_mask] = descs[i].addr;
+ q->cached_prod = cached_prod;
+-
+- return nb_entries;
+ }
+
+ static inline int xskq_prod_reserve_desc(struct xsk_queue *q,
+diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
+index b2f4ec9c537f0..aa5220565763c 100644
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -24,7 +24,8 @@
+ #include "xfrm_inout.h"
+
+ struct xfrm_trans_tasklet {
+- struct tasklet_struct tasklet;
++ struct work_struct work;
++ spinlock_t queue_lock;
+ struct sk_buff_head queue;
+ };
+
+@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
+ }
+ EXPORT_SYMBOL(xfrm_input_resume);
+
+-static void xfrm_trans_reinject(struct tasklet_struct *t)
++static void xfrm_trans_reinject(struct work_struct *work)
+ {
+- struct xfrm_trans_tasklet *trans = from_tasklet(trans, t, tasklet);
++ struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);
+ struct sk_buff_head queue;
+ struct sk_buff *skb;
+
+ __skb_queue_head_init(&queue);
++ spin_lock_bh(&trans->queue_lock);
+ skb_queue_splice_init(&trans->queue, &queue);
++ spin_unlock_bh(&trans->queue_lock);
+
++ local_bh_disable();
+ while ((skb = __skb_dequeue(&queue)))
+ XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
+ NULL, skb);
++ local_bh_enable();
+ }
+
+ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+
+ XFRM_TRANS_SKB_CB(skb)->finish = finish;
+ XFRM_TRANS_SKB_CB(skb)->net = net;
++ spin_lock_bh(&trans->queue_lock);
+ __skb_queue_tail(&trans->queue, skb);
+- tasklet_schedule(&trans->tasklet);
++ spin_unlock_bh(&trans->queue_lock);
++ schedule_work(&trans->work);
+ return 0;
+ }
+ EXPORT_SYMBOL(xfrm_trans_queue_net);
+@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)
+ struct xfrm_trans_tasklet *trans;
+
+ trans = &per_cpu(xfrm_trans_tasklet, i);
++ spin_lock_init(&trans->queue_lock);
+ __skb_queue_head_init(&trans->queue);
+- tasklet_setup(&trans->tasklet, xfrm_trans_reinject);
++ INIT_WORK(&trans->work, xfrm_trans_reinject);
+ }
+ }
+diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
+index cb40ff0ff28da..92ad336a83ab5 100644
+--- a/net/xfrm/xfrm_ipcomp.c
++++ b/net/xfrm/xfrm_ipcomp.c
+@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)
+ vfree(*per_cpu_ptr(scratches, i));
+
+ free_percpu(scratches);
++ ipcomp_scratches = NULL;
+ }
+
+ static void * __percpu *ipcomp_alloc_scratches(void)
+diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
+index ece44b7350613..2bc08ace38a3b 100644
+--- a/scripts/Kbuild.include
++++ b/scripts/Kbuild.include
+@@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\
+ quiet_redirect :=
+ silent_redirect := exec >/dev/null;
+
++# Delete the target on interruption
++#
++# GNU Make automatically deletes the target if it has already been changed by
++# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make
++# will delete incomplete targets), and resume it later.
++#
++# However, this does not work when the stderr is piped to another program, like
++# $ make >&2 | tee log
++# Make dies with SIGPIPE before cleaning the targets.
++#
++# To address it, we clean the target in signal traps.
++#
++# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM.
++# So, we cover them, and also SIGPIPE just in case.
++#
++# Of course, this is unneeded for phony targets.
++delete-on-interrupt = \
++ $(if $(filter-out $(PHONY), $@), \
++ $(foreach sig, HUP INT QUIT TERM PIPE, \
++ trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
++
+ # printing commands
+-cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1))
++cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1))
+
+ ###
+ # if_changed - execute command if any prerequisite is newer than
+diff --git a/scripts/package/mkspec b/scripts/package/mkspec
+index 8fa7c5b8a1a15..c920c1b18e7ad 100755
+--- a/scripts/package/mkspec
++++ b/scripts/package/mkspec
+@@ -88,10 +88,10 @@ $S
+ mkdir -p %{buildroot}/boot
+ %ifarch ia64
+ mkdir -p %{buildroot}/boot/efi
+- cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
++ cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
+ ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/
+ %else
+- cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
++ cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
+ %endif
+ $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install
+ $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
+index 2dccf141241d7..20af56ce245c5 100755
+--- a/scripts/selinux/install_policy.sh
++++ b/scripts/selinux/install_policy.sh
+@@ -78,7 +78,7 @@ cd /etc/selinux/dummy/contexts/files
+ $SF -F file_contexts /
+
+ mounts=`cat /proc/$$/mounts | \
+- egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
++ grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
+ awk '{ print $2 '}`
+ $SF -F file_contexts $mounts
+
+diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
+index bde74fcecee38..3e0fbbd995342 100644
+--- a/security/integrity/ima/ima_appraise.c
++++ b/security/integrity/ima/ima_appraise.c
+@@ -750,22 +750,26 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+ const struct evm_ima_xattr_data *xvalue = xattr_value;
+ int digsig = 0;
+ int result;
++ int err;
+
+ result = ima_protect_xattr(dentry, xattr_name, xattr_value,
+ xattr_value_len);
+ if (result == 1) {
+ if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
+ return -EINVAL;
++
++ err = validate_hash_algo(dentry, xvalue, xattr_value_len);
++ if (err)
++ return err;
++
+ digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
+ } else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
+ digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
+ }
+ if (result == 1 || evm_revalidate_status(xattr_name)) {
+- result = validate_hash_algo(dentry, xvalue, xattr_value_len);
+- if (result)
+- return result;
+-
+ ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
++ if (result == 1)
++ result = 0;
+ }
+ return result;
+ }
+diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig
+index 70e7985b2561c..994c1d9376e6b 100644
+--- a/security/loadpin/Kconfig
++++ b/security/loadpin/Kconfig
+@@ -33,4 +33,4 @@ config SECURITY_LOADPIN_VERITY
+ on the LoadPin securityfs entry 'dm-verity'. The ioctl
+ expects a file descriptor of a file with verity digests as
+ parameter. The file must be located on the pinned root and
+- contain a comma separated list of digests.
++ contain one digest per line.
+diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
+index 5b2ca028f5aab..494ec0c207fad 100644
+--- a/sound/core/pcm_dmaengine.c
++++ b/sound/core/pcm_dmaengine.c
+@@ -133,12 +133,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
+
+ static void dmaengine_pcm_dma_complete(void *arg)
+ {
++ unsigned int new_pos;
+ struct snd_pcm_substream *substream = arg;
+ struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+
+- prtd->pos += snd_pcm_lib_period_bytes(substream);
+- if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
+- prtd->pos = 0;
++ new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream);
++ if (new_pos >= snd_pcm_lib_buffer_bytes(substream))
++ new_pos = 0;
++ prtd->pos = new_pos;
+
+ snd_pcm_period_elapsed(substream);
+ }
+diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
+index 6963d5a487b32..d8edb60550724 100644
+--- a/sound/core/rawmidi.c
++++ b/sound/core/rawmidi.c
+@@ -1899,10 +1899,8 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
+
+ snd_info_free_entry(rmidi->proc_entry);
+ rmidi->proc_entry = NULL;
+- mutex_lock(®ister_mutex);
+ if (rmidi->ops && rmidi->ops->dev_unregister)
+ rmidi->ops->dev_unregister(rmidi);
+- mutex_unlock(®ister_mutex);
+
+ snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
+ snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
+diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
+index 7ed0a2a910352..2751bf2ff61bc 100644
+--- a/sound/core/sound_oss.c
++++ b/sound/core/sound_oss.c
+@@ -162,7 +162,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
+ mutex_unlock(&sound_oss_mutex);
+ return -ENOENT;
+ }
+- unregister_sound_special(minor);
+ switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
+ case SNDRV_MINOR_OSS_PCM:
+ track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
+@@ -174,12 +173,18 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
+ track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
+ break;
+ }
+- if (track2 >= 0) {
+- unregister_sound_special(track2);
++ if (track2 >= 0)
+ snd_oss_minors[track2] = NULL;
+- }
+ snd_oss_minors[minor] = NULL;
+ mutex_unlock(&sound_oss_mutex);
++
++ /* call unregister_sound_special() outside sound_oss_mutex;
++ * otherwise may deadlock, as it can trigger the release of a card
++ */
++ unregister_sound_special(minor);
++ if (track2 >= 0)
++ unregister_sound_special(track2);
++
+ kfree(mptr);
+ return 0;
+ }
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index 5a478649f3381..b9eb3208f2888 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -427,6 +427,11 @@ static const struct config_entry config_table[] = {
+ .device = 0x51cd,
+ },
+ /* Alderlake-PS */
++ {
++ .flags = FLAG_SOF,
++ .device = 0x51c9,
++ .codec_hid = &essx_83x6,
++ },
+ {
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x51c9,
+diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
+index 53a2b89f8983c..e63621bcb2142 100644
+--- a/sound/pci/hda/hda_beep.c
++++ b/sound/pci/hda/hda_beep.c
+@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
+ return 0;
+ }
+
++static void turn_on_beep(struct hda_beep *beep)
++{
++ if (beep->keep_power_at_enable)
++ snd_hda_power_up_pm(beep->codec);
++}
++
+ static void turn_off_beep(struct hda_beep *beep)
+ {
+ cancel_work_sync(&beep->beep_work);
+@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep)
+ /* turn off beep */
+ generate_tone(beep, 0);
+ }
++ if (beep->keep_power_at_enable)
++ snd_hda_power_down_pm(beep->codec);
+ }
+
+ /**
+@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
+ enable = !!enable;
+ if (beep->enabled != enable) {
+ beep->enabled = enable;
+- if (!enable)
++ if (enable)
++ turn_on_beep(beep);
++ else
+ turn_off_beep(beep);
+ return 1;
+ }
+@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device)
+ input_unregister_device(beep->dev);
+ else
+ input_free_device(beep->dev);
+- turn_off_beep(beep);
++ if (beep->enabled)
++ turn_off_beep(beep);
+ return 0;
+ }
+
+diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
+index a25358a4807ab..db76e3ddba654 100644
+--- a/sound/pci/hda/hda_beep.h
++++ b/sound/pci/hda/hda_beep.h
+@@ -25,6 +25,7 @@ struct hda_beep {
+ unsigned int enabled:1;
+ unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
+ unsigned int playing:1;
++ unsigned int keep_power_at_enable:1; /* set by driver */
+ struct work_struct beep_work; /* scheduled task for beep event */
+ struct mutex mutex;
+ void (*power_hook)(struct hda_beep *beep, bool on);
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 384426d7e9ddc..4ae8b9574778b 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -931,8 +931,28 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
+ }
+
+ codec->bus = bus;
++ codec->depop_delay = -1;
++ codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
++ codec->core.dev.release = snd_hda_codec_dev_release;
++ codec->core.exec_verb = codec_exec_verb;
+ codec->core.type = HDA_DEV_LEGACY;
+
++ mutex_init(&codec->spdif_mutex);
++ mutex_init(&codec->control_mutex);
++ snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
++ snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
++ snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
++ snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
++ snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
++ snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
++ snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
++ snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
++ INIT_LIST_HEAD(&codec->conn_list);
++ INIT_LIST_HEAD(&codec->pcm_list_head);
++ INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
++ refcount_set(&codec->pcm_ref, 1);
++ init_waitqueue_head(&codec->remove_sleep);
++
+ return codec;
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_codec_device_init);
+@@ -985,29 +1005,8 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
+ if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
+ return -EINVAL;
+
+- codec->core.dev.release = snd_hda_codec_dev_release;
+- codec->core.exec_verb = codec_exec_verb;
+-
+ codec->card = card;
+ codec->addr = codec_addr;
+- mutex_init(&codec->spdif_mutex);
+- mutex_init(&codec->control_mutex);
+- snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
+- snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
+- snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
+- snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
+- snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
+- snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
+- snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
+- snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
+- INIT_LIST_HEAD(&codec->conn_list);
+- INIT_LIST_HEAD(&codec->pcm_list_head);
+- refcount_set(&codec->pcm_ref, 1);
+- init_waitqueue_head(&codec->remove_sleep);
+-
+- INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
+- codec->depop_delay = -1;
+- codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+
+ #ifdef CONFIG_PM
+ codec->power_jiffies = jiffies;
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index c239d9dbbaefe..287f4f78e7b1e 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -53,7 +53,8 @@ MODULE_PARM_DESC(enable_all_pins, "Forcibly enable all pins");
+
+ struct hdmi_spec_per_cvt {
+ hda_nid_t cvt_nid;
+- int assigned;
++ bool assigned; /* the stream has been assigned */
++ bool silent_stream; /* silent stream activated */
+ unsigned int channels_min;
+ unsigned int channels_max;
+ u32 rates;
+@@ -988,7 +989,8 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
+ * of the pin.
+ */
+ static int hdmi_choose_cvt(struct hda_codec *codec,
+- int pin_idx, int *cvt_id)
++ int pin_idx, int *cvt_id,
++ bool silent)
+ {
+ struct hdmi_spec *spec = codec->spec;
+ struct hdmi_spec_per_pin *per_pin;
+@@ -1003,6 +1005,9 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
+
+ if (per_pin && per_pin->silent_stream) {
+ cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
++ per_cvt = get_cvt(spec, cvt_idx);
++ if (per_cvt->assigned && !silent)
++ return -EBUSY;
+ if (cvt_id)
+ *cvt_id = cvt_idx;
+ return 0;
+@@ -1013,7 +1018,7 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
+ per_cvt = get_cvt(spec, cvt_idx);
+
+ /* Must not already be assigned */
+- if (per_cvt->assigned)
++ if (per_cvt->assigned || per_cvt->silent_stream)
+ continue;
+ if (per_pin == NULL)
+ break;
+@@ -1199,12 +1204,12 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
+ if (pcm_idx < 0)
+ return -EINVAL;
+
+- err = hdmi_choose_cvt(codec, -1, &cvt_idx);
++ err = hdmi_choose_cvt(codec, -1, &cvt_idx, false);
+ if (err)
+ return err;
+
+ per_cvt = get_cvt(spec, cvt_idx);
+- per_cvt->assigned = 1;
++ per_cvt->assigned = true;
+ hinfo->nid = per_cvt->cvt_nid;
+
+ pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid);
+@@ -1267,18 +1272,17 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+ }
+ }
+
+- err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
++ err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false);
+ if (err < 0)
+ goto unlock;
+
+ per_cvt = get_cvt(spec, cvt_idx);
+ /* Claim converter */
+- per_cvt->assigned = 1;
++ per_cvt->assigned = true;
+
+ set_bit(pcm_idx, &spec->pcm_in_use);
+ per_pin = get_pin(spec, pin_idx);
+ per_pin->cvt_nid = per_cvt->cvt_nid;
+- per_pin->silent_stream = false;
+ hinfo->nid = per_cvt->cvt_nid;
+
+ /* flip stripe flag for the assigned stream if supported */
+@@ -1308,7 +1312,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+ snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);
+ if (hinfo->channels_min > hinfo->channels_max ||
+ !hinfo->rates || !hinfo->formats) {
+- per_cvt->assigned = 0;
++ per_cvt->assigned = false;
+ hinfo->nid = 0;
+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+ err = -ENODEV;
+@@ -1760,14 +1764,14 @@ static void silent_stream_enable(struct hda_codec *codec,
+ }
+
+ pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id);
+- err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
++ err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, true);
+ if (err) {
+ codec_err(codec, "hdmi: no free converter to enable silent mode\n");
+ goto unlock_out;
+ }
+
+ per_cvt = get_cvt(spec, cvt_idx);
+- per_cvt->assigned = 1;
++ per_cvt->silent_stream = true;
+ per_pin->cvt_nid = per_cvt->cvt_nid;
+ per_pin->silent_stream = true;
+
+@@ -1827,7 +1831,7 @@ static void silent_stream_disable(struct hda_codec *codec,
+ cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
+ if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) {
+ per_cvt = get_cvt(spec, cvt_idx);
+- per_cvt->assigned = 0;
++ per_cvt->silent_stream = false;
+ }
+
+ if (spec->silent_stream_type == SILENT_STREAM_I915) {
+@@ -2223,7 +2227,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
+ goto unlock;
+ }
+ per_cvt = get_cvt(spec, cvt_idx);
+- per_cvt->assigned = 0;
++ per_cvt->assigned = false;
+ hinfo->nid = 0;
+
+ azx_stream(get_azx_dev(substream))->stripe = 0;
+@@ -2747,9 +2751,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)
+ */
+ if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+ return;
+- /* ditto during suspend/resume process itself */
+- if (snd_hdac_is_in_pm(&codec->core))
+- return;
+
+ check_presence_and_report(codec, pin_nid, dev_id);
+ }
+@@ -2933,9 +2934,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
+ */
+ if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+ return;
+- /* ditto during suspend/resume process itself */
+- if (snd_hdac_is_in_pm(&codec->core))
+- return;
+
+ snd_hdac_i915_set_bclk(&codec->bus->core);
+ check_presence_and_report(codec, pin_nid, dev_id);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 3dc19174670eb..8f7905e0b376b 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8427,11 +8427,13 @@ static const struct hda_fixup alc269_fixups[] = {
+ [ALC285_FIXUP_ASUS_G533Z_PINS] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+- { 0x14, 0x90170120 },
++ { 0x14, 0x90170152 }, /* Speaker Surround Playback Switch */
++ { 0x19, 0x03a19020 }, /* Mic Boost Volume */
++ { 0x1a, 0x03a11c30 }, /* Mic Boost Volume */
++ { 0x1e, 0x90170151 }, /* Rear jack, IN OUT EAPD Detect */
++ { 0x21, 0x03211420 },
+ { }
+ },
+- .chained = true,
+- .chain_id = ALC294_FIXUP_ASUS_G513_PINS,
+ },
+ [ALC294_FIXUP_ASUS_COEF_1B] = {
+ .type = HDA_FIXUP_VERBS,
+@@ -9186,7 +9188,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
+- SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK),
+ SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
+@@ -9410,6 +9411,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
++ SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
+@@ -9431,6 +9433,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
+ SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
+ SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
++ SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index 7f340f18599c9..a794a01a68ca6 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec)
+ if (codec->beep) {
+ /* IDT/STAC codecs have linear beep tone parameter */
+ codec->beep->linear_tone = spec->linear_tone_beep;
++ /* keep power up while beep is enabled */
++ codec->beep->keep_power_at_enable = 1;
+ /* if no beep switch is available, make its own one */
+ caps = query_amp_caps(codec, nid, HDA_OUTPUT);
+ if (!(caps & AC_AMPCAP_MUTE)) {
+@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec)
+
+ return 0;
+ }
+-
+-static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid)
+-{
+-#ifdef CONFIG_SND_HDA_INPUT_BEEP
+- struct sigmatel_spec *spec = codec->spec;
+-#endif
+- int ret = snd_hda_gen_check_power_status(codec, nid);
+-
+-#ifdef CONFIG_SND_HDA_INPUT_BEEP
+- if (nid == spec->gen.beep_nid && codec->beep) {
+- if (codec->beep->enabled != spec->beep_power_on) {
+- spec->beep_power_on = codec->beep->enabled;
+- if (spec->beep_power_on)
+- snd_hda_power_up_pm(codec);
+- else
+- snd_hda_power_down_pm(codec);
+- }
+- ret |= spec->beep_power_on;
+- }
+-#endif
+- return ret;
+-}
+ #else
+ #define stac_suspend NULL
+ #endif /* CONFIG_PM */
+@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = {
+ .unsol_event = snd_hda_jack_unsol_event,
+ #ifdef CONFIG_PM
+ .suspend = stac_suspend,
+- .check_power_status = stac_check_power_status,
+ #endif
+ };
+
+diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c
+index 2c8e960cc9a6a..5bb23ebe12166 100644
+--- a/sound/soc/amd/acp/acp-pci.c
++++ b/sound/soc/amd/acp/acp-pci.c
+@@ -104,6 +104,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
+ addr = pci_resource_start(pci, 0);
+ chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
+ if (!chip->base) {
++ platform_device_unregister(dmic_dev);
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index e0b24e1daef3d..2cb50d5cf1a9a 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -171,6 +171,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82"),
++ }
++ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
++ }
++ },
+ {}
+ };
+
+diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
+index 50ecf30e6136a..4746c87004512 100644
+--- a/sound/soc/codecs/da7219.c
++++ b/sound/soc/codecs/da7219.c
+@@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)
+ dai_clk_lookup = clkdev_hw_create(dai_clk_hw, init.name,
+ "%s", dev_name(dev));
+ if (!dai_clk_lookup) {
++ clk_hw_unregister(dai_clk_hw);
+ ret = -ENOMEM;
+ goto err;
+ } else {
+@@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)
+ return 0;
+
+ err:
+- do {
++ while (--i >= 0) {
+ if (da7219->dai_clks_lookup[i])
+ clkdev_drop(da7219->dai_clks_lookup[i]);
+
+ clk_hw_unregister(&da7219->dai_clks_hw[i]);
+- } while (i-- > 0);
++ }
+
+ if (np)
+ kfree(da7219->clk_hw_data);
+diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
+index 55503ba480bb6..e162a08d99452 100644
+--- a/sound/soc/codecs/lpass-tx-macro.c
++++ b/sound/soc/codecs/lpass-tx-macro.c
+@@ -823,17 +823,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
+ struct tx_macro *tx = snd_soc_component_get_drvdata(component);
+
+ if (enable) {
++ if (tx->active_decimator[dai_id] == dec_id)
++ return 0;
++
+ set_bit(dec_id, &tx->active_ch_mask[dai_id]);
+ tx->active_ch_cnt[dai_id]++;
+ tx->active_decimator[dai_id] = dec_id;
+ } else {
++ if (tx->active_decimator[dai_id] == -1)
++ return 0;
++
+ tx->active_ch_cnt[dai_id]--;
+ clear_bit(dec_id, &tx->active_ch_mask[dai_id]);
+ tx->active_decimator[dai_id] = -1;
+ }
+ snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+
+- return 0;
++ return 1;
+ }
+
+ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
+@@ -1019,9 +1025,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
+ int path = e->shift_l;
+ struct tx_macro *tx = snd_soc_component_get_drvdata(component);
+
++ if (tx->dec_mode[path] == value)
++ return 0;
++
+ tx->dec_mode[path] = value;
+
+- return 0;
++ return 1;
+ }
+
+ static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
+diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c
+index c190628e29056..7f624854948c7 100644
+--- a/sound/soc/codecs/mt6359-accdet.c
++++ b/sound/soc/codecs/mt6359-accdet.c
+@@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+ mutex_init(&priv->res_lock);
+
+ priv->accdet_irq = platform_get_irq(pdev, 0);
+- if (priv->accdet_irq) {
++ if (priv->accdet_irq >= 0) {
+ ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq,
+ NULL, mt6359_accdet_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+@@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+
+ if (priv->caps & ACCDET_PMIC_EINT0) {
+ priv->accdet_eint0 = platform_get_irq(pdev, 1);
+- if (priv->accdet_eint0) {
++ if (priv->accdet_eint0 >= 0) {
+ ret = devm_request_threaded_irq(&pdev->dev,
+ priv->accdet_eint0,
+ NULL, mt6359_accdet_irq,
+@@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+ }
+ } else if (priv->caps & ACCDET_PMIC_EINT1) {
+ priv->accdet_eint1 = platform_get_irq(pdev, 2);
+- if (priv->accdet_eint1) {
++ if (priv->accdet_eint1 >= 0) {
+ ret = devm_request_threaded_irq(&pdev->dev,
+ priv->accdet_eint1,
+ NULL, mt6359_accdet_irq,
+diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c
+index ba11555796ad8..45e0df13afb9f 100644
+--- a/sound/soc/codecs/mt6660.c
++++ b/sound/soc/codecs/mt6660.c
+@@ -503,13 +503,17 @@ static int mt6660_i2c_probe(struct i2c_client *client)
+ dev_err(chip->dev, "read chip revision fail\n");
+ goto probe_fail;
+ }
+- pm_runtime_set_active(chip->dev);
+- pm_runtime_enable(chip->dev);
+
+ ret = devm_snd_soc_register_component(chip->dev,
+ &mt6660_component_driver,
+ &mt6660_codec_dai, 1);
++ if (!ret) {
++ pm_runtime_set_active(chip->dev);
++ pm_runtime_enable(chip->dev);
++ }
++
+ return ret;
++
+ probe_fail:
+ _mt6660_chip_power_on(chip, 0);
+ mutex_destroy(&chip->io_lock);
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 846d9d3ecc9de..39902f77a2e0f 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -34,6 +34,9 @@ struct tas2764_priv {
+
+ int v_sense_slot;
+ int i_sense_slot;
++
++ bool dac_powered;
++ bool unmuted;
+ };
+
+ static void tas2764_reset(struct tas2764_priv *tas2764)
+@@ -50,34 +53,22 @@ static void tas2764_reset(struct tas2764_priv *tas2764)
+ usleep_range(1000, 2000);
+ }
+
+-static int tas2764_set_bias_level(struct snd_soc_component *component,
+- enum snd_soc_bias_level level)
++static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764)
+ {
+- struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
++ struct snd_soc_component *component = tas2764->component;
++ unsigned int val;
++ int ret;
+
+- switch (level) {
+- case SND_SOC_BIAS_ON:
+- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_ACTIVE);
+- break;
+- case SND_SOC_BIAS_STANDBY:
+- case SND_SOC_BIAS_PREPARE:
+- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_MUTE);
+- break;
+- case SND_SOC_BIAS_OFF:
+- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_SHUTDOWN);
+- break;
++ if (tas2764->dac_powered)
++ val = tas2764->unmuted ?
++ TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE;
++ else
++ val = TAS2764_PWR_CTRL_SHUTDOWN;
+
+- default:
+- dev_err(tas2764->dev,
+- "wrong power level setting %d\n", level);
+- return -EINVAL;
+- }
++ ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
++ TAS2764_PWR_CTRL_MASK, val);
++ if (ret < 0)
++ return ret;
+
+ return 0;
+ }
+@@ -114,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component)
+ usleep_range(1000, 2000);
+ }
+
+- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_ACTIVE);
++ ret = tas2764_update_pwr_ctrl(tas2764);
+
+ if (ret < 0)
+ return ret;
+@@ -150,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w,
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_MUTE);
++ tas2764->dac_powered = true;
++ ret = tas2764_update_pwr_ctrl(tas2764);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_SHUTDOWN);
++ tas2764->dac_powered = false;
++ ret = tas2764_update_pwr_ctrl(tas2764);
+ break;
+ default:
+ dev_err(tas2764->dev, "Unsupported event\n");
+@@ -202,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = {
+
+ static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction)
+ {
+- struct snd_soc_component *component = dai->component;
+- int ret;
+-
+- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- mute ? TAS2764_PWR_CTRL_MUTE : 0);
++ struct tas2764_priv *tas2764 =
++ snd_soc_component_get_drvdata(dai->component);
+
+- if (ret < 0)
+- return ret;
+-
+- return 0;
++ tas2764->unmuted = !mute;
++ return tas2764_update_pwr_ctrl(tas2764);
+ }
+
+ static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth)
+@@ -485,7 +466,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = {
+ .id = 0,
+ .playback = {
+ .stream_name = "ASI1 Playback",
+- .channels_min = 2,
++ .channels_min = 1,
+ .channels_max = 2,
+ .rates = TAS2764_RATES,
+ .formats = TAS2764_FORMATS,
+@@ -526,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
+ if (ret < 0)
+ return ret;
+
+- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+- TAS2764_PWR_CTRL_MASK,
+- TAS2764_PWR_CTRL_MUTE);
+- if (ret < 0)
+- return ret;
+-
+ return 0;
+ }
+
+@@ -549,7 +524,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = {
+ .probe = tas2764_codec_probe,
+ .suspend = tas2764_codec_suspend,
+ .resume = tas2764_codec_resume,
+- .set_bias_level = tas2764_set_bias_level,
+ .controls = tas2764_snd_controls,
+ .num_controls = ARRAY_SIZE(tas2764_snd_controls),
+ .dapm_widgets = tas2764_dapm_widgets,
+diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
+index 98baef594bf31..31009283e7d4a 100644
+--- a/sound/soc/codecs/wcd-mbhc-v2.c
++++ b/sound/soc/codecs/wcd-mbhc-v2.c
+@@ -714,11 +714,12 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
+ struct snd_soc_component *component = mbhc->component;
+ int ret;
+
+- ret = pm_runtime_resume_and_get(component->dev);
++ ret = pm_runtime_get_sync(component->dev);
+ if (ret < 0 && ret != -EACCES) {
+ dev_err_ratelimited(component->dev,
+- "pm_runtime_resume_and_get failed in %s, ret %d\n",
++ "pm_runtime_get_sync failed in %s, ret %d\n",
+ __func__, ret);
++ pm_runtime_put_noidle(component->dev);
+ return ret;
+ }
+
+@@ -1096,11 +1097,12 @@ static void wcd_correct_swch_plug(struct work_struct *work)
+ mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch);
+ component = mbhc->component;
+
+- ret = pm_runtime_resume_and_get(component->dev);
++ ret = pm_runtime_get_sync(component->dev);
+ if (ret < 0 && ret != -EACCES) {
+ dev_err_ratelimited(component->dev,
+- "pm_runtime_resume_and_get failed in %s, ret %d\n",
++ "pm_runtime_get_sync failed in %s, ret %d\n",
+ __func__, ret);
++ pm_runtime_put_noidle(component->dev);
+ return;
+ }
+ micbias_mv = wcd_mbhc_get_micbias(mbhc);
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index beeeb35e80321..8a1f741de948a 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -1974,8 +1974,8 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- slim_stream_unprepare(dai_data->sruntime);
+ slim_stream_disable(dai_data->sruntime);
++ slim_stream_unprepare(dai_data->sruntime);
+ break;
+ default:
+ break;
+diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
+index f56907d0942db..28175c746b9ae 100644
+--- a/sound/soc/codecs/wcd934x.c
++++ b/sound/soc/codecs/wcd934x.c
+@@ -1913,8 +1913,8 @@ static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- slim_stream_unprepare(dai_data->sruntime);
+ slim_stream_disable(dai_data->sruntime);
++ slim_stream_unprepare(dai_data->sruntime);
+ break;
+ default:
+ break;
+diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
+index af7d324e33525..c09c9ac51b3e7 100644
+--- a/sound/soc/codecs/wm5102.c
++++ b/sound/soc/codecs/wm5102.c
+@@ -2099,9 +2099,6 @@ static int wm5102_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
+ WM5102_DIG_VU, WM5102_DIG_VU);
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
+ wm5102);
+@@ -2134,6 +2131,9 @@ static int wm5102_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
+index f3f4a10bf0f7c..fc634c995834d 100644
+--- a/sound/soc/codecs/wm5110.c
++++ b/sound/soc/codecs/wm5110.c
+@@ -2457,9 +2457,6 @@ static int wm5110_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
+ WM5110_DIG_VU, WM5110_DIG_VU);
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
+ wm5110);
+@@ -2492,6 +2489,9 @@ static int wm5110_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
+index 210ad662fc26d..77136a5216059 100644
+--- a/sound/soc/codecs/wm8997.c
++++ b/sound/soc/codecs/wm8997.c
+@@ -1161,9 +1161,6 @@ static int wm8997_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
+ WM8997_DIG_VU, WM8997_DIG_VU);
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ arizona_init_common(arizona);
+
+ ret = arizona_init_vol_limit(arizona);
+@@ -1182,6 +1179,9 @@ static int wm8997_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index cfaa45ede916a..8a2e9771bb50e 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -1602,7 +1602,9 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
+ if (list_empty(&dsp->buffer_list)) {
+ /* Fall back to legacy support */
+ ret = wm_adsp_buffer_parse_legacy(dsp);
+- if (ret)
++ if (ret == -ENODEV)
++ adsp_info(dsp, "Legacy support not available\n");
++ else if (ret)
+ adsp_warn(dsp, "Failed to parse legacy: %d\n", ret);
+ }
+
+diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
+index 8b61582753c86..9af4c4a35eb16 100644
+--- a/sound/soc/fsl/eukrea-tlv320.c
++++ b/sound/soc/fsl/eukrea-tlv320.c
+@@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ int ret;
+ int int_port = 0, ext_port;
+ struct device_node *np = pdev->dev.of_node;
+- struct device_node *ssi_np = NULL, *codec_np = NULL;
++ struct device_node *ssi_np = NULL, *codec_np = NULL, *tmp_np = NULL;
+
+ eukrea_tlv320.dev = &pdev->dev;
+ if (np) {
+@@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ }
+
+ if (machine_is_eukrea_cpuimx27() ||
+- of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) {
++ (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux"))) {
+ imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ IMX_AUDMUX_V1_PCR_SYN |
+ IMX_AUDMUX_V1_PCR_TFSDIR |
+@@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ IMX_AUDMUX_V1_PCR_SYN |
+ IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+ );
++ of_node_put(tmp_np);
+ } else if (machine_is_eukrea_cpuimx25sd() ||
+ machine_is_eukrea_cpuimx35sd() ||
+ machine_is_eukrea_cpuimx51sd() ||
+- of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) {
++ (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux"))) {
+ if (!np)
+ ext_port = machine_is_eukrea_cpuimx25sd() ?
+ 4 : 3;
+@@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ IMX_AUDMUX_V2_PTCR_SYN,
+ IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
+ );
++ of_node_put(tmp_np);
+ } else {
+ if (np) {
+ /* The eukrea,asoc-tlv320 driver was explicitly
+diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+index c530e3fc27e43..961e769602d6a 100644
+--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c
++++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+@@ -1383,7 +1383,13 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev)
+ sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams);
+ sof_priv->sof_dai_link_fixup = mt8195_dai_link_fixup;
+ soc_card_data->sof_priv = sof_priv;
++ card->probe = mtk_sof_card_probe;
+ card->late_probe = mtk_sof_card_late_probe;
++ if (!card->topology_shortname_created) {
++ snprintf(card->topology_shortname, 32, "sof-%s", card->name);
++ card->topology_shortname_created = true;
++ }
++ card->name = card->topology_shortname;
+ sof_on = 1;
+ }
+
+diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
+index f5f3540a9e186..a8758ad68442d 100644
+--- a/sound/soc/rockchip/rockchip_i2s.c
++++ b/sound/soc/rockchip/rockchip_i2s.c
+@@ -126,7 +126,6 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
+ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
+ {
+ unsigned int val = 0;
+- int retry = 10;
+ int ret = 0;
+
+ spin_lock(&i2s->lock);
+@@ -163,18 +162,14 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
+ I2S_CLR_TXC | I2S_CLR_RXC);
+ if (ret < 0)
+ goto end;
+- regmap_read(i2s->regmap, I2S_CLR, &val);
+-
+- /* Should wait for clear operation to finish */
+- while (val) {
+- regmap_read(i2s->regmap, I2S_CLR, &val);
+- retry--;
+- if (!retry) {
+- dev_warn(i2s->dev, "fail to clear\n");
+- ret = -EBUSY;
+- break;
+- }
+- }
++ ret = regmap_read_poll_timeout_atomic(i2s->regmap,
++ I2S_CLR,
++ val,
++ val == 0,
++ 20,
++ 200);
++ if (ret < 0)
++ dev_warn(i2s->dev, "fail to clear: %d\n", ret);
+ }
+ }
+ end:
+@@ -188,7 +183,6 @@ end:
+ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
+ {
+ unsigned int val = 0;
+- int retry = 10;
+ int ret = 0;
+
+ spin_lock(&i2s->lock);
+@@ -226,17 +220,14 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
+ I2S_CLR_TXC | I2S_CLR_RXC);
+ if (ret < 0)
+ goto end;
+- regmap_read(i2s->regmap, I2S_CLR, &val);
+- /* Should wait for clear operation to finish */
+- while (val) {
+- regmap_read(i2s->regmap, I2S_CLR, &val);
+- retry--;
+- if (!retry) {
+- dev_warn(i2s->dev, "fail to clear\n");
+- ret = -EBUSY;
+- break;
+- }
+- }
++ ret = regmap_read_poll_timeout_atomic(i2s->regmap,
++ I2S_CLR,
++ val,
++ val == 0,
++ 20,
++ 200);
++ if (ret < 0)
++ dev_warn(i2s->dev, "fail to clear: %d\n", ret);
+ }
+ }
+ end:
+diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
+index 6156445bcb69a..e39eb2ac7e955 100644
+--- a/sound/soc/sh/rcar/ctu.c
++++ b/sound/soc/sh/rcar/ctu.c
+@@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
+ struct rsnd_priv *priv)
+ {
+- rsnd_mod_power_on(mod);
++ int ret;
++
++ ret = rsnd_mod_power_on(mod);
++ if (ret < 0)
++ return ret;
+
+ rsnd_ctu_activation(mod);
+
+diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
+index 5137e03a9d7c7..16befcbc312cb 100644
+--- a/sound/soc/sh/rcar/dvc.c
++++ b/sound/soc/sh/rcar/dvc.c
+@@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
+ struct rsnd_priv *priv)
+ {
+- rsnd_mod_power_on(mod);
++ int ret;
++
++ ret = rsnd_mod_power_on(mod);
++ if (ret < 0)
++ return ret;
+
+ rsnd_dvc_activation(mod);
+
+diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
+index 3572c2c5686c7..1de0e085804cc 100644
+--- a/sound/soc/sh/rcar/mix.c
++++ b/sound/soc/sh/rcar/mix.c
+@@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
+ struct rsnd_priv *priv)
+ {
+- rsnd_mod_power_on(mod);
++ int ret;
++
++ ret = rsnd_mod_power_on(mod);
++ if (ret < 0)
++ return ret;
+
+ rsnd_mix_activation(mod);
+
+diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
+index 0ea84ae57c6ac..f832165e46bc0 100644
+--- a/sound/soc/sh/rcar/src.c
++++ b/sound/soc/sh/rcar/src.c
+@@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod,
+ struct rsnd_priv *priv)
+ {
+ struct rsnd_src *src = rsnd_mod_to_src(mod);
++ int ret;
+
+ /* reset sync convert_rate */
+ src->sync.val = 0;
+
+- rsnd_mod_power_on(mod);
++ ret = rsnd_mod_power_on(mod);
++ if (ret < 0)
++ return ret;
+
+ rsnd_src_activation(mod);
+
+diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
+index 43c5e27dc5c86..7ade6c5ed96ff 100644
+--- a/sound/soc/sh/rcar/ssi.c
++++ b/sound/soc/sh/rcar/ssi.c
+@@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
+
+ ssi->usrcnt++;
+
+- rsnd_mod_power_on(mod);
++ ret = rsnd_mod_power_on(mod);
++ if (ret < 0)
++ return ret;
+
+ rsnd_ssi_config_init(mod, io);
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 4f60c0a833110..4d9b91e7e14f1 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -723,7 +723,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+ snd_soc_dpcm_mutex_lock(rtd);
+- soc_pcm_clean(rtd, substream, 0);
++ __soc_pcm_close(rtd, substream);
+ snd_soc_dpcm_mutex_unlock(rtd);
+ return 0;
+ }
+diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
+index 6d4ecbe14adf3..ada2e67757494 100644
+--- a/sound/soc/sof/intel/hda.c
++++ b/sound/soc/sof/intel/hda.c
+@@ -376,6 +376,10 @@ static int dmic_num_override = -1;
+ module_param_named(dmic_num, dmic_num_override, int, 0444);
+ MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
+
++static int mclk_id_override = -1;
++module_param_named(mclk_id, mclk_id_override, int, 0444);
++MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
++
+ #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+ static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI);
+ module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444);
+@@ -1565,6 +1569,13 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
+
+ sof_pdata->tplg_filename = tplg_filename;
+ }
++
++ /* check if mclk_id should be modified from topology defaults */
++ if (mclk_id_override >= 0) {
++ dev_info(sdev->dev, "Overriding topology with MCLK %d from kernel_parameter\n", mclk_id_override);
++ sdev->mclk_id_override = true;
++ sdev->mclk_id_quirk = mclk_id_override;
++ }
+ }
+
+ /*
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index 65923e7a5976f..a39b43850f0ed 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -1249,6 +1249,7 @@ static int sof_link_afe_load(struct snd_soc_component *scomp, struct snd_sof_dai
+ static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
+ struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
+ {
++ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs;
+ struct sof_dai_private_data *private = dai->private;
+ u32 size = sizeof(*config);
+@@ -1273,6 +1274,12 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai
+
+ config[i].hdr.size = size;
+
++ if (sdev->mclk_id_override) {
++ dev_dbg(scomp->dev, "tplg: overriding topology mclk_id %d by quirk %d\n",
++ config[i].ssp.mclk_id, sdev->mclk_id_quirk);
++ config[i].ssp.mclk_id = sdev->mclk_id_quirk;
++ }
++
+ /* copy differentiating hw configs to ipc structs */
+ config[i].ssp.mclk_rate = le32_to_cpu(hw_config[i].mclk_rate);
+ config[i].ssp.bclk_rate = le32_to_cpu(hw_config[i].bclk_rate);
+diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
+index 64929dc9af397..340d92452d7c2 100644
+--- a/sound/soc/sof/ipc4-topology.c
++++ b/sound/soc/sof/ipc4-topology.c
+@@ -1544,9 +1544,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
+ msg->data_ptr = ipc_data;
+
+ ret = sof_ipc_tx_message(sdev->ipc, msg, ipc_size, NULL, 0);
+- if (ret < 0)
++ if (ret < 0) {
+ dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);
+
++ if (swidget->id != snd_soc_dapm_scheduler) {
++ struct sof_ipc4_fw_module *fw_module = swidget->module_info;
++
++ ida_free(&fw_module->m_ida, swidget->instance_id);
++ }
++ }
++
+ return ret;
+ }
+
+diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
+index 9c146015cd1b7..ff575de7e46a4 100644
+--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
++++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
+@@ -652,4 +652,5 @@ static struct platform_driver snd_sof_of_mt8195_driver = {
+ module_platform_driver(snd_sof_of_mt8195_driver);
+
+ MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
++MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON);
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index d627092b399d7..643fd1036d60b 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -138,7 +138,7 @@ static const struct dmi_system_id community_key_platforms[] = {
+ .ident = "Google Chromebooks",
+ .callback = chromebook_use_community_key,
+ .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Google"),
++ DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
+ }
+ },
+ {},
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index 823583086279b..828c74bb75f89 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -594,6 +594,10 @@ struct snd_sof_dev {
+ /* to protect the ipc_rx_handler_list and dsp_state_handler_list list */
+ struct mutex client_event_handler_mutex;
+
++ /* quirks to override topology values */
++ bool mclk_id_override;
++ u16 mclk_id_quirk; /* same size as in IPC3 definitions */
++
+ void *private; /* core does not touch this */
+ };
+
+diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
+index 04f2912e14181..643fc8a170184 100644
+--- a/sound/soc/stm/stm32_adfsdm.c
++++ b/sound/soc/stm/stm32_adfsdm.c
+@@ -335,8 +335,6 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+
+ dev_set_drvdata(&pdev->dev, priv);
+
+- pm_runtime_enable(&pdev->dev);
+-
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &stm32_adfsdm_dai_component,
+ &priv->dai_drv, 1);
+@@ -366,9 +364,13 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ #endif
+
+ ret = snd_soc_add_component(component, NULL, 0);
+- if (ret < 0)
++ if (ret < 0) {
+ dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
+ __func__);
++ return ret;
++ }
++
++ pm_runtime_enable(&pdev->dev);
+
+ return ret;
+ }
+diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
+index 6aafe793eec44..ce7f6942308f9 100644
+--- a/sound/soc/stm/stm32_i2s.c
++++ b/sound/soc/stm/stm32_i2s.c
+@@ -1136,8 +1136,6 @@ static int stm32_i2s_probe(struct platform_device *pdev)
+ return dev_err_probe(&pdev->dev, PTR_ERR(i2s->regmap),
+ "Regmap init error\n");
+
+- pm_runtime_enable(&pdev->dev);
+-
+ ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "PCM DMA register error\n");
+@@ -1180,6 +1178,8 @@ static int stm32_i2s_probe(struct platform_device *pdev)
+ FIELD_GET(I2S_VERR_MIN_MASK, val));
+ }
+
++ pm_runtime_enable(&pdev->dev);
++
+ return ret;
+
+ error:
+diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
+index 0f71467567176..d399c906bb921 100644
+--- a/sound/soc/stm/stm32_spdifrx.c
++++ b/sound/soc/stm/stm32_spdifrx.c
+@@ -1002,8 +1002,6 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
+ udelay(2);
+ reset_control_deassert(rst);
+
+- pm_runtime_enable(&pdev->dev);
+-
+ pcm_config = &stm32_spdifrx_pcm_config;
+ ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
+ if (ret)
+@@ -1036,6 +1034,8 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
+ FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
+ }
+
++ pm_runtime_enable(&pdev->dev);
++
+ return ret;
+
+ error:
+diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
+index 830beb38bf156..fdf3165acd700 100644
+--- a/sound/soc/sunxi/sun4i-codec.c
++++ b/sound/soc/sunxi/sun4i-codec.c
+@@ -1232,6 +1232,9 @@ static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
+ static const struct snd_soc_component_driver sun4i_codec_component = {
+ .name = "sun4i-codec",
+ .legacy_dai_naming = 1,
++#ifdef CONFIG_DEBUG_FS
++ .debugfs_prefix = "cpu",
++#endif
+ };
+
+ #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index 706d249a9ad6b..a5ed11ea11456 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -690,7 +690,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id)
+ return false;
+ }
+
+-static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
++static int check_delayed_register_option(struct snd_usb_audio *chip)
+ {
+ int i;
+ unsigned int id, inum;
+@@ -699,14 +699,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
+ if (delayed_register[i] &&
+ sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
+ id == chip->usb_id)
+- return iface < inum;
++ return inum;
+ }
+
+- return false;
++ return -1;
+ }
+
+ static const struct usb_device_id usb_audio_ids[]; /* defined below */
+
++/* look for the last interface that matches with our ids and remember it */
++static void find_last_interface(struct snd_usb_audio *chip)
++{
++ struct usb_host_config *config = chip->dev->actconfig;
++ struct usb_interface *intf;
++ int i;
++
++ if (!config)
++ return;
++ for (i = 0; i < config->desc.bNumInterfaces; i++) {
++ intf = config->interface[i];
++ if (usb_match_id(intf, usb_audio_ids))
++ chip->last_iface = intf->altsetting[0].desc.bInterfaceNumber;
++ }
++ usb_audio_dbg(chip, "Found last interface = %d\n", chip->last_iface);
++}
++
+ /* look for the corresponding quirk */
+ static const struct snd_usb_audio_quirk *
+ get_alias_quirk(struct usb_device *dev, unsigned int id)
+@@ -813,6 +830,7 @@ static int usb_audio_probe(struct usb_interface *intf,
+ err = -ENODEV;
+ goto __error;
+ }
++ find_last_interface(chip);
+ }
+
+ if (chip->num_interfaces >= MAX_CARD_INTERFACES) {
+@@ -862,11 +880,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+ chip->need_delayed_register = false; /* clear again */
+ }
+
+- /* we are allowed to call snd_card_register() many times, but first
+- * check to see if a device needs to skip it or do anything special
++ /* register card if we reach to the last interface or to the specified
++ * one given via option
+ */
+- if (!snd_usb_registration_quirk(chip, ifnum) &&
+- !check_delayed_register_option(chip, ifnum)) {
++ if (check_delayed_register_option(chip) == ifnum ||
++ usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
+ err = snd_card_register(chip->card);
+ if (err < 0)
+ goto __error;
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index eb71df9da831a..2420dc994632a 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -39,6 +39,7 @@ struct snd_usb_iface_ref {
+ struct snd_usb_clock_ref {
+ unsigned char clock;
+ atomic_t locked;
++ int opened;
+ int rate;
+ struct list_head list;
+ };
+@@ -93,12 +94,13 @@ static inline unsigned get_usb_high_speed_rate(unsigned int rate)
+ */
+ static void release_urb_ctx(struct snd_urb_ctx *u)
+ {
+- if (u->buffer_size)
++ if (u->urb && u->buffer_size)
+ usb_free_coherent(u->ep->chip->dev, u->buffer_size,
+ u->urb->transfer_buffer,
+ u->urb->transfer_dma);
+ usb_free_urb(u->urb);
+ u->urb = NULL;
++ u->buffer_size = 0;
+ }
+
+ static const char *usb_error_string(int err)
+@@ -801,6 +803,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
+ ep = NULL;
+ goto unlock;
+ }
++ ep->clock_ref->opened++;
+ }
+
+ ep->cur_audiofmt = fp;
+@@ -924,8 +927,10 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ endpoint_set_interface(chip, ep, false);
+
+ if (!--ep->opened) {
+- if (ep->clock_ref && !atomic_read(&ep->clock_ref->locked))
+- ep->clock_ref->rate = 0;
++ if (ep->clock_ref) {
++ if (!--ep->clock_ref->opened)
++ ep->clock_ref->rate = 0;
++ }
+ ep->iface = 0;
+ ep->altsetting = 0;
+ ep->cur_audiofmt = NULL;
+@@ -1261,6 +1266,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep)
+ if (!ep->syncbuf)
+ return -ENOMEM;
+
++ ep->nurbs = SYNC_URBS;
+ for (i = 0; i < SYNC_URBS; i++) {
+ struct snd_urb_ctx *u = &ep->urb[i];
+ u->index = i;
+@@ -1280,8 +1286,6 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep)
+ u->urb->complete = snd_complete_urb;
+ }
+
+- ep->nurbs = SYNC_URBS;
+-
+ return 0;
+
+ out_of_memory:
+@@ -1633,8 +1637,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool keep_pending)
+ WRITE_ONCE(ep->sync_source->sync_sink, NULL);
+ stop_urbs(ep, false, keep_pending);
+ if (ep->clock_ref)
+- if (!atomic_dec_return(&ep->clock_ref->locked))
+- ep->clock_ref->rate = 0;
++ atomic_dec(&ep->clock_ref->locked);
+ }
+ }
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index f93201a830b5a..06dfdd45cff8c 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -2985,6 +2985,82 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ }
+ }
+ },
++/* DIGIDESIGN MBOX 3 */
++{
++ USB_DEVICE(0x0dba, 0x5000),
++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++ .vendor_name = "Digidesign",
++ .product_name = "Mbox 3",
++ .ifnum = QUIRK_ANY_INTERFACE,
++ .type = QUIRK_COMPOSITE,
++ .data = (const struct snd_usb_audio_quirk[]) {
++ {
++ .ifnum = 0,
++ .type = QUIRK_IGNORE_INTERFACE
++ },
++ {
++ .ifnum = 1,
++ .type = QUIRK_IGNORE_INTERFACE
++ },
++ {
++ .ifnum = 2,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++ .channels = 4,
++ .iface = 2,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .attributes = 0x00,
++ .endpoint = 0x01,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC |
++ USB_ENDPOINT_SYNC_ASYNC,
++ .rates = SNDRV_PCM_RATE_48000,
++ .rate_min = 48000,
++ .rate_max = 48000,
++ .nr_rates = 1,
++ .rate_table = (unsigned int[]) {
++ 48000
++ }
++ }
++ },
++ {
++ .ifnum = 3,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++ .channels = 4,
++ .iface = 3,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .endpoint = 0x81,
++ .attributes = 0x00,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC |
++ USB_ENDPOINT_SYNC_ASYNC,
++ .maxpacksize = 0x009c,
++ .rates = SNDRV_PCM_RATE_48000,
++ .rate_min = 48000,
++ .rate_max = 48000,
++ .nr_rates = 1,
++ .rate_table = (unsigned int[]) {
++ 48000
++ }
++ }
++ },
++ {
++ .ifnum = 4,
++ .type = QUIRK_MIDI_FIXED_ENDPOINT,
++ .data = &(const struct snd_usb_midi_endpoint_info) {
++ .out_cables = 0x0001,
++ .in_cables = 0x0001
++ }
++ },
++ {
++ .ifnum = -1
++ }
++ }
++ }
++},
+ {
+ /* Tascam US122 MKII - playback-only support */
+ USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021),
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 5b4d8f5eade20..eadac586bcc83 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1020,6 +1020,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
+ return 0;
+ }
+
++static void mbox3_setup_48_24_magic(struct usb_device *dev)
++{
++ /* The Mbox 3 is "little endian" */
++ /* max volume is: 0x0000. */
++ /* min volume is: 0x0080 (shown in little endian form) */
++
++
++ /* Load 48000Hz rate into buffer */
++ u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
++
++ /* Set 48000Hz sample rate */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
++
++ /* Deactivate Tuner */
++ /* on = 0x01*/
++ /* off = 0x00*/
++ com_buff[0] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
++
++ /* Set clock source to Internal (as opposed to S/PDIF) */
++ com_buff[0] = 0x01;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0100, 0x8001, &com_buff, 1);
++
++ /* Mute the hardware loopbacks to start the device in a known state. */
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* Analogue input 1 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0110, 0x4001, &com_buff, 2);
++ /* Analogue input 1 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0111, 0x4001, &com_buff, 2);
++ /* Analogue input 2 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0114, 0x4001, &com_buff, 2);
++ /* Analogue input 2 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0115, 0x4001, &com_buff, 2);
++ /* Analogue input 3 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0118, 0x4001, &com_buff, 2);
++ /* Analogue input 3 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0119, 0x4001, &com_buff, 2);
++ /* Analogue input 4 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011c, 0x4001, &com_buff, 2);
++ /* Analogue input 4 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011d, 0x4001, &com_buff, 2);
++
++ /* Set software sends to output */
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x00;
++ /* Analogue software return 1 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0100, 0x4001, &com_buff, 2);
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* Analogue software return 1 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0101, 0x4001, &com_buff, 2);
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* Analogue software return 2 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0104, 0x4001, &com_buff, 2);
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x00;
++ /* Analogue software return 2 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0105, 0x4001, &com_buff, 2);
++
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* Analogue software return 3 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0108, 0x4001, &com_buff, 2);
++ /* Analogue software return 3 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0109, 0x4001, &com_buff, 2);
++ /* Analogue software return 4 left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010c, 0x4001, &com_buff, 2);
++ /* Analogue software return 4 right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010d, 0x4001, &com_buff, 2);
++
++ /* Return to muting sends */
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* Analogue fx return left channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0120, 0x4001, &com_buff, 2);
++ /* Analogue fx return right channel: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0121, 0x4001, &com_buff, 2);
++
++ /* Analogue software input 1 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0100, 0x4201, &com_buff, 2);
++ /* Analogue software input 2 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0101, 0x4201, &com_buff, 2);
++ /* Analogue software input 3 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0102, 0x4201, &com_buff, 2);
++ /* Analogue software input 4 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0103, 0x4201, &com_buff, 2);
++ /* Analogue input 1 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0104, 0x4201, &com_buff, 2);
++ /* Analogue input 2 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0105, 0x4201, &com_buff, 2);
++ /* Analogue input 3 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0106, 0x4201, &com_buff, 2);
++ /* Analogue input 4 fx send: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0107, 0x4201, &com_buff, 2);
++
++ /* Toggle allowing host control */
++ com_buff[0] = 0x02;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 3, 0x21, 0x0000, 0x2001, &com_buff, 1);
++
++ /* Do not dim fx returns */
++ com_buff[0] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 3, 0x21, 0x0002, 0x2001, &com_buff, 1);
++
++ /* Do not set fx returns to mono */
++ com_buff[0] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 3, 0x21, 0x0001, 0x2001, &com_buff, 1);
++
++ /* Mute the S/PDIF hardware loopback
++ * same odd volume logic here as above
++ */
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* S/PDIF hardware input 1 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0112, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 1 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0113, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 2 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0116, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 2 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0117, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 3 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011a, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 3 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011b, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 4 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011e, 0x4001, &com_buff, 2);
++ /* S/PDIF hardware input 4 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x011f, 0x4001, &com_buff, 2);
++ /* S/PDIF software return 1 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0102, 0x4001, &com_buff, 2);
++ /* S/PDIF software return 1 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0103, 0x4001, &com_buff, 2);
++ /* S/PDIF software return 2 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0106, 0x4001, &com_buff, 2);
++ /* S/PDIF software return 2 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0107, 0x4001, &com_buff, 2);
++
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x00;
++ /* S/PDIF software return 3 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010a, 0x4001, &com_buff, 2);
++
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* S/PDIF software return 3 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010b, 0x4001, &com_buff, 2);
++ /* S/PDIF software return 4 left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010e, 0x4001, &com_buff, 2);
++
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x00;
++ /* S/PDIF software return 4 right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x010f, 0x4001, &com_buff, 2);
++
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x80;
++ /* S/PDIF fx returns left channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0122, 0x4001, &com_buff, 2);
++ /* S/PDIF fx returns right channel */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0123, 0x4001, &com_buff, 2);
++
++ /* Set the dropdown "Effect" to the first option */
++ /* Room1 = 0x00 */
++ /* Room2 = 0x01 */
++ /* Room3 = 0x02 */
++ /* Hall 1 = 0x03 */
++ /* Hall 2 = 0x04 */
++ /* Plate = 0x05 */
++ /* Delay = 0x06 */
++ /* Echo = 0x07 */
++ com_buff[0] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */
++ /* min is 0x00 */
++
++
++ /* Set the effect duration to 0 */
++ /* max is 0xffff */
++ /* min is 0x0000 */
++ com_buff[0] = 0x00;
++ com_buff[1] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0400, 0x4301, &com_buff, 2);
++
++ /* Set the effect volume and feedback to 0 */
++ /* max is 0xff */
++ /* min is 0x00 */
++ com_buff[0] = 0x00;
++ /* feedback: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0500, 0x4301, &com_buff, 1);
++ /* volume: */
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 1, 0x21, 0x0300, 0x4301, &com_buff, 1);
++
++ /* Set soft button hold duration */
++ /* 0x03 = 250ms */
++ /* 0x05 = 500ms DEFAULT */
++ /* 0x08 = 750ms */
++ /* 0x0a = 1sec */
++ com_buff[0] = 0x05;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 3, 0x21, 0x0005, 0x2001, &com_buff, 1);
++
++ /* Use dim LEDs for button of state */
++ com_buff[0] = 0x00;
++ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++ 3, 0x21, 0x0004, 0x2001, &com_buff, 1);
++}
++
++#define MBOX3_DESCRIPTOR_SIZE 464
++
++static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
++{
++ struct usb_host_config *config = dev->actconfig;
++ int err;
++ int descriptor_size;
++
++ descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
++
++ if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
++ dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
++ return -ENODEV;
++ }
++
++ dev_dbg(&dev->dev, "device initialised!\n");
++
++ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
++ &dev->descriptor, sizeof(dev->descriptor));
++ config = dev->actconfig;
++ if (err < 0)
++ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
++
++ err = usb_reset_configuration(dev);
++ if (err < 0)
++ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
++ dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
++ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
++
++ mbox3_setup_48_24_magic(dev);
++ dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
++
++ return 0; /* Successful boot */
++}
+
+ #define MICROBOOK_BUF_SIZE 128
+
+@@ -1324,6 +1622,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
+ case USB_ID(0x0dba, 0x3000):
+ /* Digidesign Mbox 2 */
+ return snd_usb_mbox2_boot_quirk(dev);
++ case USB_ID(0x0dba, 0x5000):
++ /* Digidesign Mbox 3 */
++ return snd_usb_mbox3_boot_quirk(dev);
++
+
+ case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
+ case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
+@@ -1728,48 +2030,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+ }
+ }
+
+-/*
+- * registration quirk:
+- * the registration is skipped if a device matches with the given ID,
+- * unless the interface reaches to the defined one. This is for delaying
+- * the registration until the last known interface, so that the card and
+- * devices appear at the same time.
+- */
+-
+-struct registration_quirk {
+- unsigned int usb_id; /* composed via USB_ID() */
+- unsigned int interface; /* the interface to trigger register */
+-};
+-
+-#define REG_QUIRK_ENTRY(vendor, product, iface) \
+- { .usb_id = USB_ID(vendor, product), .interface = (iface) }
+-
+-static const struct registration_quirk registration_quirks[] = {
+- REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */
+- REG_QUIRK_ENTRY(0x0951, 0x16ed, 2), /* Kingston HyperX Cloud Alpha S */
+- REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */
+- REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */
+- REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2), /* JBL Quantum 800 */
+- REG_QUIRK_ENTRY(0x0ecb, 0x1f4c, 2), /* JBL Quantum 400 */
+- REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */
+- REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */
+- REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */
+- { 0 } /* terminator */
+-};
+-
+-/* return true if skipping registration */
+-bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface)
+-{
+- const struct registration_quirk *q;
+-
+- for (q = registration_quirks; q->usb_id; q++)
+- if (chip->usb_id == q->usb_id)
+- return iface < q->interface;
+-
+- /* Register as normal */
+- return false;
+-}
+-
+ /*
+ * driver behavior quirk flags
+ */
+diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
+index 31abb7cb01a52..f9bfd5ac7bab0 100644
+--- a/sound/usb/quirks.h
++++ b/sound/usb/quirks.h
+@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ int stream);
+
+-bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface);
+-
+ void snd_usb_init_quirk_flags(struct snd_usb_audio *chip);
+
+ #endif /* __USBAUDIO_QUIRKS_H */
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index ffbb4b0d09a07..2c6575029b1cd 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -37,6 +37,7 @@ struct snd_usb_audio {
+ unsigned int quirk_flags;
+ unsigned int need_delayed_register:1; /* warn for delayed registration */
+ int num_interfaces;
++ int last_iface;
+ int num_suspended_intf;
+ int sample_rate_read_error;
+
+diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
+index 125798b0bc5dd..19924b6ce796f 100644
+--- a/tools/bpf/bpftool/btf_dumper.c
++++ b/tools/bpf/bpftool/btf_dumper.c
+@@ -452,7 +452,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
+ *(char *)data);
+ break;
+ case BTF_INT_BOOL:
+- jsonw_bool(jw, *(int *)data);
++ jsonw_bool(jw, *(bool *)data);
+ break;
+ default:
+ /* shouldn't happen */
+diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
+index cced668fb2a3c..b46a998d8f8df 100644
+--- a/tools/bpf/bpftool/cgroup.c
++++ b/tools/bpf/bpftool/cgroup.c
+@@ -136,8 +136,8 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,
+ jsonw_string_field(json_wtr, "attach_type", attach_type_str);
+ else
+ jsonw_uint_field(json_wtr, "attach_type", attach_type);
+- jsonw_string_field(json_wtr, "attach_flags",
+- attach_flags_str);
++ if (!(query_flags & BPF_F_QUERY_EFFECTIVE))
++ jsonw_string_field(json_wtr, "attach_flags", attach_flags_str);
+ jsonw_string_field(json_wtr, "name", prog_name);
+ if (attach_btf_name)
+ jsonw_string_field(json_wtr, "attach_btf_name", attach_btf_name);
+@@ -150,7 +150,10 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,
+ printf("%-15s", attach_type_str);
+ else
+ printf("type %-10u", attach_type);
+- printf(" %-15s %-15s", attach_flags_str, prog_name);
++ if (query_flags & BPF_F_QUERY_EFFECTIVE)
++ printf(" %-15s", prog_name);
++ else
++ printf(" %-15s %-15s", attach_flags_str, prog_name);
+ if (attach_btf_name)
+ printf(" %-15s", attach_btf_name);
+ else if (info.attach_btf_id)
+@@ -195,6 +198,32 @@ static int cgroup_has_attached_progs(int cgroup_fd)
+
+ return no_prog ? 0 : 1;
+ }
++
++static int show_effective_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
++ int level)
++{
++ LIBBPF_OPTS(bpf_prog_query_opts, p);
++ __u32 prog_ids[1024] = {0};
++ __u32 iter;
++ int ret;
++
++ p.query_flags = query_flags;
++ p.prog_cnt = ARRAY_SIZE(prog_ids);
++ p.prog_ids = prog_ids;
++
++ ret = bpf_prog_query_opts(cgroup_fd, type, &p);
++ if (ret)
++ return ret;
++
++ if (p.prog_cnt == 0)
++ return 0;
++
++ for (iter = 0; iter < p.prog_cnt; iter++)
++ show_bpf_prog(prog_ids[iter], type, NULL, level);
++
++ return 0;
++}
++
+ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
+ int level)
+ {
+@@ -245,6 +274,14 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
+ return 0;
+ }
+
++static int show_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
++ int level)
++{
++ return query_flags & BPF_F_QUERY_EFFECTIVE ?
++ show_effective_bpf_progs(cgroup_fd, type, level) :
++ show_attached_bpf_progs(cgroup_fd, type, level);
++}
++
+ static int do_show(int argc, char **argv)
+ {
+ enum bpf_attach_type type;
+@@ -292,6 +329,8 @@ static int do_show(int argc, char **argv)
+
+ if (json_output)
+ jsonw_start_array(json_wtr);
++ else if (query_flags & BPF_F_QUERY_EFFECTIVE)
++ printf("%-8s %-15s %-15s\n", "ID", "AttachType", "Name");
+ else
+ printf("%-8s %-15s %-15s %-15s\n", "ID", "AttachType",
+ "AttachFlags", "Name");
+@@ -304,7 +343,7 @@ static int do_show(int argc, char **argv)
+ * If we were able to get the show for at least one
+ * attach type, let's return 0.
+ */
+- if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0)
++ if (show_bpf_progs(cgroup_fd, type, 0) == 0)
+ ret = 0;
+ }
+
+@@ -362,7 +401,7 @@ static int do_show_tree_fn(const char *fpath, const struct stat *sb,
+
+ btf_vmlinux = libbpf_find_kernel_btf();
+ for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
+- show_attached_bpf_progs(cgroup_fd, type, ftw->level);
++ show_bpf_progs(cgroup_fd, type, ftw->level);
+
+ if (errno == EINVAL)
+ /* Last attach type does not support query.
+@@ -436,6 +475,11 @@ static int do_show_tree(int argc, char **argv)
+
+ if (json_output)
+ jsonw_start_array(json_wtr);
++ else if (query_flags & BPF_F_QUERY_EFFECTIVE)
++ printf("%s\n"
++ "%-8s %-15s %-15s\n",
++ "CgroupPath",
++ "ID", "AttachType", "Name");
+ else
+ printf("%s\n"
+ "%-8s %-15s %-15s %-15s\n",
+diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
+index 451cefc2d0da9..ccd7457f92bff 100644
+--- a/tools/bpf/bpftool/main.c
++++ b/tools/bpf/bpftool/main.c
+@@ -435,6 +435,16 @@ int main(int argc, char **argv)
+
+ setlinebuf(stdout);
+
++#ifdef USE_LIBCAP
++ /* Libcap < 2.63 hooks before main() to compute the number of
++ * capabilities of the running kernel, and doing so it calls prctl()
++ * which may fail and set errno to non-zero.
++ * Let's reset errno to make sure this does not interfere with the
++ * batch mode.
++ */
++ errno = 0;
++#endif
++
+ last_do_help = do_help;
+ pretty_output = false;
+ json_output = false;
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index 59a217ca2dfd3..4eff7fc7ae586 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -1233,7 +1233,7 @@ enum {
+
+ /* Query effective (directly attached + inherited from ancestor cgroups)
+ * programs that will be executed for events within a cgroup.
+- * attach_flags with this flag are returned only for directly attached programs.
++ * attach_flags with this flag are always returned 0.
+ */
+ #define BPF_F_QUERY_EFFECTIVE (1U << 0)
+
+@@ -1432,7 +1432,10 @@ union bpf_attr {
+ __u32 attach_flags;
+ __aligned_u64 prog_ids;
+ __u32 prog_cnt;
+- __aligned_u64 prog_attach_flags; /* output: per-program attach_flags */
++ /* output: per-program attach_flags.
++ * not allowed to be set during effective query.
++ */
++ __aligned_u64 prog_attach_flags;
+ } query;
+
+ struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index 43ca3aff2292f..5fdb93da423b5 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -426,7 +426,7 @@ struct pt_regs;
+ */
+ #define BPF_PROG(name, args...) \
+ name(unsigned long long *ctx); \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(unsigned long long *ctx, ##args); \
+ typeof(name(0)) name(unsigned long long *ctx) \
+ { \
+@@ -435,7 +435,7 @@ typeof(name(0)) name(unsigned long long *ctx) \
+ return ____##name(___bpf_ctx_cast(args)); \
+ _Pragma("GCC diagnostic pop") \
+ } \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(unsigned long long *ctx, ##args)
+
+ struct pt_regs;
+@@ -460,7 +460,7 @@ struct pt_regs;
+ */
+ #define BPF_KPROBE(name, args...) \
+ name(struct pt_regs *ctx); \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args); \
+ typeof(name(0)) name(struct pt_regs *ctx) \
+ { \
+@@ -469,7 +469,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
+ return ____##name(___bpf_kprobe_args(args)); \
+ _Pragma("GCC diagnostic pop") \
+ } \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args)
+
+ #define ___bpf_kretprobe_args0() ctx
+@@ -484,7 +484,7 @@ ____##name(struct pt_regs *ctx, ##args)
+ */
+ #define BPF_KRETPROBE(name, args...) \
+ name(struct pt_regs *ctx); \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args); \
+ typeof(name(0)) name(struct pt_regs *ctx) \
+ { \
+@@ -540,7 +540,7 @@ static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
+ #define BPF_KSYSCALL(name, args...) \
+ name(struct pt_regs *ctx); \
+ extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args); \
+ typeof(name(0)) name(struct pt_regs *ctx) \
+ { \
+@@ -555,7 +555,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
+ return ____##name(___bpf_syscall_args(args)); \
+ _Pragma("GCC diagnostic pop") \
+ } \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args)
+
+ #define BPF_KPROBE_SYSCALL BPF_KSYSCALL
+diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
+index 583760df83b42..d421d656a0765 100644
+--- a/tools/lib/bpf/btf.h
++++ b/tools/lib/bpf/btf.h
+@@ -487,6 +487,8 @@ static inline struct btf_enum *btf_enum(const struct btf_type *t)
+ return (struct btf_enum *)(t + 1);
+ }
+
++struct btf_enum64;
++
+ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
+ {
+ return (struct btf_enum64 *)(t + 1);
+@@ -494,7 +496,28 @@ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
+
+ static inline __u64 btf_enum64_value(const struct btf_enum64 *e)
+ {
+- return ((__u64)e->val_hi32 << 32) | e->val_lo32;
++ /* struct btf_enum64 is introduced in Linux 6.0, which is very
++ * bleeding-edge. Here we are avoiding relying on struct btf_enum64
++ * definition coming from kernel UAPI headers to support wider range
++ * of system-wide kernel headers.
++ *
++ * Given this header can be also included from C++ applications, that
++ * further restricts C tricks we can use (like using compatible
++ * anonymous struct). So just treat struct btf_enum64 as
++ * a three-element array of u32 and access second (lo32) and third
++ * (hi32) elements directly.
++ *
++ * For reference, here is a struct btf_enum64 definition:
++ *
++ * const struct btf_enum64 {
++ * __u32 name_off;
++ * __u32 val_lo32;
++ * __u32 val_hi32;
++ * };
++ */
++ const __u32 *e64 = (const __u32 *)e;
++
++ return ((__u64)e64[2] << 32) | e64[1];
+ }
+
+ static inline struct btf_member *btf_members(const struct btf_type *t)
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 627edb5bb6def..4221f73a74d01 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -2385,7 +2385,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
+ d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
+
+ /* default indent string is a tab */
+- if (!opts->indent_str)
++ if (!OPTS_GET(opts, indent_str, NULL))
+ d->typed_dump->indent_str[0] = '\t';
+ else
+ libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str,
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 50d41815f431a..e36c44090720e 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -9056,11 +9056,15 @@ static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
+ int err = 0;
+
+ /* BPF program's BTF ID */
+- if (attach_prog_fd) {
++ if (prog->type == BPF_PROG_TYPE_EXT || attach_prog_fd) {
++ if (!attach_prog_fd) {
++ pr_warn("prog '%s': attach program FD is not set\n", prog->name);
++ return -EINVAL;
++ }
+ err = libbpf_find_prog_btf_id(attach_name, attach_prog_fd);
+ if (err < 0) {
+- pr_warn("failed to find BPF program (FD %d) BTF ID for '%s': %d\n",
+- attach_prog_fd, attach_name, err);
++ pr_warn("prog '%s': failed to find BPF program (FD %d) BTF ID for '%s': %d\n",
++ prog->name, attach_prog_fd, attach_name, err);
+ return err;
+ }
+ *btf_obj_fd = 0;
+@@ -9077,7 +9081,8 @@ static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
+ err = find_kernel_btf_id(prog->obj, attach_name, attach_type, btf_obj_fd, btf_type_id);
+ }
+ if (err) {
+- pr_warn("failed to find kernel BTF type ID of '%s': %d\n", attach_name, err);
++ pr_warn("prog '%s': failed to find kernel BTF type ID of '%s': %d\n",
++ prog->name, attach_name, err);
+ return err;
+ }
+ return 0;
+@@ -10662,15 +10667,17 @@ static const char *arch_specific_lib_paths(void)
+ static int resolve_full_path(const char *file, char *result, size_t result_sz)
+ {
+ const char *search_paths[3] = {};
+- int i;
++ int i, perm;
+
+ if (str_has_sfx(file, ".so") || strstr(file, ".so.")) {
+ search_paths[0] = getenv("LD_LIBRARY_PATH");
+ search_paths[1] = "/usr/lib64:/usr/lib";
+ search_paths[2] = arch_specific_lib_paths();
++ perm = R_OK;
+ } else {
+ search_paths[0] = getenv("PATH");
+ search_paths[1] = "/usr/bin:/usr/sbin";
++ perm = R_OK | X_OK;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(search_paths); i++) {
+@@ -10689,8 +10696,8 @@ static int resolve_full_path(const char *file, char *result, size_t result_sz)
+ if (!seg_len)
+ continue;
+ snprintf(result, result_sz, "%.*s/%s", seg_len, s, file);
+- /* ensure it is an executable file/link */
+- if (access(result, R_OK | X_OK) < 0)
++ /* ensure it has required permissions */
++ if (access(result, perm) < 0)
+ continue;
+ pr_debug("resolved '%s' to '%s'\n", file, result);
+ return 0;
+diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
+index 61493c4cddac1..9f956e6058ed9 100644
+--- a/tools/lib/bpf/libbpf.h
++++ b/tools/lib/bpf/libbpf.h
+@@ -118,7 +118,9 @@ struct bpf_object_open_opts {
+ * auto-pinned to that path on load; defaults to "/sys/fs/bpf".
+ */
+ const char *pin_root_path;
+- long :0;
++
++ __u32 :32; /* stub out now removed attach_prog_fd */
++
+ /* Additional kernel config content that augments and overrides
+ * system Kconfig for CONFIG_xxx externs.
+ */
+diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
+index 0b5398786bf3d..6d495656f554c 100644
+--- a/tools/lib/bpf/libbpf_probes.c
++++ b/tools/lib/bpf/libbpf_probes.c
+@@ -193,7 +193,7 @@ static int probe_map_create(enum bpf_map_type map_type)
+ LIBBPF_OPTS(bpf_map_create_opts, opts);
+ int key_size, value_size, max_entries;
+ __u32 btf_key_type_id = 0, btf_value_type_id = 0;
+- int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err;
++ int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err = 0;
+
+ key_size = sizeof(__u32);
+ value_size = sizeof(__u32);
+diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
+index f57e77a6e40fd..3900d052ed19e 100644
+--- a/tools/lib/bpf/nlattr.c
++++ b/tools/lib/bpf/nlattr.c
+@@ -32,7 +32,7 @@ static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
+
+ static int nla_ok(const struct nlattr *nla, int remaining)
+ {
+- return remaining >= sizeof(*nla) &&
++ return remaining >= (int)sizeof(*nla) &&
+ nla->nla_len >= sizeof(*nla) &&
+ nla->nla_len <= remaining;
+ }
+diff --git a/tools/lib/bpf/usdt.bpf.h b/tools/lib/bpf/usdt.bpf.h
+index 4f2adc0bd6ca3..fdfd235e52c42 100644
+--- a/tools/lib/bpf/usdt.bpf.h
++++ b/tools/lib/bpf/usdt.bpf.h
+@@ -232,7 +232,7 @@ long bpf_usdt_cookie(struct pt_regs *ctx)
+ */
+ #define BPF_USDT(name, args...) \
+ name(struct pt_regs *ctx); \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args); \
+ typeof(name(0)) name(struct pt_regs *ctx) \
+ { \
+@@ -241,7 +241,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
+ return ____##name(___bpf_usdt_args(args)); \
+ _Pragma("GCC diagnostic pop") \
+ } \
+-static __attribute__((always_inline)) typeof(name(0)) \
++static __always_inline typeof(name(0)) \
+ ____##name(struct pt_regs *ctx, ##args)
+
+ #endif /* __USDT_BPF_H__ */
+diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
+index c25e957c1e520..7e24b09b1163a 100644
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -619,6 +619,11 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
+ Elf64_Xword entsize = symtab->sh.sh_entsize;
+ int max_idx, idx = sym->idx;
+ Elf_Scn *s, *t = NULL;
++ bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE &&
++ sym->sym.st_shndx != SHN_XINDEX;
++
++ if (is_special_shndx)
++ shndx = sym->sym.st_shndx;
+
+ s = elf_getscn(elf->elf, symtab->idx);
+ if (!s) {
+@@ -704,7 +709,7 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
+ }
+
+ /* setup extended section index magic and write the symbol */
+- if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
++ if ((shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) || is_special_shndx) {
+ sym->sym.st_shndx = shndx;
+ if (!shndx_data)
+ shndx = 0;
+diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
+index 13933020a79eb..12f271ae2ddd2 100644
+--- a/tools/perf/arch/x86/util/intel-pt.c
++++ b/tools/perf/arch/x86/util/intel-pt.c
+@@ -871,7 +871,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
+ * User space tasks can migrate between CPUs, so when tracing
+ * selected CPUs, sideband for all CPUs is still needed.
+ */
+- need_system_wide_tracking = evlist->core.has_user_cpus &&
++ need_system_wide_tracking = opts->target.cpu_list &&
+ !intel_pt_evsel->core.attr.exclude_user;
+
+ tracking_evsel = evlist__add_aux_dummy(evlist, need_system_wide_tracking);
+diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
+index d5e9fc8106dd8..48b9ddd0c5c5c 100644
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -4033,6 +4033,7 @@ static const char * const intel_pt_info_fmts[] = {
+ [INTEL_PT_SNAPSHOT_MODE] = " Snapshot mode %"PRId64"\n",
+ [INTEL_PT_PER_CPU_MMAPS] = " Per-cpu maps %"PRId64"\n",
+ [INTEL_PT_MTC_BIT] = " MTC bit %#"PRIx64"\n",
++ [INTEL_PT_MTC_FREQ_BITS] = " MTC freq bits %#"PRIx64"\n",
+ [INTEL_PT_TSC_CTC_N] = " TSC:CTC numerator %"PRIu64"\n",
+ [INTEL_PT_TSC_CTC_D] = " TSC:CTC denominator %"PRIu64"\n",
+ [INTEL_PT_CYC_BIT] = " CYC bit %#"PRIx64"\n",
+@@ -4047,8 +4048,12 @@ static void intel_pt_print_info(__u64 *arr, int start, int finish)
+ if (!dump_trace)
+ return;
+
+- for (i = start; i <= finish; i++)
+- fprintf(stdout, intel_pt_info_fmts[i], arr[i]);
++ for (i = start; i <= finish; i++) {
++ const char *fmt = intel_pt_info_fmts[i];
++
++ if (fmt)
++ fprintf(stdout, fmt, arr[i]);
++ }
+ }
+
+ static void intel_pt_print_info_str(const char *name, const char *str)
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index f3b2c2a87456b..c1c57165bf9fc 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -254,6 +254,9 @@ __add_event(struct list_head *list, int *idx,
+ struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
+ cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
+
++ if (pmu)
++ perf_pmu__warn_invalid_formats(pmu);
++
+ if (pmu && attr->type == PERF_TYPE_RAW)
+ perf_pmu__warn_invalid_config(pmu, attr->config, name);
+
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index 89655d53117ae..82455b073c2f2 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -1005,6 +1005,23 @@ err:
+ return NULL;
+ }
+
++void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
++{
++ struct perf_pmu_format *format;
++
++ /* fake pmu doesn't have format list */
++ if (pmu == &perf_pmu__fake)
++ return;
++
++ list_for_each_entry(format, &pmu->format, list)
++ if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) {
++ pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'"
++ "which is not supported by this version of perf!\n",
++ pmu->name, format->name, format->value);
++ return;
++ }
++}
++
+ static struct perf_pmu *pmu_find(const char *name)
+ {
+ struct perf_pmu *pmu;
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index a7b0f9507510b..68e15c38ae710 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -17,6 +17,7 @@ enum {
+ PERF_PMU_FORMAT_VALUE_CONFIG,
+ PERF_PMU_FORMAT_VALUE_CONFIG1,
+ PERF_PMU_FORMAT_VALUE_CONFIG2,
++ PERF_PMU_FORMAT_VALUE_CONFIG_END,
+ };
+
+ #define PERF_PMU_FORMAT_BITS 64
+@@ -139,6 +140,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
+
+ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
+ const char *name);
++void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
+
+ bool perf_pmu__has_hybrid(void);
+ int perf_pmu__match(char *pattern, char *name, char *tok);
+diff --git a/tools/perf/util/pmu.l b/tools/perf/util/pmu.l
+index a15d9fbd7c0ed..58b4926cfaca9 100644
+--- a/tools/perf/util/pmu.l
++++ b/tools/perf/util/pmu.l
+@@ -27,8 +27,6 @@ num_dec [0-9]+
+
+ {num_dec} { return value(10); }
+ config { return PP_CONFIG; }
+-config1 { return PP_CONFIG1; }
+-config2 { return PP_CONFIG2; }
+ - { return '-'; }
+ : { return ':'; }
+ , { return ','; }
+diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y
+index bfd7e8509869b..283efe059819d 100644
+--- a/tools/perf/util/pmu.y
++++ b/tools/perf/util/pmu.y
+@@ -20,7 +20,7 @@ do { \
+
+ %}
+
+-%token PP_CONFIG PP_CONFIG1 PP_CONFIG2
++%token PP_CONFIG
+ %token PP_VALUE PP_ERROR
+ %type <num> PP_VALUE
+ %type <bits> bit_term
+@@ -47,18 +47,11 @@ PP_CONFIG ':' bits
+ $3));
+ }
+ |
+-PP_CONFIG1 ':' bits
++PP_CONFIG PP_VALUE ':' bits
+ {
+ ABORT_ON(perf_pmu__new_format(format, name,
+- PERF_PMU_FORMAT_VALUE_CONFIG1,
+- $3));
+-}
+-|
+-PP_CONFIG2 ':' bits
+-{
+- ABORT_ON(perf_pmu__new_format(format, name,
+- PERF_PMU_FORMAT_VALUE_CONFIG2,
+- $3));
++ $2,
++ $4));
+ }
+
+ bits:
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index 831dc32d45fad..b7d2a0cd0ac28 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -4560,7 +4560,6 @@ static double rapl_dram_energy_units_probe(int model, double rapl_energy_units)
+ case INTEL_FAM6_SKYLAKE_X: /* SKX */
+ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
+ case INTEL_FAM6_ICELAKE_X: /* ICX */
+- case INTEL_FAM6_SAPPHIRERAPIDS_X: /* SPR */
+ return (rapl_dram_energy_units = 15.3 / 1000000);
+ default:
+ return (rapl_energy_units);
+diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
+index 84c36bee4d82a..d98828cb542be 100644
+--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
++++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
+@@ -33,7 +33,7 @@ bool validate_extra_context(struct extra_context *extra, char **err)
+ return false;
+
+ fprintf(stderr, "Validating EXTRA...\n");
+- term = GET_RESV_NEXT_HEAD(extra);
++ term = GET_RESV_NEXT_HEAD(&extra->head);
+ if (!term || term->magic || term->size) {
+ *err = "Missing terminator after EXTRA context";
+ return false;
+diff --git a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
+index 78c76496b14ad..b595556315bc3 100644
+--- a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
++#include <unistd.h>
+
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -137,6 +138,7 @@ static void __test_map_lookup_and_update_batch(bool is_pcpu)
+ free(keys);
+ free(values);
+ free(visited);
++ close(map_fd);
+ }
+
+ static void array_map_batch_ops(void)
+diff --git a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
+index f807d53fd8dd4..1230ccf901280 100644
+--- a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
++#include <unistd.h>
+
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -255,6 +256,7 @@ void __test_map_lookup_and_delete_batch(bool is_pcpu)
+ free(visited);
+ if (!is_pcpu)
+ free(values);
++ close(map_fd);
+ }
+
+ void htab_map_batch_ops(void)
+diff --git a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
+index 87d07b596e170..b66d56ddb7ef2 100644
+--- a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
+@@ -7,6 +7,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <unistd.h>
+
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -150,4 +151,5 @@ void test_lpm_trie_map_batch_ops(void)
+ free(keys);
+ free(values);
+ free(visited);
++ close(map_fd);
+ }
+diff --git a/tools/testing/selftests/bpf/prog_tests/cgroup_link.c b/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
+index 9e6e6aad347c7..15093a69510eb 100644
+--- a/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
++++ b/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
+@@ -71,10 +71,9 @@ void serial_test_cgroup_link(void)
+
+ ping_and_check(cg_nr, 0);
+
+- /* query the number of effective progs and attach flags in root cg */
++ /* query the number of attached progs and attach flags in root cg */
+ err = bpf_prog_query(cgs[0].fd, BPF_CGROUP_INET_EGRESS,
+- BPF_F_QUERY_EFFECTIVE, &attach_flags, NULL,
+- &prog_cnt);
++ 0, &attach_flags, NULL, &prog_cnt);
+ CHECK_FAIL(err);
+ CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ if (CHECK(prog_cnt != 1, "effect_cnt", "exp %d, got %d\n", 1, prog_cnt))
+@@ -85,17 +84,15 @@ void serial_test_cgroup_link(void)
+ BPF_F_QUERY_EFFECTIVE, NULL, NULL,
+ &prog_cnt);
+ CHECK_FAIL(err);
+- CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
+ cg_nr, prog_cnt))
+ goto cleanup;
+
+ /* query the effective prog IDs in last cg */
+ err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
+- BPF_F_QUERY_EFFECTIVE, &attach_flags,
+- prog_ids, &prog_cnt);
++ BPF_F_QUERY_EFFECTIVE, NULL, prog_ids,
++ &prog_cnt);
+ CHECK_FAIL(err);
+- CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
+ cg_nr, prog_cnt))
+ goto cleanup;
+diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+index 08f95a8155d1b..98c3399e15c03 100644
+--- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
++++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+@@ -36,15 +36,13 @@ __u64 kretprobe_test6_result = 0;
+ __u64 kretprobe_test7_result = 0;
+ __u64 kretprobe_test8_result = 0;
+
+-extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak;
+-
+ static void kprobe_multi_check(void *ctx, bool is_return)
+ {
+ if (bpf_get_current_pid_tgid() >> 32 != pid)
+ return;
+
+ __u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
+- __u64 addr = bpf_get_func_ip(ctx) - (CONFIG_X86_KERNEL_IBT ? 4 : 0);
++ __u64 addr = bpf_get_func_ip(ctx);
+
+ #define SET(__var, __addr, __cookie) ({ \
+ if (((const void *) addr == __addr) && \
+diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
+index cbebfaa7c1e82..4d42ffea00388 100644
+--- a/tools/testing/selftests/bpf/test_maps.c
++++ b/tools/testing/selftests/bpf/test_maps.c
+@@ -658,13 +658,13 @@ static void test_sockmap(unsigned int tasks, void *data)
+ {
+ struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
+ int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
++ struct bpf_object *parse_obj, *verdict_obj, *msg_obj;
+ int ports[] = {50200, 50201, 50202, 50204};
+ int err, i, fd, udp, sfd[6] = {0xdeadbeef};
+ u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
+ int parse_prog, verdict_prog, msg_prog;
+ struct sockaddr_in addr;
+ int one = 1, s, sc, rc;
+- struct bpf_object *obj;
+ struct timeval to;
+ __u32 key, value;
+ pid_t pid[tasks];
+@@ -760,6 +760,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ i, udp);
+ goto out_sockmap;
+ }
++ close(udp);
+
+ /* Test update without programs */
+ for (i = 0; i < 6; i++) {
+@@ -822,27 +823,27 @@ static void test_sockmap(unsigned int tasks, void *data)
+
+ /* Load SK_SKB program and Attach */
+ err = bpf_prog_test_load(SOCKMAP_PARSE_PROG,
+- BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
++ BPF_PROG_TYPE_SK_SKB, &parse_obj, &parse_prog);
+ if (err) {
+ printf("Failed to load SK_SKB parse prog\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_test_load(SOCKMAP_TCP_MSG_PROG,
+- BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
++ BPF_PROG_TYPE_SK_MSG, &msg_obj, &msg_prog);
+ if (err) {
+ printf("Failed to load SK_SKB msg prog\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_test_load(SOCKMAP_VERDICT_PROG,
+- BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
++ BPF_PROG_TYPE_SK_SKB, &verdict_obj, &verdict_prog);
+ if (err) {
+ printf("Failed to load SK_SKB verdict prog\n");
+ goto out_sockmap;
+ }
+
+- bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
++ bpf_map_rx = bpf_object__find_map_by_name(verdict_obj, "sock_map_rx");
+ if (!bpf_map_rx) {
+ printf("Failed to load map rx from verdict prog\n");
+ goto out_sockmap;
+@@ -854,7 +855,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ goto out_sockmap;
+ }
+
+- bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
++ bpf_map_tx = bpf_object__find_map_by_name(verdict_obj, "sock_map_tx");
+ if (!bpf_map_tx) {
+ printf("Failed to load map tx from verdict prog\n");
+ goto out_sockmap;
+@@ -866,7 +867,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ goto out_sockmap;
+ }
+
+- bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
++ bpf_map_msg = bpf_object__find_map_by_name(verdict_obj, "sock_map_msg");
+ if (!bpf_map_msg) {
+ printf("Failed to load map msg from msg_verdict prog\n");
+ goto out_sockmap;
+@@ -878,7 +879,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ goto out_sockmap;
+ }
+
+- bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
++ bpf_map_break = bpf_object__find_map_by_name(verdict_obj, "sock_map_break");
+ if (!bpf_map_break) {
+ printf("Failed to load map tx from verdict prog\n");
+ goto out_sockmap;
+@@ -1124,7 +1125,9 @@ static void test_sockmap(unsigned int tasks, void *data)
+ }
+ close(fd);
+ close(map_fd_rx);
+- bpf_object__close(obj);
++ bpf_object__close(parse_obj);
++ bpf_object__close(msg_obj);
++ bpf_object__close(verdict_obj);
+ return;
+ out:
+ for (i = 0; i < 6; i++)
+@@ -1282,8 +1285,11 @@ static void test_map_in_map(void)
+ printf("Inner map mim.inner was not destroyed\n");
+ goto out_map_in_map;
+ }
++
++ close(fd);
+ }
+
++ bpf_object__close(obj);
+ return;
+
+ out_map_in_map:
+diff --git a/tools/testing/selftests/bpf/xsk.c b/tools/testing/selftests/bpf/xsk.c
+index f2721a4ae7c50..0b3ff49c740d4 100644
+--- a/tools/testing/selftests/bpf/xsk.c
++++ b/tools/testing/selftests/bpf/xsk.c
+@@ -1237,15 +1237,15 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+ ctx = xsk->ctx;
+ umem = ctx->umem;
+
+- xsk_put_ctx(ctx, true);
+-
+- if (!ctx->refcount) {
++ if (ctx->refcount == 1) {
+ xsk_delete_bpf_maps(xsk);
+ close(ctx->prog_fd);
+ if (ctx->has_bpf_link)
+ close(ctx->link_fd);
+ }
+
++ xsk_put_ctx(ctx, true);
++
+ err = xsk_get_mmap_offsets(xsk->fd, &off);
+ if (!err) {
+ if (xsk->rx) {
+diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
+index 74d56d971bafc..091402dc53908 100644
+--- a/tools/testing/selftests/bpf/xskxceiver.c
++++ b/tools/testing/selftests/bpf/xskxceiver.c
+@@ -1606,6 +1606,8 @@ static struct ifobject *ifobject_create(void)
+ if (!ifobj->umem)
+ goto out_umem;
+
++ ifobj->ns_fd = -1;
++
+ return ifobj;
+
+ out_umem:
+@@ -1617,6 +1619,8 @@ out_xsk_arr:
+
+ static void ifobject_delete(struct ifobject *ifobj)
+ {
++ if (ifobj->ns_fd != -1)
++ close(ifobj->ns_fd);
+ free(ifobj->umem);
+ free(ifobj->xsk_arr);
+ free(ifobj);
+diff --git a/tools/testing/selftests/cpu-hotplug/config b/tools/testing/selftests/cpu-hotplug/config
+deleted file mode 100644
+index d4aca2ad5069b..0000000000000
+--- a/tools/testing/selftests/cpu-hotplug/config
++++ /dev/null
+@@ -1 +0,0 @@
+-CONFIG_NOTIFIER_ERROR_INJECTION=y
+diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+index 0d26b5e3f9667..4c1d6d9abecc3 100755
+--- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
++++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+@@ -4,6 +4,7 @@
+ SYSFS=
+ # Kselftest framework requirement - SKIP code is 4.
+ ksft_skip=4
++retval=0
+
+ prerequisite()
+ {
+@@ -102,10 +103,10 @@ online_cpu_expect_success()
+
+ if ! online_cpu $cpu; then
+ echo $FUNCNAME $cpu: unexpected fail >&2
+- exit 1
++ retval=1
+ elif ! cpu_is_online $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+- exit 1
++ retval=1
+ fi
+ }
+
+@@ -115,10 +116,10 @@ online_cpu_expect_fail()
+
+ if online_cpu $cpu 2> /dev/null; then
+ echo $FUNCNAME $cpu: unexpected success >&2
+- exit 1
++ retval=1
+ elif ! cpu_is_offline $cpu; then
+ echo $FUNCNAME $cpu: unexpected online >&2
+- exit 1
++ retval=1
+ fi
+ }
+
+@@ -128,10 +129,10 @@ offline_cpu_expect_success()
+
+ if ! offline_cpu $cpu; then
+ echo $FUNCNAME $cpu: unexpected fail >&2
+- exit 1
++ retval=1
+ elif ! cpu_is_offline $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+- exit 1
++ retval=1
+ fi
+ }
+
+@@ -141,16 +142,33 @@ offline_cpu_expect_fail()
+
+ if offline_cpu $cpu 2> /dev/null; then
+ echo $FUNCNAME $cpu: unexpected success >&2
+- exit 1
++ retval=1
+ elif ! cpu_is_online $cpu; then
+ echo $FUNCNAME $cpu: unexpected offline >&2
+- exit 1
++ retval=1
+ fi
+ }
+
+-error=-12
++online_all_hot_pluggable_cpus()
++{
++ for cpu in `hotplaggable_offline_cpus`; do
++ online_cpu_expect_success $cpu
++ done
++}
++
++offline_all_hot_pluggable_cpus()
++{
++ local reserve_cpu=$online_max
++ for cpu in `hotpluggable_online_cpus`; do
++ # Reserve one cpu oneline at least.
++ if [ $cpu -eq $reserve_cpu ];then
++ continue
++ fi
++ offline_cpu_expect_success $cpu
++ done
++}
++
+ allcpus=0
+-priority=0
+ online_cpus=0
+ online_max=0
+ offline_cpus=0
+@@ -158,31 +176,20 @@ offline_max=0
+ present_cpus=0
+ present_max=0
+
+-while getopts e:ahp: opt; do
++while getopts ah opt; do
+ case $opt in
+- e)
+- error=$OPTARG
+- ;;
+ a)
+ allcpus=1
+ ;;
+ h)
+- echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
++ echo "Usage $0 [ -a ]"
+ echo -e "\t default offline one cpu"
+ echo -e "\t run with -a option to offline all cpus"
+ exit
+ ;;
+- p)
+- priority=$OPTARG
+- ;;
+ esac
+ done
+
+-if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+- echo "error code must be -4095 <= errno < 0" >&2
+- exit 1
+-fi
+-
+ prerequisite
+
+ #
+@@ -201,7 +208,7 @@ if [ $allcpus -eq 0 ]; then
+ offline_cpu_expect_success $present_max
+ online_cpu $present_max
+ fi
+- exit 0
++ exit $retval
+ else
+ echo "Full scope test: all hotplug cpus"
+ echo -e "\t online all offline cpus"
+@@ -209,85 +216,10 @@ else
+ echo -e "\t online all offline cpus"
+ fi
+
+-#
+-# Online all hot-pluggable CPUs
+-#
+-for cpu in `hotplaggable_offline_cpus`; do
+- online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Offline all hot-pluggable CPUs
+-#
+-for cpu in `hotpluggable_online_cpus`; do
+- offline_cpu_expect_success $cpu
+-done
+-
+-#
+-# Online all hot-pluggable CPUs again
+-#
+-for cpu in `hotplaggable_offline_cpus`; do
+- online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test with cpu notifier error injection
+-#
++online_all_hot_pluggable_cpus
+
+-DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+-NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
++offline_all_hot_pluggable_cpus
+
+-prerequisite_extra()
+-{
+- msg="skip extra tests:"
+-
+- /sbin/modprobe -q -r cpu-notifier-error-inject
+- /sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+-
+- if [ ! -d "$DEBUGFS" ]; then
+- echo $msg debugfs is not mounted >&2
+- exit $ksft_skip
+- fi
+-
+- if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+- echo $msg cpu-notifier-error-inject module is not available >&2
+- exit $ksft_skip
+- fi
+-}
+-
+-prerequisite_extra
+-
+-#
+-# Offline all hot-pluggable CPUs
+-#
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-for cpu in `hotpluggable_online_cpus`; do
+- offline_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test CPU hot-add error handling (offline => online)
+-#
+-echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+-for cpu in `hotplaggable_offline_cpus`; do
+- online_cpu_expect_fail $cpu
+-done
+-
+-#
+-# Online all hot-pluggable CPUs
+-#
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+-for cpu in `hotplaggable_offline_cpus`; do
+- online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test CPU hot-remove error handling (online => offline)
+-#
+-echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-for cpu in `hotpluggable_online_cpus`; do
+- offline_cpu_expect_fail $cpu
+-done
++online_all_hot_pluggable_cpus
+
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-/sbin/modprobe -q -r cpu-notifier-error-inject
++exit $retval
+diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
+index 03b586760164a..31c3b6ebd388b 100755
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -1466,6 +1466,13 @@ ipv4_udp_novrf()
+ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP}
+ log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF"
+
++ log_start
++ run_cmd_nsb nettest -D -s &
++ sleep 1
++ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} -U
++ log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF, with connect()"
++
++
+ log_start
+ show_hint "Should fail 'Connection refused'"
+ run_cmd nettest -D -r ${a}
+@@ -1525,6 +1532,13 @@ ipv4_udp_novrf()
+ run_cmd nettest -D -d ${NSA_DEV} -S -r ${a}
+ log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection"
+
++ log_start
++ run_cmd nettest -s -D &
++ sleep 1
++ run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} -U
++ log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
++
++
+ # IPv4 with device bind has really weird behavior - it overrides the
+ # fib lookup, generates an rtable and tries to send the packet. This
+ # causes failures for local traffic at different places
+@@ -1550,6 +1564,15 @@ ipv4_udp_novrf()
+ sleep 1
+ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S
+ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
++
++ log_start
++ show_hint "Should fail since addresses on loopback are out of device scope"
++ run_cmd nettest -D -s &
++ sleep 1
++ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -U
++ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
++
++
+ done
+
+ a=${NSA_IP}
+@@ -3157,6 +3180,13 @@ ipv6_udp_novrf()
+ sleep 1
+ run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S
+ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
++
++ log_start
++ show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope"
++ run_cmd nettest -6 -D -s &
++ sleep 1
++ run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -U
++ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
+ done
+
+ a=${NSA_IP6}
+diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c
+index d9a6fd2cd9d31..7900fa98eccb1 100644
+--- a/tools/testing/selftests/net/nettest.c
++++ b/tools/testing/selftests/net/nettest.c
+@@ -127,6 +127,9 @@ struct sock_args {
+
+ /* ESP in UDP encap test */
+ int use_xfrm;
++
++ /* use send() and connect() instead of sendto */
++ int datagram_connect;
+ };
+
+ static int server_mode;
+@@ -979,6 +982,11 @@ static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
+ log_err_errno("write failed sending msg to peer");
+ return 1;
+ }
++ } else if (args->datagram_connect) {
++ if (send(sd, msg, msglen, 0) < 0) {
++ log_err_errno("send failed sending msg to peer");
++ return 1;
++ }
+ } else if (args->ifindex && args->use_cmsg) {
+ if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
+ return 1;
+@@ -1659,7 +1667,7 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
+ if (args->has_local_ip && bind_socket(sd, args))
+ goto err;
+
+- if (args->type != SOCK_STREAM)
++ if (args->type != SOCK_STREAM && !args->datagram_connect)
+ goto out;
+
+ if (args->password && tcp_md5sig(sd, addr, alen, args))
+@@ -1854,7 +1862,7 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
+ return client_status;
+ }
+
+-#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf"
++#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"
+ #define OPT_FORCE_BIND_KEY_IFINDEX 1001
+ #define OPT_NO_BIND_KEY_IFINDEX 1002
+
+@@ -1891,6 +1899,7 @@ static void print_usage(char *prog)
+ " -I dev bind socket to given device name - server mode\n"
+ " -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
+ " to set device binding\n"
++ " -U Use connect() and send() for datagram sockets\n"
+ " -f bind socket with the IP[V6]_FREEBIND option\n"
+ " -C use cmsg and IP_PKTINFO to specify device binding\n"
+ "\n"
+@@ -2074,6 +2083,9 @@ int main(int argc, char *argv[])
+ case 'x':
+ args.use_xfrm = 1;
+ break;
++ case 'U':
++ args.datagram_connect = 1;
++ break;
+ default:
+ print_usage(argv[0]);
+ return 1;
+diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py
+index 057a4f49c79d9..c7363c6764fc6 100644
+--- a/tools/testing/selftests/tpm2/tpm2.py
++++ b/tools/testing/selftests/tpm2/tpm2.py
+@@ -371,6 +371,10 @@ class Client:
+ fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags)
+ self.tpm_poll = select.poll()
+
++ def __del__(self):
++ if self.tpm:
++ self.tpm.close()
++
+ def close(self):
+ self.tpm.close()
+
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-26 11:24 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-26 11:24 UTC (permalink / raw
To: gentoo-commits
commit: 08c794c0b0d8d1d28994c04d849ea380b928a60e
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 26 11:24:09 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Oct 26 11:24:09 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=08c794c0
Linux patches 6.0.4 and 6.0.5
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 8 +
1003_linux-6.0.4.patch | 1011 ++++++++++++++++++++++++++++++++++++++++++++++++
1004_linux-6.0.5.patch | 159 ++++++++
3 files changed, 1178 insertions(+)
diff --git a/0000_README b/0000_README
index e5b9be05..85528522 100644
--- a/0000_README
+++ b/0000_README
@@ -55,6 +55,14 @@ Patch: 1002_linux-6.0.3.patch
From: http://www.kernel.org
Desc: Linux 6.0.3
+Patch: 1003_linux-6.0.4.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.4
+
+Patch: 1004_linux-6.0.5.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.5
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1003_linux-6.0.4.patch b/1003_linux-6.0.4.patch
new file mode 100644
index 00000000..4b203225
--- /dev/null
+++ b/1003_linux-6.0.4.patch
@@ -0,0 +1,1011 @@
+diff --git a/Makefile b/Makefile
+index d4297b3d0735a..f2e41dccdd89d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index e4080ad96089a..aa6d109fac08b 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -269,6 +269,8 @@ static __init int efivar_ssdt_load(void)
+ acpi_status ret = acpi_load_table(data, NULL);
+ if (ret)
+ pr_err("failed to load table: %u\n", ret);
++ else
++ continue;
+ } else {
+ pr_err("failed to get var data: 0x%lx\n", status);
+ }
+diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
+index dd74d2ad31840..433b615871395 100644
+--- a/drivers/firmware/efi/vars.c
++++ b/drivers/firmware/efi/vars.c
+@@ -7,6 +7,7 @@
+ */
+
+ #include <linux/types.h>
++#include <linux/sizes.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+@@ -20,19 +21,19 @@ static struct efivars *__efivars;
+
+ static DEFINE_SEMAPHORE(efivars_lock);
+
+-efi_status_t check_var_size(u32 attributes, unsigned long size)
++static efi_status_t check_var_size(u32 attributes, unsigned long size)
+ {
+ const struct efivar_operations *fops;
+
+ fops = __efivars->ops;
+
+ if (!fops->query_variable_store)
+- return EFI_UNSUPPORTED;
++ return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+
+ return fops->query_variable_store(attributes, size, false);
+ }
+-EXPORT_SYMBOL_NS_GPL(check_var_size, EFIVAR);
+
++static
+ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
+ {
+ const struct efivar_operations *fops;
+@@ -40,11 +41,10 @@ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
+ fops = __efivars->ops;
+
+ if (!fops->query_variable_store)
+- return EFI_UNSUPPORTED;
++ return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+
+ return fops->query_variable_store(attributes, size, true);
+ }
+-EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR);
+
+ /**
+ * efivars_kobject - get the kobject for the registered efivars
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 25e1f5ed7ead1..91665fe44e7ca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2926,6 +2926,14 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
+ amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
+ amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
+
++ /*
++ * Per PMFW team's suggestion, driver needs to handle gfxoff
++ * and df cstate features disablement for gpu reset(e.g. Mode1Reset)
++ * scenario. Add the missing df cstate disablement here.
++ */
++ if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
++ dev_warn(adev->dev, "Failed to disallow df cstate");
++
+ for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
+ if (!adev->ip_blocks[i].status.valid)
+ continue;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
+index ae2d337158f3b..f77401709d83c 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
+@@ -27,7 +27,7 @@
+ // *** IMPORTANT ***
+ // SMU TEAM: Always increment the interface version if
+ // any structure is changed in this file
+-#define PMFW_DRIVER_IF_VERSION 5
++#define PMFW_DRIVER_IF_VERSION 7
+
+ typedef struct {
+ int32_t value;
+@@ -163,8 +163,8 @@ typedef struct {
+ uint16_t DclkFrequency; //[MHz]
+ uint16_t MemclkFrequency; //[MHz]
+ uint16_t spare; //[centi]
+- uint16_t UvdActivity; //[centi]
+ uint16_t GfxActivity; //[centi]
++ uint16_t UvdActivity; //[centi]
+
+ uint16_t Voltage[2]; //[mV] indices: VDDCR_VDD, VDDCR_SOC
+ uint16_t Current[2]; //[mA] indices: VDDCR_VDD, VDDCR_SOC
+@@ -199,6 +199,19 @@ typedef struct {
+ uint16_t DeviceState;
+ uint16_t CurTemp; //[centi-Celsius]
+ uint16_t spare2;
++
++ uint16_t AverageGfxclkFrequency;
++ uint16_t AverageFclkFrequency;
++ uint16_t AverageGfxActivity;
++ uint16_t AverageSocclkFrequency;
++ uint16_t AverageVclkFrequency;
++ uint16_t AverageVcnActivity;
++ uint16_t AverageDRAMReads; //Filtered DF Bandwidth::DRAM Reads
++ uint16_t AverageDRAMWrites; //Filtered DF Bandwidth::DRAM Writes
++ uint16_t AverageSocketPower; //Filtered value of CurrentSocketPower
++ uint16_t AverageCorePower; //Filtered of [sum of CorePower[8]])
++ uint16_t AverageCoreC0Residency[8]; //Filtered of [average C0 residency % per core]
++ uint32_t MetricsCounter; //Counts the # of metrics table parameter reads per update to the metrics table, i.e. if the metrics table update happens every 1 second, this value could be up to 1000 if the smu collected metrics data every cycle, or as low as 0 if the smu was asleep the whole time. Reset to 0 after writing.
+ } SmuMetrics_t;
+
+ typedef struct {
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index f442bf085a318..f75b9688f5129 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -28,7 +28,7 @@
+ #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
+ #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x05
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+index 445005571f76f..9cd005131f566 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+@@ -2242,9 +2242,17 @@ static void arcturus_get_unique_id(struct smu_context *smu)
+ static int arcturus_set_df_cstate(struct smu_context *smu,
+ enum pp_df_cstate state)
+ {
++ struct amdgpu_device *adev = smu->adev;
+ uint32_t smu_version;
+ int ret;
+
++ /*
++ * Arcturus does not need the cstate disablement
++ * prerequisite for gpu reset.
++ */
++ if (amdgpu_in_reset(adev) || adev->in_suspend)
++ return 0;
++
+ ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
+ if (ret) {
+ dev_err(smu->adev->dev, "Failed to get smu version!\n");
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+index 619aee51b1238..d30ec3005ea19 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+@@ -1640,6 +1640,15 @@ static bool aldebaran_is_baco_supported(struct smu_context *smu)
+ static int aldebaran_set_df_cstate(struct smu_context *smu,
+ enum pp_df_cstate state)
+ {
++ struct amdgpu_device *adev = smu->adev;
++
++ /*
++ * Aldebaran does not need the cstate disablement
++ * prerequisite for gpu reset.
++ */
++ if (amdgpu_in_reset(adev) || adev->in_suspend)
++ return 0;
++
+ return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL);
+ }
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index 1d454485e0d91..29529328152d0 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -119,6 +119,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
+ MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource, 0),
+ MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0),
+ MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
++ MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
+@@ -1753,6 +1754,15 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
+ return ret;
+ }
+
++static int smu_v13_0_0_set_df_cstate(struct smu_context *smu,
++ enum pp_df_cstate state)
++{
++ return smu_cmn_send_smc_msg_with_param(smu,
++ SMU_MSG_DFCstateControl,
++ state,
++ NULL);
++}
++
+ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ .get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
+ .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
+@@ -1822,6 +1832,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ .mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported,
+ .mode1_reset = smu_v13_0_mode1_reset,
+ .set_mp1_state = smu_v13_0_0_set_mp1_state,
++ .set_df_cstate = smu_v13_0_0_set_df_cstate,
+ };
+
+ void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
+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 c422bf8a09b1d..c4102cfb734c2 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
+@@ -121,6 +121,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =
+ MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0),
+ MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
+ MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0),
++ MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
+@@ -1587,6 +1588,16 @@ static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
+
+ return true;
+ }
++
++static int smu_v13_0_7_set_df_cstate(struct smu_context *smu,
++ enum pp_df_cstate state)
++{
++ return smu_cmn_send_smc_msg_with_param(smu,
++ SMU_MSG_DFCstateControl,
++ state,
++ NULL);
++}
++
+ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
+ .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
+@@ -1649,6 +1660,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
+ .mode1_reset = smu_v13_0_mode1_reset,
+ .set_mp1_state = smu_v13_0_7_set_mp1_state,
++ .set_df_cstate = smu_v13_0_7_set_df_cstate,
+ };
+
+ void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
+index 7d6eb9ad7a026..459571e2cc575 100644
+--- a/drivers/gpu/drm/i915/display/intel_bios.c
++++ b/drivers/gpu/drm/i915/display/intel_bios.c
+@@ -135,18 +135,6 @@ static u32 raw_block_offset(const void *bdb, enum bdb_block_id section_id)
+ return block - bdb;
+ }
+
+-/* size of the block excluding the header */
+-static u32 raw_block_size(const void *bdb, enum bdb_block_id section_id)
+-{
+- const void *block;
+-
+- block = find_raw_section(bdb, section_id);
+- if (!block)
+- return 0;
+-
+- return get_blocksize(block);
+-}
+-
+ struct bdb_block_entry {
+ struct list_head node;
+ enum bdb_block_id section_id;
+@@ -231,9 +219,14 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ {
+ int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
+ int data_block_size, lfp_data_size;
++ const void *data_block;
+ int i;
+
+- data_block_size = raw_block_size(bdb, BDB_LVDS_LFP_DATA);
++ data_block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
++ if (!data_block)
++ return false;
++
++ data_block_size = get_blocksize(data_block);
+ if (data_block_size == 0)
+ return false;
+
+@@ -261,21 +254,6 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ if (16 * lfp_data_size > data_block_size)
+ return false;
+
+- /*
+- * Except for vlv/chv machines all real VBTs seem to have 6
+- * unaccounted bytes in the fp_timing table. And it doesn't
+- * appear to be a really intentional hole as the fp_timing
+- * 0xffff terminator is always within those 6 missing bytes.
+- */
+- if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size &&
+- fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
+- return false;
+-
+- if (ptrs->ptr[0].fp_timing.offset + fp_timing_size > ptrs->ptr[0].dvo_timing.offset ||
+- ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
+- ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
+- return false;
+-
+ /* make sure the table entries have uniform size */
+ for (i = 1; i < 16; i++) {
+ if (ptrs->ptr[i].fp_timing.table_size != fp_timing_size ||
+@@ -289,6 +267,23 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ return false;
+ }
+
++ /*
++ * Except for vlv/chv machines all real VBTs seem to have 6
++ * unaccounted bytes in the fp_timing table. And it doesn't
++ * appear to be a really intentional hole as the fp_timing
++ * 0xffff terminator is always within those 6 missing bytes.
++ */
++ if (fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size == lfp_data_size)
++ fp_timing_size += 6;
++
++ if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
++ return false;
++
++ if (ptrs->ptr[0].fp_timing.offset + fp_timing_size != ptrs->ptr[0].dvo_timing.offset ||
++ ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
++ ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
++ return false;
++
+ /* make sure the tables fit inside the data block */
+ for (i = 0; i < 16; i++) {
+ if (ptrs->ptr[i].fp_timing.offset + fp_timing_size > data_block_size ||
+@@ -300,6 +295,15 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
+ return false;
+
++ /* make sure fp_timing terminators are present at expected locations */
++ for (i = 0; i < 16; i++) {
++ const u16 *t = data_block + ptrs->ptr[i].fp_timing.offset +
++ fp_timing_size - 2;
++
++ if (*t != 0xffff)
++ return false;
++ }
++
+ return true;
+ }
+
+@@ -333,18 +337,6 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
+ return validate_lfp_data_ptrs(bdb, ptrs);
+ }
+
+-static const void *find_fp_timing_terminator(const u8 *data, int size)
+-{
+- int i;
+-
+- for (i = 0; i < size - 1; i++) {
+- if (data[i] == 0xff && data[i+1] == 0xff)
+- return &data[i];
+- }
+-
+- return NULL;
+-}
+-
+ static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
+ int table_size, int total_size)
+ {
+@@ -368,11 +360,22 @@ static void next_lfp_data_ptr(struct lvds_lfp_data_ptr_table *next,
+ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ const void *bdb)
+ {
+- int i, size, table_size, block_size, offset;
+- const void *t0, *t1, *block;
++ int i, size, table_size, block_size, offset, fp_timing_size;
+ struct bdb_lvds_lfp_data_ptrs *ptrs;
++ const void *block;
+ void *ptrs_block;
+
++ /*
++ * The hardcoded fp_timing_size is only valid for
++ * modernish VBTs. All older VBTs definitely should
++ * include block 41 and thus we don't need to
++ * generate one.
++ */
++ if (i915->vbt.version < 155)
++ return NULL;
++
++ fp_timing_size = 38;
++
+ block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ if (!block)
+ return NULL;
+@@ -381,17 +384,8 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+
+ block_size = get_blocksize(block);
+
+- size = block_size;
+- t0 = find_fp_timing_terminator(block, size);
+- if (!t0)
+- return NULL;
+-
+- size -= t0 - block - 2;
+- t1 = find_fp_timing_terminator(t0 + 2, size);
+- if (!t1)
+- return NULL;
+-
+- size = t1 - t0;
++ size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
++ sizeof(struct lvds_pnp_id);
+ if (size * 16 > block_size)
+ return NULL;
+
+@@ -409,7 +403,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ table_size = sizeof(struct lvds_dvo_timing);
+ size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
+
+- table_size = t0 - block + 2;
++ table_size = fp_timing_size;
+ size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
+
+ if (ptrs->ptr[0].fp_timing.table_size)
+@@ -424,14 +418,14 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ return NULL;
+ }
+
+- size = t1 - t0;
++ size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
++ sizeof(struct lvds_pnp_id);
+ for (i = 1; i < 16; i++) {
+ next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
+ next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
+ next_lfp_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
+ }
+
+- size = t1 - t0;
+ table_size = sizeof(struct lvds_lfp_panel_name);
+
+ if (16 * (size + table_size) <= block_size) {
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 50bab12d9476f..043cf1cc87946 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -1142,6 +1142,7 @@
+ #define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
+ #define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
+ #define USB_DEVICE_ID_SONY_PS5_CONTROLLER 0x0ce6
++#define USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 0x0df2
+ #define USB_DEVICE_ID_SONY_MOTION_CONTROLLER 0x03d5
+ #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
+ #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
+diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
+index b1b5721b5d8f7..d21d868e29ab4 100644
+--- a/drivers/hid/hid-playstation.c
++++ b/drivers/hid/hid-playstation.c
+@@ -46,6 +46,7 @@ struct ps_device {
+ uint32_t fw_version;
+
+ int (*parse_report)(struct ps_device *dev, struct hid_report *report, u8 *data, int size);
++ void (*remove)(struct ps_device *dev);
+ };
+
+ /* Calibration data for playstation motion sensors. */
+@@ -174,6 +175,7 @@ struct dualsense {
+ struct led_classdev player_leds[5];
+
+ struct work_struct output_worker;
++ bool output_worker_initialized;
+ void *output_report_dmabuf;
+ uint8_t output_seq; /* Sequence number for output report. */
+ };
+@@ -299,6 +301,7 @@ static const struct {int x; int y; } ps_gamepad_hat_mapping[] = {
+ {0, 0},
+ };
+
++static inline void dualsense_schedule_work(struct dualsense *ds);
+ static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue);
+
+ /*
+@@ -792,6 +795,7 @@ err_free:
+ return ret;
+ }
+
++
+ static int dualsense_get_firmware_info(struct dualsense *ds)
+ {
+ uint8_t *buf;
+@@ -881,7 +885,7 @@ static int dualsense_player_led_set_brightness(struct led_classdev *led, enum le
+ ds->update_player_leds = true;
+ spin_unlock_irqrestore(&ds->base.lock, flags);
+
+- schedule_work(&ds->output_worker);
++ dualsense_schedule_work(ds);
+
+ return 0;
+ }
+@@ -925,6 +929,16 @@ static void dualsense_init_output_report(struct dualsense *ds, struct dualsense_
+ }
+ }
+
++static inline void dualsense_schedule_work(struct dualsense *ds)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ds->base.lock, flags);
++ if (ds->output_worker_initialized)
++ schedule_work(&ds->output_worker);
++ spin_unlock_irqrestore(&ds->base.lock, flags);
++}
++
+ /*
+ * Helper function to send DualSense output reports. Applies a CRC at the end of a report
+ * for Bluetooth reports.
+@@ -1085,7 +1099,7 @@ static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *r
+ spin_unlock_irqrestore(&ps_dev->lock, flags);
+
+ /* Schedule updating of microphone state at hardware level. */
+- schedule_work(&ds->output_worker);
++ dualsense_schedule_work(ds);
+ }
+ ds->last_btn_mic_state = btn_mic_state;
+
+@@ -1200,10 +1214,22 @@ static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_ef
+ ds->motor_right = effect->u.rumble.weak_magnitude / 256;
+ spin_unlock_irqrestore(&ds->base.lock, flags);
+
+- schedule_work(&ds->output_worker);
++ dualsense_schedule_work(ds);
+ return 0;
+ }
+
++static void dualsense_remove(struct ps_device *ps_dev)
++{
++ struct dualsense *ds = container_of(ps_dev, struct dualsense, base);
++ unsigned long flags;
++
++ spin_lock_irqsave(&ds->base.lock, flags);
++ ds->output_worker_initialized = false;
++ spin_unlock_irqrestore(&ds->base.lock, flags);
++
++ cancel_work_sync(&ds->output_worker);
++}
++
+ static int dualsense_reset_leds(struct dualsense *ds)
+ {
+ struct dualsense_output_report report;
+@@ -1240,7 +1266,7 @@ static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t gr
+ ds->lightbar_blue = blue;
+ spin_unlock_irqrestore(&ds->base.lock, flags);
+
+- schedule_work(&ds->output_worker);
++ dualsense_schedule_work(ds);
+ }
+
+ static void dualsense_set_player_leds(struct dualsense *ds)
+@@ -1263,7 +1289,7 @@ static void dualsense_set_player_leds(struct dualsense *ds)
+
+ ds->update_player_leds = true;
+ ds->player_leds_state = player_ids[player_id];
+- schedule_work(&ds->output_worker);
++ dualsense_schedule_work(ds);
+ }
+
+ static struct ps_device *dualsense_create(struct hid_device *hdev)
+@@ -1302,7 +1328,9 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
+ ps_dev->battery_capacity = 100; /* initial value until parse_report. */
+ ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN;
+ ps_dev->parse_report = dualsense_parse_report;
++ ps_dev->remove = dualsense_remove;
+ INIT_WORK(&ds->output_worker, dualsense_output_worker);
++ ds->output_worker_initialized = true;
+ hid_set_drvdata(hdev, ds);
+
+ max_output_report_size = sizeof(struct dualsense_output_report_bt);
+@@ -1439,7 +1467,8 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ goto err_stop;
+ }
+
+- if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) {
++ if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ||
++ hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) {
+ dev = dualsense_create(hdev);
+ if (IS_ERR(dev)) {
+ hid_err(hdev, "Failed to create dualsense.\n");
+@@ -1470,6 +1499,9 @@ static void ps_remove(struct hid_device *hdev)
+ ps_devices_list_remove(dev);
+ ps_device_release_player_id(dev);
+
++ if (dev->remove)
++ dev->remove(dev);
++
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+ }
+@@ -1477,6 +1509,8 @@ static void ps_remove(struct hid_device *hdev)
+ static const struct hid_device_id ps_devices[] = {
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, ps_devices);
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index 811b0a5379d03..2f1cc66d26412 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -2035,7 +2035,7 @@ static void disable_passdown_if_not_supported(struct clone *clone)
+ reason = "max discard sectors smaller than a region";
+
+ if (reason) {
+- DMWARN("Destination device (%pd) %s: Disabling discard passdown.",
++ DMWARN("Destination device (%pg) %s: Disabling discard passdown.",
+ dest_dev, reason);
+ clear_bit(DM_CLONE_DISCARD_PASSDOWN, &clone->flags);
+ }
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 4691a33bc374f..2a4b3efb7e12b 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -1051,13 +1051,13 @@ static void amd_get_iomux_res(struct amd_gpio *gpio_dev)
+
+ index = device_property_match_string(dev, "pinctrl-resource-names", "iomux");
+ if (index < 0) {
+- dev_warn(dev, "failed to get iomux index\n");
++ dev_dbg(dev, "iomux not supported\n");
+ goto out_no_pinmux;
+ }
+
+ gpio_dev->iomux_base = devm_platform_ioremap_resource(gpio_dev->pdev, index);
+ if (IS_ERR(gpio_dev->iomux_base)) {
+- dev_warn(dev, "Failed to get iomux %d io resource\n", index);
++ dev_dbg(dev, "iomux not supported %d io resource\n", index);
+ goto out_no_pinmux;
+ }
+
+diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
+index 46cd799af148d..bf3e4edeceda9 100644
+--- a/drivers/thermal/intel/intel_powerclamp.c
++++ b/drivers/thermal/intel/intel_powerclamp.c
+@@ -531,11 +531,7 @@ static int start_power_clamp(void)
+ cpus_read_lock();
+
+ /* prefer BSP */
+- control_cpu = 0;
+- if (!cpu_online(control_cpu)) {
+- control_cpu = get_cpu();
+- put_cpu();
+- }
++ control_cpu = cpumask_first(cpu_online_mask);
+
+ clamping = true;
+ schedule_delayed_work(&poll_pkg_cstate_work, 0);
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index d245826a9324d..101e13c2cf41c 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -335,30 +335,36 @@ EXPORT_SYMBOL(aperture_remove_conflicting_devices);
+ */
+ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name)
+ {
++ bool primary = false;
+ resource_size_t base, size;
+ int bar, ret;
+
+- /*
+- * WARNING: Apparently we must kick fbdev drivers before vgacon,
+- * otherwise the vga fbdev driver falls over.
+- */
+-#if IS_REACHABLE(CONFIG_FB)
+- ret = remove_conflicting_pci_framebuffers(pdev, name);
+- if (ret)
+- return ret;
++#ifdef CONFIG_X86
++ primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+ #endif
+- ret = vga_remove_vgacon(pdev);
+- if (ret)
+- return ret;
+
+ for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) {
+ if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+ continue;
++
+ base = pci_resource_start(pdev, bar);
+ size = pci_resource_len(pdev, bar);
+- aperture_detach_devices(base, size);
++ ret = aperture_remove_conflicting_devices(base, size, primary, name);
++ if (ret)
++ break;
+ }
+
++ if (ret)
++ return ret;
++
++ /*
++ * WARNING: Apparently we must kick fbdev drivers before vgacon,
++ * otherwise the vga fbdev driver falls over.
++ */
++ ret = vga_remove_vgacon(pdev);
++ if (ret)
++ return ret;
++
+ return 0;
+
+ }
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index bda4d304feb68..4ed0960e6c058 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1787,54 +1787,6 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
+ }
+ EXPORT_SYMBOL(remove_conflicting_framebuffers);
+
+-/**
+- * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
+- * @pdev: PCI device
+- * @name: requesting driver name
+- *
+- * This function removes framebuffer devices (eg. initialized by firmware)
+- * using memory range configured for any of @pdev's memory bars.
+- *
+- * The function assumes that PCI device with shadowed ROM drives a primary
+- * display and so kicks out vga16fb.
+- */
+-int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name)
+-{
+- struct apertures_struct *ap;
+- bool primary = false;
+- int err, idx, bar;
+-
+- for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+- if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+- continue;
+- idx++;
+- }
+-
+- ap = alloc_apertures(idx);
+- if (!ap)
+- return -ENOMEM;
+-
+- for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+- if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+- continue;
+- ap->ranges[idx].base = pci_resource_start(pdev, bar);
+- ap->ranges[idx].size = pci_resource_len(pdev, bar);
+- pci_dbg(pdev, "%s: bar %d: 0x%lx -> 0x%lx\n", __func__, bar,
+- (unsigned long)pci_resource_start(pdev, bar),
+- (unsigned long)pci_resource_end(pdev, bar));
+- idx++;
+- }
+-
+-#ifdef CONFIG_X86
+- primary = pdev->resource[PCI_ROM_RESOURCE].flags &
+- IORESOURCE_ROM_SHADOW;
+-#endif
+- err = remove_conflicting_framebuffers(ap, name, primary);
+- kfree(ap);
+- return err;
+-}
+-EXPORT_SYMBOL(remove_conflicting_pci_framebuffers);
+-
+ /**
+ * register_framebuffer - registers a frame buffer device
+ * @fb_info: frame buffer info structure
+diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c
+index a0ef63cfcecba..9e4f47808bd5a 100644
+--- a/fs/efivarfs/vars.c
++++ b/fs/efivarfs/vars.c
+@@ -651,22 +651,6 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
+ if (err)
+ return err;
+
+- /*
+- * Ensure that the available space hasn't shrunk below the safe level
+- */
+- status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
+- if (status != EFI_SUCCESS) {
+- if (status != EFI_UNSUPPORTED) {
+- err = efi_status_to_err(status);
+- goto out;
+- }
+-
+- if (*size > 65536) {
+- err = -ENOSPC;
+- goto out;
+- }
+- }
+-
+ status = efivar_set_variable_locked(name, vendor, attributes, *size,
+ data, false);
+ if (status != EFI_SUCCESS) {
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index d2b84c2fec39f..4459794b65db0 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1055,9 +1055,6 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
+ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size, void *data);
+
+-efi_status_t check_var_size(u32 attributes, unsigned long size);
+-efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size);
+-
+ #if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
+ extern bool efi_capsule_pending(int *reset_type);
+
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index 07fcd0e566826..b91c770165600 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -615,8 +615,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ /* drivers/video/fbmem.c */
+ extern int register_framebuffer(struct fb_info *fb_info);
+ extern void unregister_framebuffer(struct fb_info *fb_info);
+-extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
+- const char *name);
+ extern int remove_conflicting_framebuffers(struct apertures_struct *a,
+ const char *name, bool primary);
+ extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 711c3593c3b8d..18d942bbdf6e0 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -41,6 +41,7 @@ struct net;
+ #define SOCK_NOSPACE 2
+ #define SOCK_PASSCRED 3
+ #define SOCK_PASSSEC 4
++#define SOCK_SUPPORT_ZC 5
+
+ #ifndef ARCH_HAS_SOCKET_TYPES
+ /**
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index c6536d4b2da0b..6f1d0e5df23ad 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -1164,10 +1164,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
+ wqe = kzalloc_node(sizeof(struct io_wqe), GFP_KERNEL, alloc_node);
+ if (!wqe)
+ goto err;
++ wq->wqes[node] = wqe;
+ if (!alloc_cpumask_var(&wqe->cpu_mask, GFP_KERNEL))
+ goto err;
+ cpumask_copy(wqe->cpu_mask, cpumask_of_node(node));
+- wq->wqes[node] = wqe;
+ wqe->node = alloc_node;
+ wqe->acct[IO_WQ_ACCT_BOUND].max_workers = bounded;
+ wqe->acct[IO_WQ_ACCT_UNBOUND].max_workers =
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 4878bf40f8b1c..7804ac77745b1 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -1001,6 +1001,8 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
+ sock = sock_from_file(req->file);
+ if (unlikely(!sock))
+ return -ENOTSOCK;
++ if (!test_bit(SOCK_SUPPORT_ZC, &sock->flags))
++ return -EOPNOTSUPP;
+
+ msg.msg_name = NULL;
+ msg.msg_control = NULL;
+diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c
+index 460c12b7dfea2..7971e989e425b 100644
+--- a/kernel/gcov/gcc_4_7.c
++++ b/kernel/gcov/gcc_4_7.c
+@@ -30,6 +30,13 @@
+
+ #define GCOV_TAG_FUNCTION_LENGTH 3
+
++/* Since GCC 12.1 sizes are in BYTES and not in WORDS (4B). */
++#if (__GNUC__ >= 12)
++#define GCOV_UNIT_SIZE 4
++#else
++#define GCOV_UNIT_SIZE 1
++#endif
++
+ static struct gcov_info *gcov_info_head;
+
+ /**
+@@ -383,12 +390,18 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info)
+ pos += store_gcov_u32(buffer, pos, info->version);
+ pos += store_gcov_u32(buffer, pos, info->stamp);
+
++#if (__GNUC__ >= 12)
++ /* Use zero as checksum of the compilation unit. */
++ pos += store_gcov_u32(buffer, pos, 0);
++#endif
++
+ for (fi_idx = 0; fi_idx < info->n_functions; fi_idx++) {
+ fi_ptr = info->functions[fi_idx];
+
+ /* Function record. */
+ pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION);
+- pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION_LENGTH);
++ pos += store_gcov_u32(buffer, pos,
++ GCOV_TAG_FUNCTION_LENGTH * GCOV_UNIT_SIZE);
+ pos += store_gcov_u32(buffer, pos, fi_ptr->ident);
+ pos += store_gcov_u32(buffer, pos, fi_ptr->lineno_checksum);
+ pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum);
+@@ -402,7 +415,8 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info)
+ /* Counter record. */
+ pos += store_gcov_u32(buffer, pos,
+ GCOV_TAG_FOR_COUNTER(ct_idx));
+- pos += store_gcov_u32(buffer, pos, ci_ptr->num * 2);
++ pos += store_gcov_u32(buffer, pos,
++ ci_ptr->num * 2 * GCOV_UNIT_SIZE);
+
+ for (cv_idx = 0; cv_idx < ci_ptr->num; cv_idx++) {
+ pos += store_gcov_u64(buffer, pos,
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5f1d84d901c71..5fbd0a5b48f7e 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -457,6 +457,7 @@ void tcp_init_sock(struct sock *sk)
+ WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_wmem[1]));
+ WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[1]));
+
++ set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ sk_sockets_allocated_inc(sk);
+ }
+ EXPORT_SYMBOL(tcp_init_sock);
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 560d9eadeaa58..516b11c136daf 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1620,6 +1620,7 @@ int udp_init_sock(struct sock *sk)
+ {
+ skb_queue_head_init(&udp_sk(sk)->reader_queue);
+ sk->sk_destruct = udp_destruct_sock;
++ set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(udp_init_sock);
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 4ae8b9574778b..384426d7e9ddc 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -931,28 +931,8 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
+ }
+
+ codec->bus = bus;
+- codec->depop_delay = -1;
+- codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+- codec->core.dev.release = snd_hda_codec_dev_release;
+- codec->core.exec_verb = codec_exec_verb;
+ codec->core.type = HDA_DEV_LEGACY;
+
+- mutex_init(&codec->spdif_mutex);
+- mutex_init(&codec->control_mutex);
+- snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
+- snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
+- snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
+- snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
+- snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
+- snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
+- snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
+- snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
+- INIT_LIST_HEAD(&codec->conn_list);
+- INIT_LIST_HEAD(&codec->pcm_list_head);
+- INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
+- refcount_set(&codec->pcm_ref, 1);
+- init_waitqueue_head(&codec->remove_sleep);
+-
+ return codec;
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_codec_device_init);
+@@ -1005,8 +985,29 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
+ if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
+ return -EINVAL;
+
++ codec->core.dev.release = snd_hda_codec_dev_release;
++ codec->core.exec_verb = codec_exec_verb;
++
+ codec->card = card;
+ codec->addr = codec_addr;
++ mutex_init(&codec->spdif_mutex);
++ mutex_init(&codec->control_mutex);
++ snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
++ snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
++ snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
++ snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
++ snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
++ snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
++ snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
++ snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
++ INIT_LIST_HEAD(&codec->conn_list);
++ INIT_LIST_HEAD(&codec->pcm_list_head);
++ refcount_set(&codec->pcm_ref, 1);
++ init_waitqueue_head(&codec->remove_sleep);
++
++ INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
++ codec->depop_delay = -1;
++ codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+
+ #ifdef CONFIG_PM
+ codec->power_jiffies = jiffies;
diff --git a/1004_linux-6.0.5.patch b/1004_linux-6.0.5.patch
new file mode 100644
index 00000000..e13708b0
--- /dev/null
+++ b/1004_linux-6.0.5.patch
@@ -0,0 +1,159 @@
+diff --git a/Makefile b/Makefile
+index f2e41dccdd89d..62a7398c8d06f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 4
++SUBLEVEL = 5
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
+index f7405a58877e2..73303458e8866 100644
+--- a/drivers/clk/tegra/clk-tegra114.c
++++ b/drivers/clk/tegra/clk-tegra114.c
+@@ -1166,6 +1166,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
+ { TEGRA114_CLK_I2S3_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
+ { TEGRA114_CLK_I2S4_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
+ { TEGRA114_CLK_VIMCLK_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
++ { TEGRA114_CLK_PWM, TEGRA114_CLK_PLL_P, 408000000, 0 },
+ /* must be the last entry */
+ { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
+index 934520aab6e38..7628cc470a275 100644
+--- a/drivers/clk/tegra/clk-tegra124.c
++++ b/drivers/clk/tegra/clk-tegra124.c
+@@ -1330,6 +1330,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
+ { TEGRA124_CLK_I2S3_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
+ { TEGRA124_CLK_I2S4_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
+ { TEGRA124_CLK_VIMCLK_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
++ { TEGRA124_CLK_PWM, TEGRA124_CLK_PLL_P, 408000000, 0 },
+ /* must be the last entry */
+ { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index 8a4514f6d5033..422d782475532 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -1044,6 +1044,7 @@ static struct tegra_clk_init_table init_table[] = {
+ { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
+ { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
+ { TEGRA20_CLK_VDE, TEGRA20_CLK_PLL_C, 300000000, 0 },
++ { TEGRA20_CLK_PWM, TEGRA20_CLK_PLL_P, 48000000, 0 },
+ /* must be the last entry */
+ { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
+index 499f999e91e13..a3488aaac3f78 100644
+--- a/drivers/clk/tegra/clk-tegra210.c
++++ b/drivers/clk/tegra/clk-tegra210.c
+@@ -3597,6 +3597,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
+ { TEGRA210_CLK_VIMCLK_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 },
+ { TEGRA210_CLK_HDA, TEGRA210_CLK_PLL_P, 51000000, 0 },
+ { TEGRA210_CLK_HDA2CODEC_2X, TEGRA210_CLK_PLL_P, 48000000, 0 },
++ { TEGRA210_CLK_PWM, TEGRA210_CLK_PLL_P, 48000000, 0 },
+ /* This MUST be the last entry. */
+ { TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
+index 04b4961238209..98ec1a50e8542 100644
+--- a/drivers/clk/tegra/clk-tegra30.c
++++ b/drivers/clk/tegra/clk-tegra30.c
+@@ -1237,6 +1237,7 @@ static struct tegra_clk_init_table init_table[] = {
+ { TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
+ { TEGRA30_CLK_HDA, TEGRA30_CLK_PLL_P, 102000000, 0 },
+ { TEGRA30_CLK_HDA2CODEC_2X, TEGRA30_CLK_PLL_P, 48000000, 0 },
++ { TEGRA30_CLK_PWM, TEGRA30_CLK_PLL_P, 48000000, 0 },
+ /* must be the last entry */
+ { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 015b0440df5dc..85404c62a1c27 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -48,25 +48,6 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info, u64 offset,
+ u64 bytes, bool update_stats);
+
+-static void __btrfs_remove_free_space_cache_locked(
+- struct btrfs_free_space_ctl *ctl)
+-{
+- struct btrfs_free_space *info;
+- struct rb_node *node;
+-
+- while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
+- info = rb_entry(node, struct btrfs_free_space, offset_index);
+- if (!info->bitmap) {
+- unlink_free_space(ctl, info, true);
+- kmem_cache_free(btrfs_free_space_cachep, info);
+- } else {
+- free_bitmap(ctl, info);
+- }
+-
+- cond_resched_lock(&ctl->tree_lock);
+- }
+-}
+-
+ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
+ struct btrfs_path *path,
+ u64 offset)
+@@ -900,14 +881,7 @@ out:
+ return ret;
+ free_cache:
+ io_ctl_drop_pages(&io_ctl);
+-
+- /*
+- * We need to call the _locked variant so we don't try to update the
+- * discard counters.
+- */
+- spin_lock(&ctl->tree_lock);
+- __btrfs_remove_free_space_cache_locked(ctl);
+- spin_unlock(&ctl->tree_lock);
++ __btrfs_remove_free_space_cache(ctl);
+ goto out;
+ }
+
+@@ -1033,13 +1007,7 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+ if (ret == 0)
+ ret = 1;
+ } else {
+- /*
+- * We need to call the _locked variant so we don't try to update
+- * the discard counters.
+- */
+- spin_lock(&tmp_ctl.tree_lock);
+ __btrfs_remove_free_space_cache(&tmp_ctl);
+- spin_unlock(&tmp_ctl.tree_lock);
+ btrfs_warn(fs_info,
+ "block group %llu has wrong amount of free space",
+ block_group->start);
+@@ -3002,6 +2970,25 @@ static void __btrfs_return_cluster_to_free_space(
+ btrfs_put_block_group(block_group);
+ }
+
++static void __btrfs_remove_free_space_cache_locked(
++ struct btrfs_free_space_ctl *ctl)
++{
++ struct btrfs_free_space *info;
++ struct rb_node *node;
++
++ while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
++ info = rb_entry(node, struct btrfs_free_space, offset_index);
++ if (!info->bitmap) {
++ unlink_free_space(ctl, info, true);
++ kmem_cache_free(btrfs_free_space_cachep, info);
++ } else {
++ free_bitmap(ctl, info);
++ }
++
++ cond_resched_lock(&ctl->tree_lock);
++ }
++}
++
+ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
+ {
+ spin_lock(&ctl->tree_lock);
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-29 9:54 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-29 9:54 UTC (permalink / raw
To: gentoo-commits
commit: 09961889c2417cfb42ef549dedc4e7bbc9b7f082
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 29 09:54:21 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct 29 09:54:21 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=09961889
Linux patch 6.0.6
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1005_linux-6.0.6.patch | 3748 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 3752 insertions(+)
diff --git a/0000_README b/0000_README
index 85528522..68ada3e5 100644
--- a/0000_README
+++ b/0000_README
@@ -63,6 +63,10 @@ Patch: 1004_linux-6.0.5.patch
From: http://www.kernel.org
Desc: Linux 6.0.5
+Patch: 1005_linux-6.0.6.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.6
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1005_linux-6.0.6.patch b/1005_linux-6.0.6.patch
new file mode 100644
index 00000000..fe496b3f
--- /dev/null
+++ b/1005_linux-6.0.6.patch
@@ -0,0 +1,3748 @@
+diff --git a/Makefile b/Makefile
+index 62a7398c8d06f..e6c10009d413a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 5
++SUBLEVEL = 6
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
+index 9d3299a702423..a4dff86d39f0a 100644
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -2149,7 +2149,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
+
+ memset(entry, 0, esz);
+
+- while (len > 0) {
++ while (true) {
+ int next_offset;
+ size_t byte_offset;
+
+@@ -2162,6 +2162,9 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
+ return next_offset;
+
+ byte_offset = next_offset * esz;
++ if (byte_offset >= len)
++ break;
++
+ id += next_offset;
+ gpa += byte_offset;
+ len -= byte_offset;
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 159c025ebb03e..4728d3f5d5c40 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1961,7 +1961,6 @@ config EFI
+ config EFI_STUB
+ bool "EFI stub support"
+ depends on EFI
+- depends on $(cc-option,-mabi=ms) || X86_32
+ select RELOCATABLE
+ help
+ This kernel feature allows a bzImage to be loaded directly
+diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
+index 0bef44d30a278..2fd52b65deac1 100644
+--- a/arch/x86/include/asm/iommu.h
++++ b/arch/x86/include/asm/iommu.h
+@@ -25,8 +25,10 @@ arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
+ {
+ u64 start = rmrr->base_address;
+ u64 end = rmrr->end_address + 1;
++ int entry_type;
+
+- if (e820__mapped_all(start, end, E820_TYPE_RESERVED))
++ entry_type = e820__get_entry_type(start, end);
++ if (entry_type == E820_TYPE_RESERVED || entry_type == E820_TYPE_NVS)
+ return 0;
+
+ pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n",
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 615bc6efa1dd4..72869276326bb 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -440,7 +440,13 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p
+ return ret;
+
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+- if (rev >= mc->hdr.patch_id)
++
++ /*
++ * Allow application of the same revision to pick up SMT-specific
++ * changes even if the revision of the other SMT thread is already
++ * up-to-date.
++ */
++ if (rev > mc->hdr.patch_id)
+ return ret;
+
+ if (!__apply_microcode_amd(mc)) {
+@@ -528,8 +534,12 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
+
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
+- /* Check whether we have saved a new patch already: */
+- if (*new_rev && rev < mc->hdr.patch_id) {
++ /*
++ * Check whether a new patch has been saved already. Also, allow application of
++ * the same revision in order to pick up SMT-thread-specific configuration even
++ * if the sibling SMT thread already has an up-to-date revision.
++ */
++ if (*new_rev && rev <= mc->hdr.patch_id) {
+ if (!__apply_microcode_amd(mc)) {
+ *new_rev = mc->hdr.patch_id;
+ return;
+diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
+index bb1c3f5f60c81..a5c51a14fbce8 100644
+--- a/arch/x86/kernel/cpu/resctrl/core.c
++++ b/arch/x86/kernel/cpu/resctrl/core.c
+@@ -66,9 +66,6 @@ struct rdt_hw_resource rdt_resources_all[] = {
+ .rid = RDT_RESOURCE_L3,
+ .name = "L3",
+ .cache_level = 3,
+- .cache = {
+- .min_cbm_bits = 1,
+- },
+ .domains = domain_init(RDT_RESOURCE_L3),
+ .parse_ctrlval = parse_cbm,
+ .format_str = "%d=%0*x",
+@@ -83,9 +80,6 @@ struct rdt_hw_resource rdt_resources_all[] = {
+ .rid = RDT_RESOURCE_L2,
+ .name = "L2",
+ .cache_level = 2,
+- .cache = {
+- .min_cbm_bits = 1,
+- },
+ .domains = domain_init(RDT_RESOURCE_L2),
+ .parse_ctrlval = parse_cbm,
+ .format_str = "%d=%0*x",
+@@ -877,6 +871,7 @@ static __init void rdt_init_res_defs_intel(void)
+ r->cache.arch_has_sparse_bitmaps = false;
+ r->cache.arch_has_empty_bitmaps = false;
+ r->cache.arch_has_per_cpu_cfg = false;
++ r->cache.min_cbm_bits = 1;
+ } else if (r->rid == RDT_RESOURCE_MBA) {
+ hw_res->msr_base = MSR_IA32_MBA_THRTL_BASE;
+ hw_res->msr_update = mba_wrmsr_intel;
+@@ -897,6 +892,7 @@ static __init void rdt_init_res_defs_amd(void)
+ r->cache.arch_has_sparse_bitmaps = true;
+ r->cache.arch_has_empty_bitmaps = true;
+ r->cache.arch_has_per_cpu_cfg = true;
++ r->cache.min_cbm_bits = 0;
+ } else if (r->rid == RDT_RESOURCE_MBA) {
+ hw_res->msr_base = MSR_IA32_MBA_BW_BASE;
+ hw_res->msr_update = mba_wrmsr_amd;
+diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
+index 132a2de44d2fe..5e868b62a7c4e 100644
+--- a/arch/x86/kernel/cpu/topology.c
++++ b/arch/x86/kernel/cpu/topology.c
+@@ -96,6 +96,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width;
+ unsigned int core_select_mask, core_level_siblings;
+ unsigned int die_select_mask, die_level_siblings;
++ unsigned int pkg_mask_width;
+ bool die_level_present = false;
+ int leaf;
+
+@@ -111,10 +112,10 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
+ core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
+- die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
++ pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+
+ sub_index = 1;
+- do {
++ while (true) {
+ cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
+
+ /*
+@@ -132,10 +133,15 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ }
+
++ if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
++ pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
++ else
++ break;
++
+ sub_index++;
+- } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
++ }
+
+- core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
++ core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width;
+ die_select_mask = (~(-1 << die_plus_mask_width)) >>
+ core_plus_mask_width;
+
+@@ -148,7 +154,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ }
+
+ c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
+- die_plus_mask_width);
++ pkg_mask_width);
+ /*
+ * Reinit the apicid, now that we have extended initial_apicid.
+ */
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index e2435090f2258..86c3b29f1abc0 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -6406,26 +6406,22 @@ static int kvm_add_msr_filter(struct kvm_x86_msr_filter *msr_filter,
+ return 0;
+ }
+
+-static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
++static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm,
++ struct kvm_msr_filter *filter)
+ {
+- struct kvm_msr_filter __user *user_msr_filter = argp;
+ struct kvm_x86_msr_filter *new_filter, *old_filter;
+- struct kvm_msr_filter filter;
+ bool default_allow;
+ bool empty = true;
+ int r = 0;
+ u32 i;
+
+- if (copy_from_user(&filter, user_msr_filter, sizeof(filter)))
+- return -EFAULT;
+-
+- if (filter.flags & ~KVM_MSR_FILTER_DEFAULT_DENY)
++ if (filter->flags & ~KVM_MSR_FILTER_DEFAULT_DENY)
+ return -EINVAL;
+
+- for (i = 0; i < ARRAY_SIZE(filter.ranges); i++)
+- empty &= !filter.ranges[i].nmsrs;
++ for (i = 0; i < ARRAY_SIZE(filter->ranges); i++)
++ empty &= !filter->ranges[i].nmsrs;
+
+- default_allow = !(filter.flags & KVM_MSR_FILTER_DEFAULT_DENY);
++ default_allow = !(filter->flags & KVM_MSR_FILTER_DEFAULT_DENY);
+ if (empty && !default_allow)
+ return -EINVAL;
+
+@@ -6433,8 +6429,8 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
+ if (!new_filter)
+ return -ENOMEM;
+
+- for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) {
+- r = kvm_add_msr_filter(new_filter, &filter.ranges[i]);
++ for (i = 0; i < ARRAY_SIZE(filter->ranges); i++) {
++ r = kvm_add_msr_filter(new_filter, &filter->ranges[i]);
+ if (r) {
+ kvm_free_msr_filter(new_filter);
+ return r;
+@@ -6457,6 +6453,62 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
+ return 0;
+ }
+
++#ifdef CONFIG_KVM_COMPAT
++/* for KVM_X86_SET_MSR_FILTER */
++struct kvm_msr_filter_range_compat {
++ __u32 flags;
++ __u32 nmsrs;
++ __u32 base;
++ __u32 bitmap;
++};
++
++struct kvm_msr_filter_compat {
++ __u32 flags;
++ struct kvm_msr_filter_range_compat ranges[KVM_MSR_FILTER_MAX_RANGES];
++};
++
++#define KVM_X86_SET_MSR_FILTER_COMPAT _IOW(KVMIO, 0xc6, struct kvm_msr_filter_compat)
++
++long kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++ unsigned long arg)
++{
++ void __user *argp = (void __user *)arg;
++ struct kvm *kvm = filp->private_data;
++ long r = -ENOTTY;
++
++ switch (ioctl) {
++ case KVM_X86_SET_MSR_FILTER_COMPAT: {
++ struct kvm_msr_filter __user *user_msr_filter = argp;
++ struct kvm_msr_filter_compat filter_compat;
++ struct kvm_msr_filter filter;
++ int i;
++
++ if (copy_from_user(&filter_compat, user_msr_filter,
++ sizeof(filter_compat)))
++ return -EFAULT;
++
++ filter.flags = filter_compat.flags;
++ for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) {
++ struct kvm_msr_filter_range_compat *cr;
++
++ cr = &filter_compat.ranges[i];
++ filter.ranges[i] = (struct kvm_msr_filter_range) {
++ .flags = cr->flags,
++ .nmsrs = cr->nmsrs,
++ .base = cr->base,
++ .bitmap = (__u8 *)(ulong)cr->bitmap,
++ };
++ }
++
++ r = kvm_vm_ioctl_set_msr_filter(kvm, &filter);
++ break;
++ }
++ }
++
++ return r;
++}
++#endif
++
+ #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
+ static int kvm_arch_suspend_notifier(struct kvm *kvm)
+ {
+@@ -6879,9 +6931,16 @@ set_pit2_out:
+ case KVM_SET_PMU_EVENT_FILTER:
+ r = kvm_vm_ioctl_set_pmu_event_filter(kvm, argp);
+ break;
+- case KVM_X86_SET_MSR_FILTER:
+- r = kvm_vm_ioctl_set_msr_filter(kvm, argp);
++ case KVM_X86_SET_MSR_FILTER: {
++ struct kvm_msr_filter __user *user_msr_filter = argp;
++ struct kvm_msr_filter filter;
++
++ if (copy_from_user(&filter, user_msr_filter, sizeof(filter)))
++ return -EFAULT;
++
++ r = kvm_vm_ioctl_set_msr_filter(kvm, &filter);
+ break;
++ }
+ default:
+ r = -ENOTTY;
+ }
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 887b8682eb690..fe840536e6ac4 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3028,8 +3028,11 @@ static void blk_mq_clear_rq_mapping(struct blk_mq_tags *drv_tags,
+ struct page *page;
+ unsigned long flags;
+
+- /* There is no need to clear a driver tags own mapping */
+- if (drv_tags == tags)
++ /*
++ * There is no need to clear mapping if driver tags is not initialized
++ * or the mapping belongs to the driver tags.
++ */
++ if (!drv_tags || drv_tags == tags)
+ return;
+
+ list_for_each_entry(page, &tags->page_list, lru) {
+diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
+index 72f1fb77abcd0..e648158368a7d 100644
+--- a/drivers/acpi/acpi_extlog.c
++++ b/drivers/acpi/acpi_extlog.c
+@@ -12,6 +12,7 @@
+ #include <linux/ratelimit.h>
+ #include <linux/edac.h>
+ #include <linux/ras.h>
++#include <acpi/ghes.h>
+ #include <asm/cpu.h>
+ #include <asm/mce.h>
+
+@@ -138,8 +139,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
+ int cpu = mce->extcpu;
+ struct acpi_hest_generic_status *estatus, *tmp;
+ struct acpi_hest_generic_data *gdata;
+- const guid_t *fru_id = &guid_null;
+- char *fru_text = "";
++ const guid_t *fru_id;
++ char *fru_text;
+ guid_t *sec_type;
+ static u32 err_seq;
+
+@@ -160,17 +161,23 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
+
+ /* log event via trace */
+ err_seq++;
+- gdata = (struct acpi_hest_generic_data *)(tmp + 1);
+- if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+- fru_id = (guid_t *)gdata->fru_id;
+- if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+- fru_text = gdata->fru_text;
+- sec_type = (guid_t *)gdata->section_type;
+- if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
+- struct cper_sec_mem_err *mem = (void *)(gdata + 1);
+- if (gdata->error_data_length >= sizeof(*mem))
+- trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
+- (u8)gdata->error_severity);
++ apei_estatus_for_each_section(tmp, gdata) {
++ if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
++ fru_id = (guid_t *)gdata->fru_id;
++ else
++ fru_id = &guid_null;
++ if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
++ fru_text = gdata->fru_text;
++ else
++ fru_text = "";
++ sec_type = (guid_t *)gdata->section_type;
++ if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
++ struct cper_sec_mem_err *mem = (void *)(gdata + 1);
++
++ if (gdata->error_data_length >= sizeof(*mem))
++ trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
++ (u8)gdata->error_severity);
++ }
+ }
+
+ out:
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 5d7f38016a243..68a566f696845 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -514,6 +514,70 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
+ },
+ },
++ /*
++ * More Tongfang devices with the same issue as the Clevo NL5xRU and
++ * NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description above.
++ */
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GKxNRxx",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GKxNRxx"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GKxNRxx",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++ DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GKxNRxx",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++ DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GKxNRxx",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++ DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GKxNRxx",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++ DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GMxNGxx",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GMxNGxx"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GMxZGxx",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GMxZGxx"),
++ },
++ },
++ {
++ .callback = video_detect_force_native,
++ .ident = "TongFang GMxRGxx",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
++ },
++ },
+ /*
+ * Desktops which falsely report a backlight and which our heuristics
+ * for this do not catch.
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index ad11a4c52fbeb..6f3286c8506d3 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -252,7 +252,7 @@ enum {
+ PCS_7 = 0x94, /* 7+ port PCS (Denverton) */
+
+ /* em constants */
+- EM_MAX_SLOTS = 8,
++ EM_MAX_SLOTS = SATA_PMP_MAX_PORTS,
+ EM_MAX_RETRY = 5,
+
+ /* em_ctl bits */
+diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
+index 79aa9f2853129..20382f3962f50 100644
+--- a/drivers/ata/ahci_imx.c
++++ b/drivers/ata/ahci_imx.c
+@@ -1230,4 +1230,4 @@ module_platform_driver(imx_ahci_driver);
+ MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver");
+ MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>");
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS("ahci:imx");
++MODULE_ALIAS("platform:" DRV_NAME);
+diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
+index 8f7f144e54f3a..7f9bcc82fc9c4 100644
+--- a/drivers/block/drbd/drbd_req.c
++++ b/drivers/block/drbd/drbd_req.c
+@@ -30,11 +30,6 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
+ return NULL;
+ memset(req, 0, sizeof(*req));
+
+- req->private_bio = bio_alloc_clone(device->ldev->backing_bdev, bio_src,
+- GFP_NOIO, &drbd_io_bio_set);
+- req->private_bio->bi_private = req;
+- req->private_bio->bi_end_io = drbd_request_endio;
+-
+ req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0)
+ | (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0)
+ | (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0);
+@@ -1219,9 +1214,12 @@ drbd_request_prepare(struct drbd_device *device, struct bio *bio)
+ /* Update disk stats */
+ req->start_jif = bio_start_io_acct(req->master_bio);
+
+- if (!get_ldev(device)) {
+- bio_put(req->private_bio);
+- req->private_bio = NULL;
++ if (get_ldev(device)) {
++ req->private_bio = bio_alloc_clone(device->ldev->backing_bdev,
++ bio, GFP_NOIO,
++ &drbd_io_bio_set);
++ req->private_bio->bi_private = req;
++ req->private_bio->bi_end_io = drbd_request_endio;
+ }
+
+ /* process discards always from our submitter thread */
+diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+index 863548f59c3e5..82e0339d7722b 100644
+--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+@@ -213,6 +213,7 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+ int speed = 0, pvs = 0, pvs_ver = 0;
+ u8 *speedbin;
+ size_t len;
++ int ret = 0;
+
+ speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+
+@@ -230,7 +231,8 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+ break;
+ default:
+ dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n");
+- return -ENODEV;
++ ret = -ENODEV;
++ goto len_error;
+ }
+
+ snprintf(*pvs_name, sizeof("speedXX-pvsXX-vXX"), "speed%d-pvs%d-v%d",
+@@ -238,8 +240,9 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+
+ drv->versions = (1 << speed);
+
++len_error:
+ kfree(speedbin);
+- return 0;
++ return ret;
+ }
+
+ static const struct qcom_cpufreq_match_data match_data_kryo = {
+@@ -262,7 +265,8 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
+ struct nvmem_cell *speedbin_nvmem;
+ struct device_node *np;
+ struct device *cpu_dev;
+- char *pvs_name = "speedXX-pvsXX-vXX";
++ char pvs_name_buffer[] = "speedXX-pvsXX-vXX";
++ char *pvs_name = pvs_name_buffer;
+ unsigned cpu;
+ const struct of_device_id *match;
+ int ret;
+diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c
+index 1216046cf4c2e..0ea7631d9c27e 100644
+--- a/drivers/cpufreq/tegra194-cpufreq.c
++++ b/drivers/cpufreq/tegra194-cpufreq.c
+@@ -592,6 +592,7 @@ static const struct of_device_id tegra194_cpufreq_of_match[] = {
+ { .compatible = "nvidia,tegra234-ccplex-cluster", .data = &tegra234_cpufreq_soc },
+ { /* sentinel */ }
+ };
++MODULE_DEVICE_TABLE(of, tegra194_cpufreq_of_match);
+
+ static struct platform_driver tegra194_ccplex_driver = {
+ .driver = {
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 56424f75dd2cc..65181efba50ec 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -1504,11 +1504,6 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
+ WREG32_SDMA(i, mmSDMA0_CNTL, temp);
+
+ if (!amdgpu_sriov_vf(adev)) {
+- ring = &adev->sdma.instance[i].ring;
+- adev->nbio.funcs->sdma_doorbell_range(adev, i,
+- ring->use_doorbell, ring->doorbell_index,
+- adev->doorbell_index.sdma_doorbell_range);
+-
+ /* unhalt engine */
+ temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL);
+ temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0);
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
+index 183024d7c184e..e3b2b6b4f1a66 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
+@@ -1211,6 +1211,20 @@ static int soc15_common_sw_fini(void *handle)
+ return 0;
+ }
+
++static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev)
++{
++ int i;
++
++ /* sdma doorbell range is programed by hypervisor */
++ if (!amdgpu_sriov_vf(adev)) {
++ for (i = 0; i < adev->sdma.num_instances; i++) {
++ adev->nbio.funcs->sdma_doorbell_range(adev, i,
++ true, adev->doorbell_index.sdma_engine[i] << 1,
++ adev->doorbell_index.sdma_doorbell_range);
++ }
++ }
++}
++
+ static int soc15_common_hw_init(void *handle)
+ {
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+@@ -1230,6 +1244,13 @@ static int soc15_common_hw_init(void *handle)
+
+ /* enable the doorbell aperture */
+ soc15_enable_doorbell_aperture(adev, true);
++ /* HW doorbell routing policy: doorbell writing not
++ * in SDMA/IH/MM/ACV range will be routed to CP. So
++ * we need to init SDMA doorbell range prior
++ * to CP ip block init and ring test. IH already
++ * happens before CP.
++ */
++ soc15_sdma_doorbell_range_init(adev);
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
+index cb81ed2fbd539..d0c6cf61c676a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
++++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
+@@ -77,7 +77,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_32.o := $(dml_ccflags) $(frame_warn_flag)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_rq_dlg_calc_32.o := $(dml_ccflags)
+-CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags)
++CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags) $(frame_warn_flag)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index 6b8dfa1e7650d..c186ace7f83b9 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -490,6 +490,7 @@ module_init(vc4_drm_register);
+ module_exit(vc4_drm_unregister);
+
+ MODULE_ALIAS("platform:vc4-drm");
++MODULE_SOFTDEP("pre: snd-soc-hdmi-codec");
+ MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
+ MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 1e5f68704d7d8..780a19a75c3f5 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2871,6 +2871,15 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ u32 __maybe_unused value;
+ int ret;
+
++ /*
++ * The HSM clock is in the HDMI power domain, so we need to set
++ * its frequency while the power domain is active so that it
++ * keeps its rate.
++ */
++ ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
++ if (ret)
++ return ret;
++
+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
+ if (ret)
+ return ret;
+diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
+index 664a624a363d0..c9c968d4b36a3 100644
+--- a/drivers/hid/hid-magicmouse.c
++++ b/drivers/hid/hid-magicmouse.c
+@@ -480,7 +480,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
+ magicmouse_raw_event(hdev, report, data + 2, data[1]);
+ magicmouse_raw_event(hdev, report, data + 2 + data[1],
+ size - 2 - data[1]);
+- break;
++ return 0;
+ default:
+ return 0;
+ }
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index ccf0af5b988a7..8bf32c6c85d95 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -46,9 +46,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
+ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
+ #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
+
+-#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id)
+-#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
+-
+ #ifdef CONFIG_SMP
+ #define for_each_sibling(i, cpu) \
+ for_each_cpu(i, topology_sibling_cpumask(cpu))
+@@ -91,6 +88,8 @@ struct temp_data {
+ struct platform_data {
+ struct device *hwmon_dev;
+ u16 pkg_id;
++ u16 cpu_map[NUM_REAL_CORES];
++ struct ida ida;
+ struct cpumask cpumask;
+ struct temp_data *core_data[MAX_CORE_DATA];
+ struct device_attribute name_attr;
+@@ -441,7 +440,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
+ MSR_IA32_THERM_STATUS;
+ tdata->is_pkg_data = pkg_flag;
+ tdata->cpu = cpu;
+- tdata->cpu_core_id = TO_CORE_ID(cpu);
++ tdata->cpu_core_id = topology_core_id(cpu);
+ tdata->attr_size = MAX_CORE_ATTRS;
+ mutex_init(&tdata->update_lock);
+ return tdata;
+@@ -454,7 +453,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ struct platform_data *pdata = platform_get_drvdata(pdev);
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+ u32 eax, edx;
+- int err, attr_no;
++ int err, index, attr_no;
+
+ /*
+ * Find attr number for sysfs:
+@@ -462,14 +461,26 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ * The attr number is always core id + 2
+ * The Pkgtemp will always show up as temp1_*, if available
+ */
+- attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu);
++ if (pkg_flag) {
++ attr_no = PKG_SYSFS_ATTR_NO;
++ } else {
++ index = ida_alloc(&pdata->ida, GFP_KERNEL);
++ if (index < 0)
++ return index;
++ pdata->cpu_map[index] = topology_core_id(cpu);
++ attr_no = index + BASE_SYSFS_ATTR_NO;
++ }
+
+- if (attr_no > MAX_CORE_DATA - 1)
+- return -ERANGE;
++ if (attr_no > MAX_CORE_DATA - 1) {
++ err = -ERANGE;
++ goto ida_free;
++ }
+
+ tdata = init_temp_data(cpu, pkg_flag);
+- if (!tdata)
+- return -ENOMEM;
++ if (!tdata) {
++ err = -ENOMEM;
++ goto ida_free;
++ }
+
+ /* Test if we can access the status register */
+ err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
+@@ -505,6 +516,9 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ exit_free:
+ pdata->core_data[attr_no] = NULL;
+ kfree(tdata);
++ida_free:
++ if (!pkg_flag)
++ ida_free(&pdata->ida, index);
+ return err;
+ }
+
+@@ -524,6 +538,9 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
+
+ kfree(pdata->core_data[indx]);
+ pdata->core_data[indx] = NULL;
++
++ if (indx >= BASE_SYSFS_ATTR_NO)
++ ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
+ }
+
+ static int coretemp_probe(struct platform_device *pdev)
+@@ -537,6 +554,7 @@ static int coretemp_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ pdata->pkg_id = pdev->id;
++ ida_init(&pdata->ida);
+ platform_set_drvdata(pdev, pdata);
+
+ pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
+@@ -553,6 +571,7 @@ static int coretemp_remove(struct platform_device *pdev)
+ if (pdata->core_data[i])
+ coretemp_remove_core(pdata, i);
+
++ ida_destroy(&pdata->ida);
+ return 0;
+ }
+
+@@ -647,7 +666,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ struct platform_device *pdev = coretemp_get_pdev(cpu);
+ struct platform_data *pd;
+ struct temp_data *tdata;
+- int indx, target;
++ int i, indx = -1, target;
+
+ /*
+ * Don't execute this on suspend as the device remove locks
+@@ -660,12 +679,19 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ if (!pdev)
+ return 0;
+
+- /* The core id is too big, just return */
+- indx = TO_ATTR_NO(cpu);
+- if (indx > MAX_CORE_DATA - 1)
++ pd = platform_get_drvdata(pdev);
++
++ for (i = 0; i < NUM_REAL_CORES; i++) {
++ if (pd->cpu_map[i] == topology_core_id(cpu)) {
++ indx = i + BASE_SYSFS_ATTR_NO;
++ break;
++ }
++ }
++
++ /* Too many cores and this core is not populated, just return */
++ if (indx < 0)
+ return 0;
+
+- pd = platform_get_drvdata(pdev);
+ tdata = pd->core_data[indx];
+
+ cpumask_clear_cpu(cpu, &pd->cpumask);
+diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
+index ea48e6a9cfca7..1cf89f885d61e 100644
+--- a/drivers/i2c/busses/i2c-qcom-cci.c
++++ b/drivers/i2c/busses/i2c-qcom-cci.c
+@@ -639,6 +639,11 @@ static int cci_probe(struct platform_device *pdev)
+ if (ret < 0)
+ goto error;
+
++ pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
++ pm_runtime_use_autosuspend(dev);
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
+ for (i = 0; i < cci->data->num_masters; i++) {
+ if (!cci->master[i].cci)
+ continue;
+@@ -650,14 +655,12 @@ static int cci_probe(struct platform_device *pdev)
+ }
+ }
+
+- pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
+- pm_runtime_use_autosuspend(dev);
+- pm_runtime_set_active(dev);
+- pm_runtime_enable(dev);
+-
+ return 0;
+
+ error_i2c:
++ pm_runtime_disable(dev);
++ pm_runtime_dont_use_autosuspend(dev);
++
+ for (--i ; i >= 0; i--) {
+ if (cci->master[i].cci) {
+ i2c_del_adapter(&cci->master[i].adap);
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 31bc50e538a34..ecc0b05b2796c 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2400,6 +2400,7 @@ static int __init si_domain_init(int hw)
+
+ if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
+ domain_exit(si_domain);
++ si_domain = NULL;
+ return -EFAULT;
+ }
+
+@@ -3042,6 +3043,10 @@ free_iommu:
+ disable_dmar_iommu(iommu);
+ free_dmar_iommu(iommu);
+ }
++ if (si_domain) {
++ domain_exit(si_domain);
++ si_domain = NULL;
++ }
+
+ return ret;
+ }
+diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
+index 09c7ed2650ca4..9c5ef818ca365 100644
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -795,7 +795,8 @@ static void __make_buffer_clean(struct dm_buffer *b)
+ {
+ BUG_ON(b->hold_count);
+
+- if (!b->state) /* fast case */
++ /* smp_load_acquire() pairs with read_endio()'s smp_mb__before_atomic() */
++ if (!smp_load_acquire(&b->state)) /* fast case */
+ return;
+
+ wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE);
+@@ -816,7 +817,7 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c)
+ BUG_ON(test_bit(B_DIRTY, &b->state));
+
+ if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep &&
+- unlikely(test_bit(B_READING, &b->state)))
++ unlikely(test_bit_acquire(B_READING, &b->state)))
+ continue;
+
+ if (!b->hold_count) {
+@@ -1058,7 +1059,7 @@ found_buffer:
+ * If the user called both dm_bufio_prefetch and dm_bufio_get on
+ * the same buffer, it would deadlock if we waited.
+ */
+- if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
++ if (nf == NF_GET && unlikely(test_bit_acquire(B_READING, &b->state)))
+ return NULL;
+
+ b->hold_count++;
+@@ -1218,7 +1219,7 @@ void dm_bufio_release(struct dm_buffer *b)
+ * invalid buffer.
+ */
+ if ((b->read_error || b->write_error) &&
+- !test_bit(B_READING, &b->state) &&
++ !test_bit_acquire(B_READING, &b->state) &&
+ !test_bit(B_WRITING, &b->state) &&
+ !test_bit(B_DIRTY, &b->state)) {
+ __unlink_buffer(b);
+@@ -1479,7 +1480,7 @@ EXPORT_SYMBOL_GPL(dm_bufio_release_move);
+
+ static void forget_buffer_locked(struct dm_buffer *b)
+ {
+- if (likely(!b->hold_count) && likely(!b->state)) {
++ if (likely(!b->hold_count) && likely(!smp_load_acquire(&b->state))) {
+ __unlink_buffer(b);
+ __free_buffer_wake(b);
+ }
+@@ -1639,7 +1640,7 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
+ {
+ if (!(gfp & __GFP_FS) ||
+ (static_branch_unlikely(&no_sleep_enabled) && b->c->no_sleep)) {
+- if (test_bit(B_READING, &b->state) ||
++ if (test_bit_acquire(B_READING, &b->state) ||
+ test_bit(B_WRITING, &b->state) ||
+ test_bit(B_DIRTY, &b->state))
+ return false;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 60549b65c799c..b4a2cb5333fcc 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2065,7 +2065,6 @@ static struct mapped_device *alloc_dev(int minor)
+ md->disk->minors = 1;
+ md->disk->flags |= GENHD_FL_NO_PART;
+ md->disk->fops = &dm_blk_dops;
+- md->disk->queue = md->queue;
+ md->disk->private_data = md;
+ sprintf(md->disk->disk_name, "dm-%d", minor);
+
+diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
+index 60de4200375dd..ab6a29ffc81e2 100644
+--- a/drivers/media/platform/qcom/venus/helpers.c
++++ b/drivers/media/platform/qcom/venus/helpers.c
+@@ -1800,7 +1800,7 @@ bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt)
+ struct venus_core *core = inst->core;
+ u32 fmt = to_hfi_raw_fmt(v4l2_pixfmt);
+ struct hfi_plat_caps *caps;
+- u32 buftype;
++ bool found;
+
+ if (!fmt)
+ return false;
+@@ -1809,12 +1809,13 @@ bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt)
+ if (!caps)
+ return false;
+
+- if (inst->session_type == VIDC_SESSION_TYPE_DEC)
+- buftype = HFI_BUFFER_OUTPUT2;
+- else
+- buftype = HFI_BUFFER_OUTPUT;
++ found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt);
++ if (found)
++ goto done;
+
+- return find_fmt_from_caps(caps, buftype, fmt);
++ found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
++done:
++ return found;
+ }
+ EXPORT_SYMBOL_GPL(venus_helper_check_format);
+
+diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
+index ac0bb45d07f4b..4ceaba37e2e57 100644
+--- a/drivers/media/platform/qcom/venus/vdec.c
++++ b/drivers/media/platform/qcom/venus/vdec.c
+@@ -183,6 +183,8 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
+ else
+ return NULL;
+ fmt = find_format(inst, pixmp->pixelformat, f->type);
++ if (!fmt)
++ return NULL;
+ }
+
+ pixmp->width = clamp(pixmp->width, frame_width_min(inst),
+diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
+index 39d2b03e26317..c76ba24c1f559 100644
+--- a/drivers/media/rc/mceusb.c
++++ b/drivers/media/rc/mceusb.c
+@@ -1077,7 +1077,7 @@ static int mceusb_set_timeout(struct rc_dev *dev, unsigned int timeout)
+ struct mceusb_dev *ir = dev->priv;
+ unsigned int units;
+
+- units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT);
++ units = DIV_ROUND_UP(timeout, MCE_TIME_UNIT);
+
+ cmdbuf[2] = units >> 8;
+ cmdbuf[3] = units;
+diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
+index c181346388a41..300c9345ee2be 100644
+--- a/drivers/net/dsa/qca/qca8k-8xxx.c
++++ b/drivers/net/dsa/qca/qca8k-8xxx.c
+@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
+ struct qca8k_mgmt_eth_data *mgmt_eth_data;
+ struct qca8k_priv *priv = ds->priv;
+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
++ u32 command;
+ u8 len, cmd;
++ int i;
+
+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
+ mgmt_eth_data = &priv->mgmt_eth_data;
+
+- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
+- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
++ command = get_unaligned_le32(&mgmt_ethhdr->command);
++ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
++ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
+
+ /* Make sure the seq match the requested packet */
+- if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
++ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
+ mgmt_eth_data->ack = true;
+
+ if (cmd == MDIO_READ) {
+- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
++ u32 *val = mgmt_eth_data->data;
++
++ *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);
+
+ /* Get the rest of the 12 byte of data.
+ * The read/write function will extract the requested data.
+ */
+- if (len > QCA_HDR_MGMT_DATA1_LEN)
+- memcpy(mgmt_eth_data->data + 1, skb->data,
+- QCA_HDR_MGMT_DATA2_LEN);
++ if (len > QCA_HDR_MGMT_DATA1_LEN) {
++ __le32 *data2 = (__le32 *)skb->data;
++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
++ len - QCA_HDR_MGMT_DATA1_LEN);
++
++ val++;
++
++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
++ *val = get_unaligned_le32(data2);
++ val++;
++ data2++;
++ }
++ }
+ }
+
+ complete(&mgmt_eth_data->rw_done);
+@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
+ unsigned int real_len;
+ struct sk_buff *skb;
+- u32 *data2;
++ __le32 *data2;
++ u32 command;
+ u16 hdr;
++ int i;
+
+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
+ if (!skb)
+@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
+
+- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
+- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
+- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
+- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
++ command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
++ command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
++ command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
++ command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
+ QCA_HDR_MGMT_CHECK_CODE_VAL);
+
++ put_unaligned_le32(command, &mgmt_ethhdr->command);
++
+ if (cmd == MDIO_WRITE)
+- mgmt_ethhdr->mdio_data = *val;
++ put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data);
+
+ mgmt_ethhdr->hdr = htons(hdr);
+
+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
+- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
+- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
++ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) {
++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
++ len - QCA_HDR_MGMT_DATA1_LEN);
++
++ val++;
++
++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
++ put_unaligned_le32(*val, data2);
++ data2++;
++ val++;
++ }
++ }
+
+ return skb;
+ }
+@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
+ {
+ struct qca_mgmt_ethhdr *mgmt_ethhdr;
++ u32 seq;
+
++ seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
+- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
++ put_unaligned_le32(seq, &mgmt_ethhdr->seq);
+ }
+
+ static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
+@@ -1487,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
+ struct qca8k_priv *priv = ds->priv;
+ const struct qca8k_mib_desc *mib;
+ struct mib_ethhdr *mib_ethhdr;
+- int i, mib_len, offset = 0;
+- u64 *data;
++ __le32 *data2;
+ u8 port;
++ int i;
+
+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
+ mib_eth_data = &priv->mib_eth_data;
+@@ -1501,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
+ if (port != mib_eth_data->req_port)
+ goto exit;
+
+- data = mib_eth_data->data;
++ data2 = (__le32 *)skb->data;
+
+ for (i = 0; i < priv->info->mib_count; i++) {
+ mib = &ar8327_mib[i];
+
+ /* First 3 mib are present in the skb head */
+ if (i < 3) {
+- data[i] = mib_ethhdr->data[i];
++ mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i);
+ continue;
+ }
+
+- mib_len = sizeof(uint32_t);
+-
+ /* Some mib are 64 bit wide */
+ if (mib->size == 2)
+- mib_len = sizeof(uint64_t);
+-
+- /* Copy the mib value from packet to the */
+- memcpy(data + i, skb->data + offset, mib_len);
++ mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2);
++ else
++ mib_eth_data->data[i] = get_unaligned_le32(data2);
+
+- /* Set the offset for the next mib */
+- offset += mib_len;
++ data2 += mib->size;
+ }
+
+ exit:
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+index a36803e79e92e..8a6f788f62944 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+@@ -613,6 +613,7 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti
+
+ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
+ {
++ bool rc = false;
+ u32 datalen;
+ u16 index;
+ u8 *buf;
+@@ -632,20 +633,20 @@ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
+
+ if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
+ NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
+- goto err;
++ goto done;
+ }
+
+ if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
+ BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
+ NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
+- goto err;
++ goto done;
+ }
+
+- return true;
++ rc = true;
+
+-err:
++done:
+ kfree(buf);
+- return false;
++ return rc;
+ }
+
+ static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
+diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
+index 00fafc0f85121..430eccea8e5e9 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
++++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
+@@ -419,8 +419,10 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
+ hdev->cls_dev.release = hnae_release;
+ (void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
+ ret = device_register(&hdev->cls_dev);
+- if (ret)
++ if (ret) {
++ put_device(&hdev->cls_dev);
+ return ret;
++ }
+
+ __module_get(THIS_MODULE);
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index e9cd0fa6a0d2f..af5fe84db5961 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -2181,9 +2181,6 @@ static int i40e_set_ringparam(struct net_device *netdev,
+ */
+ rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS;
+ err = i40e_setup_rx_descriptors(&rx_rings[i]);
+- if (err)
+- goto rx_unwind;
+- err = i40e_alloc_rx_bi(&rx_rings[i]);
+ if (err)
+ goto rx_unwind;
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index e3d9804aeb25e..b3336d31f8a9d 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -3565,12 +3565,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
+ if (ring->vsi->type == I40E_VSI_MAIN)
+ xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
+
+- kfree(ring->rx_bi);
+ ring->xsk_pool = i40e_xsk_pool(ring);
+ if (ring->xsk_pool) {
+- ret = i40e_alloc_rx_bi_zc(ring);
+- if (ret)
+- return ret;
+ ring->rx_buf_len =
+ xsk_pool_get_rx_frame_size(ring->xsk_pool);
+ /* For AF_XDP ZC, we disallow packets to span on
+@@ -3588,9 +3584,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
+ ring->queue_index);
+
+ } else {
+- ret = i40e_alloc_rx_bi(ring);
+- if (ret)
+- return ret;
+ ring->rx_buf_len = vsi->rx_buf_len;
+ if (ring->vsi->type == I40E_VSI_MAIN) {
+ ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
+@@ -13304,6 +13297,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
+ i40e_reset_and_rebuild(pf, true, true);
+ }
+
++ if (!i40e_enabled_xdp_vsi(vsi) && prog) {
++ if (i40e_realloc_rx_bi_zc(vsi, true))
++ return -ENOMEM;
++ } else if (i40e_enabled_xdp_vsi(vsi) && !prog) {
++ if (i40e_realloc_rx_bi_zc(vsi, false))
++ return -ENOMEM;
++ }
++
+ for (i = 0; i < vsi->num_queue_pairs; i++)
+ WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
+
+@@ -13536,6 +13537,7 @@ int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair)
+
+ i40e_queue_pair_disable_irq(vsi, queue_pair);
+ err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */);
++ i40e_clean_rx_ring(vsi->rx_rings[queue_pair]);
+ i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */);
+ i40e_queue_pair_clean_rings(vsi, queue_pair);
+ i40e_queue_pair_reset_stats(vsi, queue_pair);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+index 69e67eb6aea72..b97c95f89fa02 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+@@ -1457,14 +1457,6 @@ err:
+ return -ENOMEM;
+ }
+
+-int i40e_alloc_rx_bi(struct i40e_ring *rx_ring)
+-{
+- unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count;
+-
+- rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL);
+- return rx_ring->rx_bi ? 0 : -ENOMEM;
+-}
+-
+ static void i40e_clear_rx_bi(struct i40e_ring *rx_ring)
+ {
+ memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count);
+@@ -1593,6 +1585,11 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
+
+ rx_ring->xdp_prog = rx_ring->vsi->xdp_prog;
+
++ rx_ring->rx_bi =
++ kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL);
++ if (!rx_ring->rx_bi)
++ return -ENOMEM;
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+index 41f86e9535a00..768290dc6f48b 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+@@ -469,7 +469,6 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
+ bool __i40e_chk_linearize(struct sk_buff *skb);
+ int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
+ u32 flags);
+-int i40e_alloc_rx_bi(struct i40e_ring *rx_ring);
+
+ /**
+ * i40e_get_head - Retrieve head from head writeback
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+index 6d4009e0cbd62..cd7b52fb6b46c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+@@ -10,14 +10,6 @@
+ #include "i40e_txrx_common.h"
+ #include "i40e_xsk.h"
+
+-int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring)
+-{
+- unsigned long sz = sizeof(*rx_ring->rx_bi_zc) * rx_ring->count;
+-
+- rx_ring->rx_bi_zc = kzalloc(sz, GFP_KERNEL);
+- return rx_ring->rx_bi_zc ? 0 : -ENOMEM;
+-}
+-
+ void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring)
+ {
+ memset(rx_ring->rx_bi_zc, 0,
+@@ -29,6 +21,58 @@ static struct xdp_buff **i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx)
+ return &rx_ring->rx_bi_zc[idx];
+ }
+
++/**
++ * i40e_realloc_rx_xdp_bi - reallocate SW ring for either XSK or normal buffer
++ * @rx_ring: Current rx ring
++ * @pool_present: is pool for XSK present
++ *
++ * Try allocating memory and return ENOMEM, if failed to allocate.
++ * If allocation was successful, substitute buffer with allocated one.
++ * Returns 0 on success, negative on failure
++ */
++static int i40e_realloc_rx_xdp_bi(struct i40e_ring *rx_ring, bool pool_present)
++{
++ size_t elem_size = pool_present ? sizeof(*rx_ring->rx_bi_zc) :
++ sizeof(*rx_ring->rx_bi);
++ void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL);
++
++ if (!sw_ring)
++ return -ENOMEM;
++
++ if (pool_present) {
++ kfree(rx_ring->rx_bi);
++ rx_ring->rx_bi = NULL;
++ rx_ring->rx_bi_zc = sw_ring;
++ } else {
++ kfree(rx_ring->rx_bi_zc);
++ rx_ring->rx_bi_zc = NULL;
++ rx_ring->rx_bi = sw_ring;
++ }
++ return 0;
++}
++
++/**
++ * i40e_realloc_rx_bi_zc - reallocate rx SW rings
++ * @vsi: Current VSI
++ * @zc: is zero copy set
++ *
++ * Reallocate buffer for rx_rings that might be used by XSK.
++ * XDP requires more memory, than rx_buf provides.
++ * Returns 0 on success, negative on failure
++ */
++int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc)
++{
++ struct i40e_ring *rx_ring;
++ unsigned long q;
++
++ for_each_set_bit(q, vsi->af_xdp_zc_qps, vsi->alloc_queue_pairs) {
++ rx_ring = vsi->rx_rings[q];
++ if (i40e_realloc_rx_xdp_bi(rx_ring, zc))
++ return -ENOMEM;
++ }
++ return 0;
++}
++
+ /**
+ * i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a
+ * certain ring/qid
+@@ -69,6 +113,10 @@ static int i40e_xsk_pool_enable(struct i40e_vsi *vsi,
+ if (err)
+ return err;
+
++ err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], true);
++ if (err)
++ return err;
++
+ err = i40e_queue_pair_enable(vsi, qid);
+ if (err)
+ return err;
+@@ -113,6 +161,9 @@ static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid)
+ xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR);
+
+ if (if_running) {
++ err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], false);
++ if (err)
++ return err;
+ err = i40e_queue_pair_enable(vsi, qid);
+ if (err)
+ return err;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.h b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
+index bb962987f300a..821df248f8bee 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
+@@ -32,7 +32,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget);
+
+ bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring);
+ int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags);
+-int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring);
++int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc);
+ void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring);
+
+ #endif /* _I40E_XSK_H_ */
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index b344632beaddf..84433f3a3e228 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4028,19 +4028,23 @@ static int mtk_probe(struct platform_device *pdev)
+ eth->irq[i] = platform_get_irq(pdev, i);
+ if (eth->irq[i] < 0) {
+ dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
+- return -ENXIO;
++ err = -ENXIO;
++ goto err_wed_exit;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(eth->clks); i++) {
+ eth->clks[i] = devm_clk_get(eth->dev,
+ mtk_clks_source_name[i]);
+ if (IS_ERR(eth->clks[i])) {
+- if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
+- return -EPROBE_DEFER;
++ if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) {
++ err = -EPROBE_DEFER;
++ goto err_wed_exit;
++ }
+ if (eth->soc->required_clks & BIT(i)) {
+ dev_err(&pdev->dev, "clock %s not found\n",
+ mtk_clks_source_name[i]);
+- return -EINVAL;
++ err = -EINVAL;
++ goto err_wed_exit;
+ }
+ eth->clks[i] = NULL;
+ }
+@@ -4051,7 +4055,7 @@ static int mtk_probe(struct platform_device *pdev)
+
+ err = mtk_hw_init(eth);
+ if (err)
+- return err;
++ goto err_wed_exit;
+
+ eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO);
+
+@@ -4140,6 +4144,8 @@ err_free_dev:
+ mtk_free_dev(eth);
+ err_deinit_hw:
+ mtk_hw_deinit(eth);
++err_wed_exit:
++ mtk_wed_exit();
+
+ return err;
+ }
+@@ -4159,6 +4165,7 @@ static int mtk_remove(struct platform_device *pdev)
+ phylink_disconnect_phy(mac->phylink);
+ }
+
++ mtk_wed_exit();
+ mtk_hw_deinit(eth);
+
+ netif_napi_del(ð->tx_napi);
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 29be2fcafea3b..614147ad6116a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -808,16 +808,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+
+ pdev = of_find_device_by_node(np);
+ if (!pdev)
+- return;
++ goto err_of_node_put;
+
+ get_device(&pdev->dev);
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+- return;
++ goto err_put_device;
+
+ regs = syscon_regmap_lookup_by_phandle(np, NULL);
+ if (IS_ERR(regs))
+- return;
++ goto err_put_device;
+
+ rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
+
+@@ -853,8 +853,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+
+ hw_list[index] = hw;
+
++ mutex_unlock(&hw_lock);
++
++ return;
++
+ unlock:
+ mutex_unlock(&hw_lock);
++err_put_device:
++ put_device(&pdev->dev);
++err_of_node_put:
++ of_node_put(np);
+ }
+
+ void mtk_wed_exit(void)
+@@ -875,6 +883,7 @@ void mtk_wed_exit(void)
+ hw_list[i] = NULL;
+ debugfs_remove(hw->debugfs_dir);
+ put_device(hw->dev);
++ of_node_put(hw->node);
+ kfree(hw);
+ }
+ }
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+index 0be79c5167813..6ae6d79193a3c 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+@@ -2820,11 +2820,15 @@ err_out:
+ * than the full array, but leave the qcq shells in place
+ */
+ for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) {
+- lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
+- ionic_qcq_free(lif, lif->txqcqs[i]);
++ if (lif->txqcqs && lif->txqcqs[i]) {
++ lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
++ ionic_qcq_free(lif, lif->txqcqs[i]);
++ }
+
+- lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
+- ionic_qcq_free(lif, lif->rxqcqs[i]);
++ if (lif->rxqcqs && lif->rxqcqs[i]) {
++ lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
++ ionic_qcq_free(lif, lif->rxqcqs[i]);
++ }
+ }
+
+ if (err)
+diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
+index d1e1aa19a68ed..7022fb2005a2f 100644
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -3277,6 +3277,30 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
+ bool was_enabled = efx->port_enabled;
+ int rc;
+
++#ifdef CONFIG_SFC_SRIOV
++ /* If this function is a VF and we have access to the parent PF,
++ * then use the PF control path to attempt to change the VF MAC address.
++ */
++ if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
++ struct efx_nic *efx_pf = pci_get_drvdata(efx->pci_dev->physfn);
++ struct efx_ef10_nic_data *nic_data = efx->nic_data;
++ u8 mac[ETH_ALEN];
++
++ /* net_dev->dev_addr can be zeroed by efx_net_stop in
++ * efx_ef10_sriov_set_vf_mac, so pass in a copy.
++ */
++ ether_addr_copy(mac, efx->net_dev->dev_addr);
++
++ rc = efx_ef10_sriov_set_vf_mac(efx_pf, nic_data->vf_index, mac);
++ if (!rc)
++ return 0;
++
++ netif_dbg(efx, drv, efx->net_dev,
++ "Updating VF mac via PF failed (%d), setting directly\n",
++ rc);
++ }
++#endif
++
+ efx_device_detach_sync(efx);
+ efx_net_stop(efx->net_dev);
+
+@@ -3297,40 +3321,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
+ efx_net_open(efx->net_dev);
+ efx_device_attach_if_not_resetting(efx);
+
+-#ifdef CONFIG_SFC_SRIOV
+- if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
+- struct efx_ef10_nic_data *nic_data = efx->nic_data;
+- struct pci_dev *pci_dev_pf = efx->pci_dev->physfn;
+-
+- if (rc == -EPERM) {
+- struct efx_nic *efx_pf;
+-
+- /* Switch to PF and change MAC address on vport */
+- efx_pf = pci_get_drvdata(pci_dev_pf);
+-
+- rc = efx_ef10_sriov_set_vf_mac(efx_pf,
+- nic_data->vf_index,
+- efx->net_dev->dev_addr);
+- } else if (!rc) {
+- struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
+- struct efx_ef10_nic_data *nic_data = efx_pf->nic_data;
+- unsigned int i;
+-
+- /* MAC address successfully changed by VF (with MAC
+- * spoofing) so update the parent PF if possible.
+- */
+- for (i = 0; i < efx_pf->vf_count; ++i) {
+- struct ef10_vf *vf = nic_data->vf + i;
+-
+- if (vf->efx == efx) {
+- ether_addr_copy(vf->mac,
+- efx->net_dev->dev_addr);
+- return 0;
+- }
+- }
+- }
+- } else
+-#endif
+ if (rc == -EPERM) {
+ netif_err(efx, drv, efx->net_dev,
+ "Cannot change MAC address; use sfboot to enable"
+diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
+index 4d928839d2922..f569d07ef2676 100644
+--- a/drivers/net/ethernet/sfc/filter.h
++++ b/drivers/net/ethernet/sfc/filter.h
+@@ -161,9 +161,9 @@ struct efx_filter_spec {
+ u32 priority:2;
+ u32 flags:6;
+ u32 dmaq_id:12;
+- u32 vport_id;
+ u32 rss_context;
+- __be16 outer_vid __aligned(4); /* allow jhash2() of match values */
++ u32 vport_id;
++ __be16 outer_vid;
+ __be16 inner_vid;
+ u8 loc_mac[ETH_ALEN];
+ u8 rem_mac[ETH_ALEN];
+diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
+index 4826e6a7e4ce3..9220afeddee81 100644
+--- a/drivers/net/ethernet/sfc/rx_common.c
++++ b/drivers/net/ethernet/sfc/rx_common.c
+@@ -660,17 +660,17 @@ bool efx_filter_spec_equal(const struct efx_filter_spec *left,
+ (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
+ return false;
+
+- return memcmp(&left->outer_vid, &right->outer_vid,
++ return memcmp(&left->vport_id, &right->vport_id,
+ sizeof(struct efx_filter_spec) -
+- offsetof(struct efx_filter_spec, outer_vid)) == 0;
++ offsetof(struct efx_filter_spec, vport_id)) == 0;
+ }
+
+ u32 efx_filter_spec_hash(const struct efx_filter_spec *spec)
+ {
+- BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
+- return jhash2((const u32 *)&spec->outer_vid,
++ BUILD_BUG_ON(offsetof(struct efx_filter_spec, vport_id) & 3);
++ return jhash2((const u32 *)&spec->vport_id,
+ (sizeof(struct efx_filter_spec) -
+- offsetof(struct efx_filter_spec, outer_vid)) / 4,
++ offsetof(struct efx_filter_spec, vport_id)) / 4,
+ 0);
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 9083159b93f14..bc060ef558d37 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1214,6 +1214,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
+ if (priv->plat->tx_queues_to_use > 1)
+ priv->phylink_config.mac_capabilities &=
+ ~(MAC_10HD | MAC_100HD | MAC_1000HD);
++ priv->phylink_config.mac_managed_pm = true;
+
+ phylink = phylink_create(&priv->phylink_config, fwnode,
+ mode, &stmmac_phylink_mac_ops);
+diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
+index 8549e0e356c9b..b60db8b6f4774 100644
+--- a/drivers/net/phy/dp83822.c
++++ b/drivers/net/phy/dp83822.c
+@@ -254,8 +254,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
+ DP83822_EEE_ERROR_CHANGE_INT_EN);
+
+ if (!dp83822->fx_enabled)
+- misr_status |= DP83822_MDI_XOVER_INT_EN |
+- DP83822_ANEG_ERR_INT_EN |
++ misr_status |= DP83822_ANEG_ERR_INT_EN |
+ DP83822_WOL_PKT_INT_EN;
+
+ err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
+diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
+index 6939563d3b7c5..417527f8bbf55 100644
+--- a/drivers/net/phy/dp83867.c
++++ b/drivers/net/phy/dp83867.c
+@@ -853,6 +853,14 @@ static int dp83867_config_init(struct phy_device *phydev)
+ else
+ val &= ~DP83867_SGMII_TYPE;
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
++
++ /* This is a SW workaround for link instability if RX_CTRL is
++ * not strapped to mode 3 or 4 in HW. This is required for SGMII
++ * in addition to clearing bit 7, handled above.
++ */
++ if (dp83867->rxctrl_strap_quirk)
++ phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
++ BIT(8));
+ }
+
+ val = phy_read(phydev, DP83867_CFG3);
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index 9bd69328dc4d4..7bbbe69a7b0af 100644
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -1431,6 +1431,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
+ if (phy_interrupt_is_valid(phy))
+ phy_request_interrupt(phy);
+
++ if (pl->config->mac_managed_pm)
++ phy->mac_managed_pm = true;
++
+ return 0;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index e5b1f6249763a..9c92f20c4aeb4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -152,6 +152,7 @@ static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr)
+ { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */
+ { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */
+ { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */
++ { 0x74030000, 0x10000, 0x10000 }, /* PCIE_MAC_IREG */
+ { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */
+ { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */
+ { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+index 5efda694fb9d5..19facf31e4e14 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+@@ -59,6 +59,8 @@ int mt7921e_mcu_init(struct mt7921_dev *dev)
+ if (err)
+ return err;
+
++ mt76_rmw_field(dev, MT_PCIE_MAC_PM, MT_PCIE_MAC_PM_L0S_DIS, 1);
++
+ err = mt7921_run_firmware(dev);
+
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
+index ea643260ceb66..c65582acfa55d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
+@@ -440,6 +440,8 @@
+ #define MT_PCIE_MAC_BASE 0x10000
+ #define MT_PCIE_MAC(ofs) (MT_PCIE_MAC_BASE + (ofs))
+ #define MT_PCIE_MAC_INT_ENABLE MT_PCIE_MAC(0x188)
++#define MT_PCIE_MAC_PM MT_PCIE_MAC(0x194)
++#define MT_PCIE_MAC_PM_L0S_DIS BIT(8)
+
+ #define MT_DMA_SHDL(ofs) (0x7c026000 + (ofs))
+ #define MT_DMASHDL_SW_CONTROL MT_DMA_SHDL(0x004)
+diff --git a/drivers/net/wwan/wwan_hwsim.c b/drivers/net/wwan/wwan_hwsim.c
+index fad642f9ffd8d..857a55b625fea 100644
+--- a/drivers/net/wwan/wwan_hwsim.c
++++ b/drivers/net/wwan/wwan_hwsim.c
+@@ -311,7 +311,7 @@ err_unreg_dev:
+ return ERR_PTR(err);
+
+ err_free_dev:
+- kfree(dev);
++ put_device(&dev->dev);
+
+ return ERR_PTR(err);
+ }
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 59e4b188fc71c..ed47c256dbd27 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3256,8 +3256,12 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
+ return ret;
+
+ if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
++ /*
++ * Do not return errors unless we are in a controller reset,
++ * the controller works perfectly fine without hwmon.
++ */
+ ret = nvme_hwmon_init(ctrl);
+- if (ret < 0)
++ if (ret == -EINTR)
+ return ret;
+ }
+
+diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c
+index 0a586d7129201..9e6e56c20ec99 100644
+--- a/drivers/nvme/host/hwmon.c
++++ b/drivers/nvme/host/hwmon.c
+@@ -12,7 +12,7 @@
+
+ struct nvme_hwmon_data {
+ struct nvme_ctrl *ctrl;
+- struct nvme_smart_log log;
++ struct nvme_smart_log *log;
+ struct mutex read_lock;
+ };
+
+@@ -60,14 +60,14 @@ static int nvme_set_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under,
+ static int nvme_hwmon_get_smart_log(struct nvme_hwmon_data *data)
+ {
+ return nvme_get_log(data->ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0,
+- NVME_CSI_NVM, &data->log, sizeof(data->log), 0);
++ NVME_CSI_NVM, data->log, sizeof(*data->log), 0);
+ }
+
+ static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+ {
+ struct nvme_hwmon_data *data = dev_get_drvdata(dev);
+- struct nvme_smart_log *log = &data->log;
++ struct nvme_smart_log *log = data->log;
+ int temp;
+ int err;
+
+@@ -163,7 +163,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
+ case hwmon_temp_max:
+ case hwmon_temp_min:
+ if ((!channel && data->ctrl->wctemp) ||
+- (channel && data->log.temp_sensor[channel - 1])) {
++ (channel && data->log->temp_sensor[channel - 1])) {
+ if (data->ctrl->quirks &
+ NVME_QUIRK_NO_TEMP_THRESH_CHANGE)
+ return 0444;
+@@ -176,7 +176,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
+ break;
+ case hwmon_temp_input:
+ case hwmon_temp_label:
+- if (!channel || data->log.temp_sensor[channel - 1])
++ if (!channel || data->log->temp_sensor[channel - 1])
+ return 0444;
+ break;
+ default:
+@@ -230,7 +230,13 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+- return 0;
++ return -ENOMEM;
++
++ data->log = kzalloc(sizeof(*data->log), GFP_KERNEL);
++ if (!data->log) {
++ err = -ENOMEM;
++ goto err_free_data;
++ }
+
+ data->ctrl = ctrl;
+ mutex_init(&data->read_lock);
+@@ -238,8 +244,7 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+ err = nvme_hwmon_get_smart_log(data);
+ if (err) {
+ dev_warn(dev, "Failed to read smart log (error %d)\n", err);
+- kfree(data);
+- return err;
++ goto err_free_log;
+ }
+
+ hwmon = hwmon_device_register_with_info(dev, "nvme",
+@@ -247,11 +252,17 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+ NULL);
+ if (IS_ERR(hwmon)) {
+ dev_warn(dev, "Failed to instantiate hwmon device\n");
+- kfree(data);
+- return PTR_ERR(hwmon);
++ err = PTR_ERR(hwmon);
++ goto err_free_log;
+ }
+ ctrl->hwmon_device = hwmon;
+ return 0;
++
++err_free_log:
++ kfree(data->log);
++err_free_data:
++ kfree(data);
++ return err;
+ }
+
+ void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
+@@ -262,6 +273,7 @@ void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
+
+ hwmon_device_unregister(ctrl->hwmon_device);
+ ctrl->hwmon_device = NULL;
++ kfree(data->log);
+ kfree(data);
+ }
+ }
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 14677145bbba0..aecb5853f8da4 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -1176,7 +1176,7 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl)
+ * reset the keep alive timer when the controller is enabled.
+ */
+ if (ctrl->kato)
+- mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ);
++ mod_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ);
+ }
+
+ static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl)
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 700eb19e84500..fc326fdf483fb 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -635,6 +635,13 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
+ struct rtc_time tm;
+ int rc;
+
++ /* we haven't yet read SMU version */
++ if (!pdev->major) {
++ rc = amd_pmc_get_smu_version(pdev);
++ if (rc)
++ return rc;
++ }
++
+ if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
+ return 0;
+
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 1a02134438fcc..47e210095315e 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -4822,7 +4822,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+ rc = lpfc_vmid_res_alloc(phba, vport);
+
+ if (rc)
+- goto out;
++ goto out_put_shost;
+
+ /* Initialize all internally managed lists. */
+ INIT_LIST_HEAD(&vport->fc_nodes);
+@@ -4840,16 +4840,17 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+
+ error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
+ if (error)
+- goto out_put_shost;
++ goto out_free_vmid;
+
+ spin_lock_irq(&phba->port_list_lock);
+ list_add_tail(&vport->listentry, &phba->port_list);
+ spin_unlock_irq(&phba->port_list_lock);
+ return vport;
+
+-out_put_shost:
++out_free_vmid:
+ kfree(vport->vmid);
+ bitmap_free(vport->vmid_priority_range);
++out_put_shost:
+ scsi_host_put(shost);
+ out:
+ return NULL;
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index d1c539cefba87..2234bb8d48b34 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -192,33 +192,30 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+ {
+- struct v4l2_rect *try_sel, *r;
+- struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
+- struct imgu_v4l2_subdev,
+- subdev);
++ struct imgu_v4l2_subdev *imgu_sd =
++ container_of(sd, struct imgu_v4l2_subdev, subdev);
+
+ if (sel->pad != IMGU_NODE_IN)
+ return -EINVAL;
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
+- r = &imgu_sd->rect.eff;
+- break;
++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++ sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
++ sel->pad);
++ else
++ sel->r = imgu_sd->rect.eff;
++ return 0;
+ case V4L2_SEL_TGT_COMPOSE:
+- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
+- r = &imgu_sd->rect.bds;
+- break;
++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++ sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
++ sel->pad);
++ else
++ sel->r = imgu_sd->rect.bds;
++ return 0;
+ default:
+ return -EINVAL;
+ }
+-
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- sel->r = *try_sel;
+- else
+- sel->r = *r;
+-
+- return 0;
+ }
+
+ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 101e13c2cf41c..9223d3d4089f1 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -357,6 +357,17 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
+ if (ret)
+ return ret;
+
++ /*
++ * If a driver asked to unregister a platform device registered by
++ * sysfb, then can be assumed that this is a driver for a display
++ * that is set up by the system firmware and has a generic driver.
++ *
++ * Drivers for devices that don't have a generic driver will never
++ * ask for this, so let's assume that a real driver for the display
++ * was already probed and prevent sysfb to register devices later.
++ */
++ sysfb_disable();
++
+ /*
+ * WARNING: Apparently we must kick fbdev drivers before vgacon,
+ * otherwise the vga fbdev driver falls over.
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index d385357e19b61..ccc818b409774 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -138,6 +138,7 @@ struct share_check {
+ u64 root_objectid;
+ u64 inum;
+ int share_count;
++ bool have_delayed_delete_refs;
+ };
+
+ static inline int extent_is_shared(struct share_check *sc)
+@@ -820,16 +821,11 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ struct preftrees *preftrees, struct share_check *sc)
+ {
+ struct btrfs_delayed_ref_node *node;
+- struct btrfs_delayed_extent_op *extent_op = head->extent_op;
+ struct btrfs_key key;
+- struct btrfs_key tmp_op_key;
+ struct rb_node *n;
+ int count;
+ int ret = 0;
+
+- if (extent_op && extent_op->update_key)
+- btrfs_disk_key_to_cpu(&tmp_op_key, &extent_op->key);
+-
+ spin_lock(&head->lock);
+ for (n = rb_first_cached(&head->ref_tree); n; n = rb_next(n)) {
+ node = rb_entry(n, struct btrfs_delayed_ref_node,
+@@ -855,10 +851,16 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ case BTRFS_TREE_BLOCK_REF_KEY: {
+ /* NORMAL INDIRECT METADATA backref */
+ struct btrfs_delayed_tree_ref *ref;
++ struct btrfs_key *key_ptr = NULL;
++
++ if (head->extent_op && head->extent_op->update_key) {
++ btrfs_disk_key_to_cpu(&key, &head->extent_op->key);
++ key_ptr = &key;
++ }
+
+ ref = btrfs_delayed_node_to_tree_ref(node);
+ ret = add_indirect_ref(fs_info, preftrees, ref->root,
+- &tmp_op_key, ref->level + 1,
++ key_ptr, ref->level + 1,
+ node->bytenr, count, sc,
+ GFP_ATOMIC);
+ break;
+@@ -884,13 +886,22 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ key.offset = ref->offset;
+
+ /*
+- * Found a inum that doesn't match our known inum, we
+- * know it's shared.
++ * If we have a share check context and a reference for
++ * another inode, we can't exit immediately. This is
++ * because even if this is a BTRFS_ADD_DELAYED_REF
++ * reference we may find next a BTRFS_DROP_DELAYED_REF
++ * which cancels out this ADD reference.
++ *
++ * If this is a DROP reference and there was no previous
++ * ADD reference, then we need to signal that when we
++ * process references from the extent tree (through
++ * add_inline_refs() and add_keyed_refs()), we should
++ * not exit early if we find a reference for another
++ * inode, because one of the delayed DROP references
++ * may cancel that reference in the extent tree.
+ */
+- if (sc && sc->inum && ref->objectid != sc->inum) {
+- ret = BACKREF_FOUND_SHARED;
+- goto out;
+- }
++ if (sc && count < 0)
++ sc->have_delayed_delete_refs = true;
+
+ ret = add_indirect_ref(fs_info, preftrees, ref->root,
+ &key, 0, node->bytenr, count, sc,
+@@ -920,7 +931,7 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ }
+ if (!ret)
+ ret = extent_is_shared(sc);
+-out:
++
+ spin_unlock(&head->lock);
+ return ret;
+ }
+@@ -1023,7 +1034,8 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
+ key.type = BTRFS_EXTENT_DATA_KEY;
+ key.offset = btrfs_extent_data_ref_offset(leaf, dref);
+
+- if (sc && sc->inum && key.objectid != sc->inum) {
++ if (sc && sc->inum && key.objectid != sc->inum &&
++ !sc->have_delayed_delete_refs) {
+ ret = BACKREF_FOUND_SHARED;
+ break;
+ }
+@@ -1033,6 +1045,7 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
+ ret = add_indirect_ref(fs_info, preftrees, root,
+ &key, 0, bytenr, count,
+ sc, GFP_NOFS);
++
+ break;
+ }
+ default:
+@@ -1122,7 +1135,8 @@ static int add_keyed_refs(struct btrfs_root *extent_root,
+ key.type = BTRFS_EXTENT_DATA_KEY;
+ key.offset = btrfs_extent_data_ref_offset(leaf, dref);
+
+- if (sc && sc->inum && key.objectid != sc->inum) {
++ if (sc && sc->inum && key.objectid != sc->inum &&
++ !sc->have_delayed_delete_refs) {
+ ret = BACKREF_FOUND_SHARED;
+ break;
+ }
+@@ -1544,6 +1558,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
+ .root_objectid = root->root_key.objectid,
+ .inum = inum,
+ .share_count = 0,
++ .have_delayed_delete_refs = false,
+ };
+
+ ulist_init(roots);
+@@ -1578,6 +1593,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
+ break;
+ bytenr = node->val;
+ shared.share_count = 0;
++ shared.have_delayed_delete_refs = false;
+ cond_resched();
+ }
+
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 8042d7280dec1..6bc8be9ed2a56 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1297,8 +1297,11 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
+ ssize_t rc;
+ struct cifsFileInfo *cfile = dst_file->private_data;
+
+- if (cfile->swapfile)
+- return -EOPNOTSUPP;
++ if (cfile->swapfile) {
++ rc = -EOPNOTSUPP;
++ free_xid(xid);
++ return rc;
++ }
+
+ rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
+ len, flags);
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 08f7392716e2f..05c78a18ade07 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -551,8 +551,10 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
+ inode, direntry, direntry);
+
+- if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
+- return -EIO;
++ if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
++ rc = -EIO;
++ goto out_free_xid;
++ }
+
+ tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
+ rc = PTR_ERR(tlink);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 7d756721e1a68..5c045dd697846 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -1882,11 +1882,13 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+ struct cifsFileInfo *cfile;
+ __u32 type;
+
+- rc = -EACCES;
+ xid = get_xid();
+
+- if (!(fl->fl_flags & FL_FLOCK))
+- return -ENOLCK;
++ if (!(fl->fl_flags & FL_FLOCK)) {
++ rc = -ENOLCK;
++ free_xid(xid);
++ return rc;
++ }
+
+ cfile = (struct cifsFileInfo *)file->private_data;
+ tcon = tlink_tcon(cfile->tlink);
+@@ -1905,8 +1907,9 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+ * if no lock or unlock then nothing to do since we do not
+ * know what it is
+ */
++ rc = -EOPNOTSUPP;
+ free_xid(xid);
+- return -EOPNOTSUPP;
++ return rc;
+ }
+
+ rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 3af3b05b6c740..11cd06aa74f0a 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -496,6 +496,7 @@ out:
+ cifs_put_tcp_session(chan->server, 0);
+ }
+
++ free_xid(xid);
+ return rc;
+ }
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index b02552e5f3eeb..14376437187ae 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -530,6 +530,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ p = buf;
+
+ spin_lock(&ses->iface_lock);
++ ses->iface_count = 0;
+ /*
+ * Go through iface_list and do kref_put to remove
+ * any unused ifaces. ifaces in use will be removed
+@@ -650,9 +651,9 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ kref_put(&iface->refcount, release_iface);
+ } else
+ list_add_tail(&info->iface_head, &ses->iface_list);
+- spin_unlock(&ses->iface_lock);
+
+ ses->iface_count++;
++ spin_unlock(&ses->iface_lock);
+ ses->iface_last_update = jiffies;
+ next_iface:
+ nb_iface++;
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 5016d742576d0..92a1d0695ebdf 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1526,7 +1526,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
+ &blob_length, ses, server,
+ sess_data->nls_cp);
+ if (rc)
+- goto out_err;
++ goto out;
+
+ if (use_spnego) {
+ /* BB eventually need to add this */
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index 5792ca9e0d5ef..6e663275aeb13 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -838,15 +838,13 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be,
+
+ if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK)) {
+ unsigned int pgnr;
+- struct page *oldpage;
+
+ pgnr = (bvec->offset + be->pcl->pageofs_out) >> PAGE_SHIFT;
+ DBG_BUGON(pgnr >= be->nr_pages);
+- oldpage = be->decompressed_pages[pgnr];
+- be->decompressed_pages[pgnr] = bvec->page;
+-
+- if (!oldpage)
++ if (!be->decompressed_pages[pgnr]) {
++ be->decompressed_pages[pgnr] = bvec->page;
+ return;
++ }
+ }
+
+ /* (cold path) one pcluster is requested multiple times */
+diff --git a/fs/erofs/zdata.h b/fs/erofs/zdata.h
+index e7f04c4fbb81c..d98c952129852 100644
+--- a/fs/erofs/zdata.h
++++ b/fs/erofs/zdata.h
+@@ -126,10 +126,10 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl)
+ }
+
+ /*
+- * bit 31: I/O error occurred on this page
+- * bit 0 - 30: remaining parts to complete this page
++ * bit 30: I/O error occurred on this page
++ * bit 0 - 29: remaining parts to complete this page
+ */
+-#define Z_EROFS_PAGE_EIO (1 << 31)
++#define Z_EROFS_PAGE_EIO (1 << 30)
+
+ static inline void z_erofs_onlinepage_init(struct page *page)
+ {
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index b26f304baa52e..e5d20da585287 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -710,10 +710,10 @@ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ * After allocating len, we should have space at least for a 0 byte
+ * padding.
+ */
+- if (len + sizeof(struct ext4_fc_tl) > bsize)
++ if (len + EXT4_FC_TAG_BASE_LEN > bsize)
+ return NULL;
+
+- if (bsize - off - 1 > len + sizeof(struct ext4_fc_tl)) {
++ if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) {
+ /*
+ * Only allocate from current buffer if we have enough space for
+ * this request AND we have space to add a zero byte padding.
+@@ -730,10 +730,10 @@ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ /* Need to add PAD tag */
+ tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off);
+ tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
+- pad_len = bsize - off - 1 - sizeof(struct ext4_fc_tl);
++ pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN;
+ tl->fc_len = cpu_to_le16(pad_len);
+ if (crc)
+- *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl));
++ *crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN);
+ if (pad_len > 0)
+ ext4_fc_memzero(sb, tl + 1, pad_len, crc);
+ ext4_fc_submit_bh(sb, false);
+@@ -775,7 +775,7 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ * ext4_fc_reserve_space takes care of allocating an extra block if
+ * there's no enough space on this block for accommodating this tail.
+ */
+- dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(tail), &crc);
++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + sizeof(tail), &crc);
+ if (!dst)
+ return -ENOSPC;
+
+@@ -785,8 +785,8 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail));
+ sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize);
+
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), &crc);
+- dst += sizeof(tl);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ tail.fc_tid = cpu_to_le32(sbi->s_journal->j_running_transaction->t_tid);
+ ext4_fc_memcpy(sb, dst, &tail.fc_tid, sizeof(tail.fc_tid), &crc);
+ dst += sizeof(tail.fc_tid);
+@@ -808,15 +808,15 @@ static bool ext4_fc_add_tlv(struct super_block *sb, u16 tag, u16 len, u8 *val,
+ struct ext4_fc_tl tl;
+ u8 *dst;
+
+- dst = ext4_fc_reserve_space(sb, sizeof(tl) + len, crc);
++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + len, crc);
+ if (!dst)
+ return false;
+
+ tl.fc_tag = cpu_to_le16(tag);
+ tl.fc_len = cpu_to_le16(len);
+
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+- ext4_fc_memcpy(sb, dst + sizeof(tl), val, len, crc);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ ext4_fc_memcpy(sb, dst + EXT4_FC_TAG_BASE_LEN, val, len, crc);
+
+ return true;
+ }
+@@ -828,8 +828,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ struct ext4_fc_dentry_info fcd;
+ struct ext4_fc_tl tl;
+ int dlen = fc_dentry->fcd_name.len;
+- u8 *dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(fcd) + dlen,
+- crc);
++ u8 *dst = ext4_fc_reserve_space(sb,
++ EXT4_FC_TAG_BASE_LEN + sizeof(fcd) + dlen, crc);
+
+ if (!dst)
+ return false;
+@@ -838,8 +838,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ fcd.fc_ino = cpu_to_le32(fc_dentry->fcd_ino);
+ tl.fc_tag = cpu_to_le16(fc_dentry->fcd_op);
+ tl.fc_len = cpu_to_le16(sizeof(fcd) + dlen);
+- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+- dst += sizeof(tl);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ ext4_fc_memcpy(sb, dst, &fcd, sizeof(fcd), crc);
+ dst += sizeof(fcd);
+ ext4_fc_memcpy(sb, dst, fc_dentry->fcd_name.name, dlen, crc);
+@@ -876,13 +876,13 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc)
+
+ ret = -ECANCELED;
+ dst = ext4_fc_reserve_space(inode->i_sb,
+- sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc);
++ EXT4_FC_TAG_BASE_LEN + inode_len + sizeof(fc_inode.fc_ino), crc);
+ if (!dst)
+ goto err;
+
+- if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc))
++ if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc))
+ goto err;
+- dst += sizeof(tl);
++ dst += EXT4_FC_TAG_BASE_LEN;
+ if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc))
+ goto err;
+ dst += sizeof(fc_inode);
+@@ -1346,7 +1346,7 @@ struct dentry_info_args {
+ };
+
+ static inline void tl_to_darg(struct dentry_info_args *darg,
+- struct ext4_fc_tl *tl, u8 *val)
++ struct ext4_fc_tl *tl, u8 *val)
+ {
+ struct ext4_fc_dentry_info fcd;
+
+@@ -1355,8 +1355,14 @@ static inline void tl_to_darg(struct dentry_info_args *darg,
+ darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
+ darg->ino = le32_to_cpu(fcd.fc_ino);
+ darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
+- darg->dname_len = le16_to_cpu(tl->fc_len) -
+- sizeof(struct ext4_fc_dentry_info);
++ darg->dname_len = tl->fc_len - sizeof(struct ext4_fc_dentry_info);
++}
++
++static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val)
++{
++ memcpy(tl, val, EXT4_FC_TAG_BASE_LEN);
++ tl->fc_len = le16_to_cpu(tl->fc_len);
++ tl->fc_tag = le16_to_cpu(tl->fc_tag);
+ }
+
+ /* Unlink replay function */
+@@ -1521,7 +1527,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ struct ext4_inode *raw_fc_inode;
+ struct inode *inode = NULL;
+ struct ext4_iloc iloc;
+- int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
++ int inode_len, ino, ret, tag = tl->fc_tag;
+ struct ext4_extent_header *eh;
+
+ memcpy(&fc_inode, val, sizeof(fc_inode));
+@@ -1546,7 +1552,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ if (ret)
+ goto out;
+
+- inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
++ inode_len = tl->fc_len - sizeof(struct ext4_fc_inode);
+ raw_inode = ext4_raw_inode(&iloc);
+
+ memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
+@@ -1980,6 +1986,34 @@ void ext4_fc_replay_cleanup(struct super_block *sb)
+ kfree(sbi->s_fc_replay_state.fc_modified_inodes);
+ }
+
++static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl,
++ u8 *val, u8 *end)
++{
++ if (val + tl->fc_len > end)
++ return false;
++
++ /* Here only check ADD_RANGE/TAIL/HEAD which will read data when do
++ * journal rescan before do CRC check. Other tags length check will
++ * rely on CRC check.
++ */
++ switch (tl->fc_tag) {
++ case EXT4_FC_TAG_ADD_RANGE:
++ return (sizeof(struct ext4_fc_add_range) == tl->fc_len);
++ case EXT4_FC_TAG_TAIL:
++ return (sizeof(struct ext4_fc_tail) <= tl->fc_len);
++ case EXT4_FC_TAG_HEAD:
++ return (sizeof(struct ext4_fc_head) == tl->fc_len);
++ case EXT4_FC_TAG_DEL_RANGE:
++ case EXT4_FC_TAG_LINK:
++ case EXT4_FC_TAG_UNLINK:
++ case EXT4_FC_TAG_CREAT:
++ case EXT4_FC_TAG_INODE:
++ case EXT4_FC_TAG_PAD:
++ default:
++ return true;
++ }
++}
++
+ /*
+ * Recovery Scan phase handler
+ *
+@@ -2036,12 +2070,18 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ }
+
+ state->fc_replay_expected_off++;
+- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+- memcpy(&tl, cur, sizeof(tl));
+- val = cur + sizeof(tl);
++ for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++ ext4_fc_get_tl(&tl, cur);
++ val = cur + EXT4_FC_TAG_BASE_LEN;
++ if (!ext4_fc_tag_len_isvalid(&tl, val, end)) {
++ ret = state->fc_replay_num_tags ?
++ JBD2_FC_REPLAY_STOP : -ECANCELED;
++ goto out_err;
++ }
+ ext4_debug("Scan phase, tag:%s, blk %lld\n",
+- tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
+- switch (le16_to_cpu(tl.fc_tag)) {
++ tag2str(tl.fc_tag), bh->b_blocknr);
++ switch (tl.fc_tag) {
+ case EXT4_FC_TAG_ADD_RANGE:
+ memcpy(&ext, val, sizeof(ext));
+ ex = (struct ext4_extent *)&ext.fc_ex;
+@@ -2061,13 +2101,13 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ case EXT4_FC_TAG_PAD:
+ state->fc_cur_tag++;
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) + le16_to_cpu(tl.fc_len));
++ EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ break;
+ case EXT4_FC_TAG_TAIL:
+ state->fc_cur_tag++;
+ memcpy(&tail, val, sizeof(tail));
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) +
++ EXT4_FC_TAG_BASE_LEN +
+ offsetof(struct ext4_fc_tail,
+ fc_crc));
+ if (le32_to_cpu(tail.fc_tid) == expected_tid &&
+@@ -2094,7 +2134,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ }
+ state->fc_cur_tag++;
+ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+- sizeof(tl) + le16_to_cpu(tl.fc_len));
++ EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ break;
+ default:
+ ret = state->fc_replay_num_tags ?
+@@ -2149,19 +2189,20 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ start = (u8 *)bh->b_data;
+ end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
+
+- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+- memcpy(&tl, cur, sizeof(tl));
+- val = cur + sizeof(tl);
++ for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++ ext4_fc_get_tl(&tl, cur);
++ val = cur + EXT4_FC_TAG_BASE_LEN;
+
+ if (state->fc_replay_num_tags == 0) {
+ ret = JBD2_FC_REPLAY_STOP;
+ ext4_fc_set_bitmaps_and_counters(sb);
+ break;
+ }
+- ext4_debug("Replay phase, tag:%s\n",
+- tag2str(le16_to_cpu(tl.fc_tag)));
++
++ ext4_debug("Replay phase, tag:%s\n", tag2str(tl.fc_tag));
+ state->fc_replay_num_tags--;
+- switch (le16_to_cpu(tl.fc_tag)) {
++ switch (tl.fc_tag) {
+ case EXT4_FC_TAG_LINK:
+ ret = ext4_fc_replay_link(sb, &tl, val);
+ break;
+@@ -2182,19 +2223,18 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ break;
+ case EXT4_FC_TAG_PAD:
+ trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
+- le16_to_cpu(tl.fc_len), 0);
++ tl.fc_len, 0);
+ break;
+ case EXT4_FC_TAG_TAIL:
+- trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
+- le16_to_cpu(tl.fc_len), 0);
++ trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL,
++ 0, tl.fc_len, 0);
+ memcpy(&tail, val, sizeof(tail));
+ WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
+ break;
+ case EXT4_FC_TAG_HEAD:
+ break;
+ default:
+- trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
+- le16_to_cpu(tl.fc_len), 0);
++ trace_ext4_fc_replay(sb, tl.fc_tag, 0, tl.fc_len, 0);
+ ret = -ECANCELED;
+ break;
+ }
+diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
+index 1db12847a83b6..a6154c3ed1357 100644
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -70,6 +70,9 @@ struct ext4_fc_tail {
+ __le32 fc_crc;
+ };
+
++/* Tag base length */
++#define EXT4_FC_TAG_BASE_LEN (sizeof(struct ext4_fc_tl))
++
+ /*
+ * Fast commit status codes
+ */
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 961d1cf54388e..05f32989bad6f 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -232,6 +232,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
+ handle_t *handle = NULL;
+ struct ocfs2_super *osb;
+ struct ocfs2_dinode *dirfe;
++ struct ocfs2_dinode *fe = NULL;
+ struct buffer_head *new_fe_bh = NULL;
+ struct inode *inode = NULL;
+ struct ocfs2_alloc_context *inode_ac = NULL;
+@@ -382,6 +383,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
+ goto leave;
+ }
+
++ fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
+ if (S_ISDIR(mode)) {
+ status = ocfs2_fill_new_dir(osb, handle, dir, inode,
+ new_fe_bh, data_ac, meta_ac);
+@@ -454,8 +456,11 @@ roll_back:
+ leave:
+ if (status < 0 && did_quota_inode)
+ dquot_free_inode(inode);
+- if (handle)
++ if (handle) {
++ if (status < 0 && fe)
++ ocfs2_set_links_count(fe, 0);
+ ocfs2_commit_trans(osb, handle);
++ }
+
+ ocfs2_inode_unlock(dir, 1);
+ if (did_block_signals)
+@@ -632,18 +637,9 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
+ return status;
+ }
+
+- status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
++ return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
+ parent_fe_bh, handle, inode_ac,
+ fe_blkno, suballoc_loc, suballoc_bit);
+- if (status < 0) {
+- u64 bg_blkno = ocfs2_which_suballoc_group(fe_blkno, suballoc_bit);
+- int tmp = ocfs2_free_suballoc_bits(handle, inode_ac->ac_inode,
+- inode_ac->ac_bh, suballoc_bit, bg_blkno, 1);
+- if (tmp)
+- mlog_errno(tmp);
+- }
+-
+- return status;
+ }
+
+ static int ocfs2_mkdir(struct user_namespace *mnt_userns,
+@@ -2028,8 +2024,11 @@ bail:
+ ocfs2_clusters_to_bytes(osb->sb, 1));
+ if (status < 0 && did_quota_inode)
+ dquot_free_inode(inode);
+- if (handle)
++ if (handle) {
++ if (status < 0 && fe)
++ ocfs2_set_links_count(fe, 0);
+ ocfs2_commit_trans(osb, handle);
++ }
+
+ ocfs2_inode_unlock(dir, 1);
+ if (did_block_signals)
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 4e0023643f8be..1e7bbc0873a42 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -969,7 +969,7 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
+ vma = vma->vm_next;
+ }
+
+- show_vma_header_prefix(m, priv->mm->mmap->vm_start,
++ show_vma_header_prefix(m, priv->mm->mmap ? priv->mm->mmap->vm_start : 0,
+ last_vma_end, 0, 0, 0, 0);
+ seq_pad(m, ' ');
+ seq_puts(m, "[rollup]\n");
+diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h
+index 50be7cbd93a5b..b1b5720d89a59 100644
+--- a/include/linux/dsa/tag_qca.h
++++ b/include/linux/dsa/tag_qca.h
+@@ -61,9 +61,9 @@ struct sk_buff;
+
+ /* Special struct emulating a Ethernet header */
+ struct qca_mgmt_ethhdr {
+- u32 command; /* command bit 31:0 */
+- u32 seq; /* seq 63:32 */
+- u32 mdio_data; /* first 4byte mdio */
++ __le32 command; /* command bit 31:0 */
++ __le32 seq; /* seq 63:32 */
++ __le32 mdio_data; /* first 4byte mdio */
+ __be16 hdr; /* qca hdr */
+ } __packed;
+
+@@ -73,7 +73,7 @@ enum mdio_cmd {
+ };
+
+ struct mib_ethhdr {
+- u32 data[3]; /* first 3 mib counter */
++ __le32 data[3]; /* first 3 mib counter */
+ __be16 hdr; /* qca hdr */
+ } __packed;
+
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index f4519d3689e10..7a40f9bdc173e 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -1391,6 +1391,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
+ struct kvm_enable_cap *cap);
+ long kvm_arch_vm_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg);
++long kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++ unsigned long arg);
+
+ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+diff --git a/include/linux/phylink.h b/include/linux/phylink.h
+index 6d06896fc20d8..a3adf7fe7eaf4 100644
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -88,6 +88,7 @@ enum phylink_op_type {
+ * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
+ * @poll_fixed_state: if true, starts link_poll,
+ * if MAC link is at %MLO_AN_FIXED mode.
++ * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM.
+ * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
+ * @get_fixed_state: callback to execute to determine the fixed link state,
+ * if MAC link is at %MLO_AN_FIXED mode.
+@@ -100,6 +101,7 @@ struct phylink_config {
+ enum phylink_op_type type;
+ bool legacy_pre_march2020;
+ bool poll_fixed_state;
++ bool mac_managed_pm;
+ bool ovr_an_inband;
+ void (*get_fixed_state)(struct phylink_config *config,
+ struct phylink_link_state *state);
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index ec693fe7c5539..f2958fb5ae08b 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -1137,7 +1137,6 @@ static inline void __qdisc_reset_queue(struct qdisc_skb_head *qh)
+ static inline void qdisc_reset_queue(struct Qdisc *sch)
+ {
+ __qdisc_reset_queue(&sch->q);
+- sch->qstats.backlog = 0;
+ }
+
+ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
+diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
+index 473b0b0fa4abc..efc9085c68927 100644
+--- a/include/net/sock_reuseport.h
++++ b/include/net/sock_reuseport.h
+@@ -43,21 +43,20 @@ struct sock *reuseport_migrate_sock(struct sock *sk,
+ extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
+ extern int reuseport_detach_prog(struct sock *sk);
+
+-static inline bool reuseport_has_conns(struct sock *sk, bool set)
++static inline bool reuseport_has_conns(struct sock *sk)
+ {
+ struct sock_reuseport *reuse;
+ bool ret = false;
+
+ rcu_read_lock();
+ reuse = rcu_dereference(sk->sk_reuseport_cb);
+- if (reuse) {
+- if (set)
+- reuse->has_conns = 1;
+- ret = reuse->has_conns;
+- }
++ if (reuse && reuse->has_conns)
++ ret = true;
+ rcu_read_unlock();
+
+ return ret;
+ }
+
++void reuseport_has_conns_set(struct sock *sk);
++
+ #endif /* _SOCK_REUSEPORT_H */
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 45809ae6f64ef..5121b20a91936 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -229,12 +229,12 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
+
+ static inline bool io_run_task_work(void)
+ {
+- if (test_thread_flag(TIF_NOTIFY_SIGNAL)) {
++ if (task_work_pending(current)) {
++ if (test_thread_flag(TIF_NOTIFY_SIGNAL))
++ clear_notify_signal();
+ __set_current_state(TASK_RUNNING);
+- clear_notify_signal();
+- if (task_work_pending(current))
+- task_work_run();
+- return true;
++ task_work_run();
++ return 1;
+ }
+
+ return false;
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 4a7e5d030c782..90d2fc6fd80e4 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -95,6 +95,9 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
+
+ msg->src_fd = array_index_nospec(msg->src_fd, ctx->nr_user_files);
+ file_ptr = io_fixed_file_slot(&ctx->file_table, msg->src_fd)->file_ptr;
++ if (!file_ptr)
++ goto out_unlock;
++
+ src_file = (struct file *) (file_ptr & FFS_MASK);
+ get_file(src_file);
+
+diff --git a/io_uring/rw.c b/io_uring/rw.c
+index 60c08a944e2fb..93d7cb5eb9fe5 100644
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -192,8 +192,6 @@ static void io_req_io_end(struct io_kiocb *req)
+ {
+ struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+
+- WARN_ON(!in_task());
+-
+ if (rw->kiocb.ki_flags & IOCB_WRITE) {
+ kiocb_end_write(req);
+ fsnotify_modify(req->file);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 513b523ba75b3..ecc197d24efb7 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -2928,11 +2928,11 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
+ page = alloc_buddy_huge_page_with_mpol(h, vma, addr);
+ if (!page)
+ goto out_uncharge_cgroup;
++ spin_lock_irq(&hugetlb_lock);
+ if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
+ SetHPageRestoreReserve(page);
+ h->resv_huge_pages--;
+ }
+- spin_lock_irq(&hugetlb_lock);
+ list_add(&page->lru, &h->hugepage_activelist);
+ /* Fall through */
+ }
+diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
+index 829db9eba0cb9..aaf64b9539150 100644
+--- a/net/atm/mpoa_proc.c
++++ b/net/atm/mpoa_proc.c
+@@ -219,11 +219,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
+ if (!page)
+ return -ENOMEM;
+
+- for (p = page, len = 0; len < nbytes; p++, len++) {
++ for (p = page, len = 0; len < nbytes; p++) {
+ if (get_user(*p, buff++)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
++ len += 1;
+ if (*p == '\0' || *p == '\n')
+ break;
+ }
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 56c8b0921c9fd..2c14f48d24573 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -5136,11 +5136,13 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
+ case TC_ACT_SHOT:
+ mini_qdisc_qstats_cpu_drop(miniq);
+ kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS);
++ *ret = NET_RX_DROP;
+ return NULL;
+ case TC_ACT_STOLEN:
+ case TC_ACT_QUEUED:
+ case TC_ACT_TRAP:
+ consume_skb(skb);
++ *ret = NET_RX_SUCCESS;
+ return NULL;
+ case TC_ACT_REDIRECT:
+ /* skb_mac_header check was done by cls/act_bpf, so
+@@ -5153,8 +5155,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
+ *another = true;
+ break;
+ }
++ *ret = NET_RX_SUCCESS;
+ return NULL;
+ case TC_ACT_CONSUMED:
++ *ret = NET_RX_SUCCESS;
+ return NULL;
+ default:
+ break;
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index ca70525621c71..1efdc47a999b4 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -500,11 +500,11 @@ bool sk_msg_is_readable(struct sock *sk)
+ }
+ EXPORT_SYMBOL_GPL(sk_msg_is_readable);
+
+-static struct sk_msg *alloc_sk_msg(void)
++static struct sk_msg *alloc_sk_msg(gfp_t gfp)
+ {
+ struct sk_msg *msg;
+
+- msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_KERNEL);
++ msg = kzalloc(sizeof(*msg), gfp | __GFP_NOWARN);
+ if (unlikely(!msg))
+ return NULL;
+ sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS);
+@@ -520,7 +520,7 @@ static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk,
+ if (!sk_rmem_schedule(sk, skb, skb->truesize))
+ return NULL;
+
+- return alloc_sk_msg();
++ return alloc_sk_msg(GFP_KERNEL);
+ }
+
+ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
+@@ -597,7 +597,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
+ u32 off, u32 len)
+ {
+- struct sk_msg *msg = alloc_sk_msg();
++ struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC);
+ struct sock *sk = psock->sk;
+ int err;
+
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index 5daa1fa542490..fb90e1e00773b 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -21,6 +21,22 @@ static DEFINE_IDA(reuseport_ida);
+ static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse,
+ struct sock_reuseport *reuse, bool bind_inany);
+
++void reuseport_has_conns_set(struct sock *sk)
++{
++ struct sock_reuseport *reuse;
++
++ if (!rcu_access_pointer(sk->sk_reuseport_cb))
++ return;
++
++ spin_lock_bh(&reuseport_lock);
++ reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
++ lockdep_is_held(&reuseport_lock));
++ if (likely(reuse))
++ reuse->has_conns = 1;
++ spin_unlock_bh(&reuseport_lock);
++}
++EXPORT_SYMBOL(reuseport_has_conns_set);
++
+ static int reuseport_sock_index(struct sock *sk,
+ const struct sock_reuseport *reuse,
+ bool closed)
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 5bf357734b113..a50429a62f744 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -150,15 +150,15 @@ struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
+ struct hsr_port *port)
+ {
+ if (!frame->skb_std) {
+- if (frame->skb_hsr) {
++ if (frame->skb_hsr)
+ frame->skb_std =
+ create_stripped_skb_hsr(frame->skb_hsr, frame);
+- } else {
+- /* Unexpected */
+- WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n",
+- __FILE__, __LINE__, port->dev->name);
++ else
++ netdev_warn_once(port->dev,
++ "Unexpected frame received in hsr_get_untagged_frame()\n");
++
++ if (!frame->skb_std)
+ return NULL;
+- }
+ }
+
+ return skb_clone(frame->skb_std, GFP_ATOMIC);
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index 405a8c2aea641..5e66add7befac 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -70,7 +70,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
+ }
+ inet->inet_daddr = fl4->daddr;
+ inet->inet_dport = usin->sin_port;
+- reuseport_has_conns(sk, true);
++ reuseport_has_conns_set(sk);
+ sk->sk_state = TCP_ESTABLISHED;
+ sk_set_txhash(sk);
+ inet->inet_id = prandom_u32();
+diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
+index 8cd3224d913e0..26b3b0e2adcd7 100644
+--- a/net/ipv4/netfilter/ipt_rpfilter.c
++++ b/net/ipv4/netfilter/ipt_rpfilter.c
+@@ -78,7 +78,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
+ flow.flowi4_tos = iph->tos & IPTOS_RT_MASK;
+ flow.flowi4_scope = RT_SCOPE_UNIVERSE;
+- flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par));
++ flow.flowi4_l3mdev = l3mdev_master_ifindex_rcu(xt_in(par));
++ flow.flowi4_uid = sock_net_uid(xt_net(par), NULL);
+
+ return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
+ }
+diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c
+index 7ade04ff972d7..fc65d69f23e16 100644
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ struct flowi4 fl4 = {
+ .flowi4_scope = RT_SCOPE_UNIVERSE,
+ .flowi4_iif = LOOPBACK_IFINDEX,
++ .flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
+ };
+ const struct net_device *oif;
+ const struct net_device *found;
+@@ -84,7 +85,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ oif = NULL;
+
+ if (priv->flags & NFTA_FIB_F_IIF)
+- fl4.flowi4_oif = l3mdev_master_ifindex_rcu(oif);
++ fl4.flowi4_l3mdev = l3mdev_master_ifindex_rcu(oif);
+
+ if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
+ nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 516b11c136daf..d9099754ac69d 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -448,7 +448,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
+ result = lookup_reuseport(net, sk, skb,
+ saddr, sport, daddr, hnum);
+ /* Fall back to scoring if group has connections */
+- if (result && !reuseport_has_conns(sk, false))
++ if (result && !reuseport_has_conns(sk))
+ return result;
+
+ result = result ? : sk;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 10ce86bf228e1..d5967cba5b568 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -7214,9 +7214,11 @@ err_reg_dflt:
+ __addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
+ err_reg_all:
+ kfree(dflt);
++ net->ipv6.devconf_dflt = NULL;
+ #endif
+ err_alloc_dflt:
+ kfree(all);
++ net->ipv6.devconf_all = NULL;
+ err_alloc_all:
+ kfree(net->ipv6.inet6_addr_lst);
+ err_alloc_addr:
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index df665d4e8f0f1..5ecb56522f9d6 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -256,7 +256,7 @@ ipv4_connected:
+ goto out;
+ }
+
+- reuseport_has_conns(sk, true);
++ reuseport_has_conns_set(sk);
+ sk->sk_state = TCP_ESTABLISHED;
+ sk_set_txhash(sk);
+ out:
+diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
+index d800801a5dd27..a01d9b842bd07 100644
+--- a/net/ipv6/netfilter/ip6t_rpfilter.c
++++ b/net/ipv6/netfilter/ip6t_rpfilter.c
+@@ -37,8 +37,10 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ bool ret = false;
+ struct flowi6 fl6 = {
+ .flowi6_iif = LOOPBACK_IFINDEX,
++ .flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev),
+ .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
+ .flowi6_proto = iph->nexthdr,
++ .flowi6_uid = sock_net_uid(net, NULL),
+ .daddr = iph->saddr,
+ };
+ int lookup_flags;
+@@ -55,9 +57,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ if (rpfilter_addr_linklocal(&iph->saddr)) {
+ lookup_flags |= RT6_LOOKUP_F_IFACE;
+ fl6.flowi6_oif = dev->ifindex;
+- /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
+- } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
+- (flags & XT_RPFILTER_LOOSE) == 0)
++ } else if ((flags & XT_RPFILTER_LOOSE) == 0)
+ fl6.flowi6_oif = dev->ifindex;
+
+ rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
+@@ -72,9 +72,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ goto out;
+ }
+
+- if (rt->rt6i_idev->dev == dev ||
+- l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex ||
+- (flags & XT_RPFILTER_LOOSE))
++ if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE))
+ ret = true;
+ out:
+ ip6_rt_put(rt);
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index 1d7e520d9966c..36dc14b34388c 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -41,9 +41,8 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
+ if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
+ lookup_flags |= RT6_LOOKUP_F_IFACE;
+ fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
+- } else if ((priv->flags & NFTA_FIB_F_IIF) &&
+- (netif_is_l3_master(dev) || netif_is_l3_slave(dev))) {
+- fl6->flowi6_oif = dev->ifindex;
++ } else if (priv->flags & NFTA_FIB_F_IIF) {
++ fl6->flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
+ }
+
+ if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
+@@ -67,6 +66,7 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
+ struct flowi6 fl6 = {
+ .flowi6_iif = LOOPBACK_IFINDEX,
+ .flowi6_proto = pkt->tprot,
++ .flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+ };
+ u32 ret = 0;
+
+@@ -164,6 +164,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ struct flowi6 fl6 = {
+ .flowi6_iif = LOOPBACK_IFINDEX,
+ .flowi6_proto = pkt->tprot,
++ .flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+ };
+ struct rt6_info *rt;
+ int lookup_flags;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 3366d6a77ff29..fb667e02e9760 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -182,7 +182,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
+ result = lookup_reuseport(net, sk, skb,
+ saddr, sport, daddr, hnum);
+ /* Fall back to scoring if group has connections */
+- if (result && !reuseport_has_conns(sk, false))
++ if (result && !reuseport_has_conns(sk))
+ return result;
+
+ result = result ? : sk;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 63c70141b3e5d..5897afd124668 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5865,8 +5865,9 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set,
+ (NFT_SET_CONCAT | NFT_SET_INTERVAL)) {
+ if (flags & NFT_SET_ELEM_INTERVAL_END)
+ return false;
+- if (!nla[NFTA_SET_ELEM_KEY_END] &&
+- !(flags & NFT_SET_ELEM_CATCHALL))
++
++ if (nla[NFTA_SET_ELEM_KEY_END] &&
++ flags & NFT_SET_ELEM_CATCHALL)
+ return false;
+ } else {
+ if (nla[NFTA_SET_ELEM_KEY_END])
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index bf87b50837a84..67ee8ae3f310b 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -1081,12 +1081,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
+
+ skip:
+ if (!ingress) {
+- notify_and_destroy(net, skb, n, classid,
+- rtnl_dereference(dev->qdisc), new);
++ old = rtnl_dereference(dev->qdisc);
+ if (new && !new->ops->attach)
+ qdisc_refcount_inc(new);
+ rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc);
+
++ notify_and_destroy(net, skb, n, classid, old, new);
++
+ if (new && new->ops->attach)
+ new->ops->attach(new);
+ } else {
+diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
+index 4c8e994cf0a53..816fd0d7ba38a 100644
+--- a/net/sched/sch_atm.c
++++ b/net/sched/sch_atm.c
+@@ -577,7 +577,6 @@ static void atm_tc_reset(struct Qdisc *sch)
+ pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
+ list_for_each_entry(flow, &p->flows, list)
+ qdisc_reset(flow->q);
+- sch->q.qlen = 0;
+ }
+
+ static void atm_tc_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
+index a43a58a73d096..9530d65e6002a 100644
+--- a/net/sched/sch_cake.c
++++ b/net/sched/sch_cake.c
+@@ -2224,8 +2224,12 @@ retry:
+
+ static void cake_reset(struct Qdisc *sch)
+ {
++ struct cake_sched_data *q = qdisc_priv(sch);
+ u32 c;
+
++ if (!q->tins)
++ return;
++
+ for (c = 0; c < CAKE_MAX_TINS; c++)
+ cake_clear_tin(sch, c);
+ }
+diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
+index 91a0dc463c482..ba99ce05cd527 100644
+--- a/net/sched/sch_cbq.c
++++ b/net/sched/sch_cbq.c
+@@ -975,7 +975,6 @@ cbq_reset(struct Qdisc *sch)
+ cl->cpriority = cl->priority;
+ }
+ }
+- sch->q.qlen = 0;
+ }
+
+
+diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
+index 2adbd945bf15a..25d2daaa81227 100644
+--- a/net/sched/sch_choke.c
++++ b/net/sched/sch_choke.c
+@@ -315,8 +315,6 @@ static void choke_reset(struct Qdisc *sch)
+ rtnl_qdisc_drop(skb, sch);
+ }
+
+- sch->q.qlen = 0;
+- sch->qstats.backlog = 0;
+ if (q->tab)
+ memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *));
+ q->head = q->tail = 0;
+diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
+index 18e4f7a0b2912..4e5b1cf11b858 100644
+--- a/net/sched/sch_drr.c
++++ b/net/sched/sch_drr.c
+@@ -441,8 +441,6 @@ static void drr_reset_qdisc(struct Qdisc *sch)
+ qdisc_reset(cl->qdisc);
+ }
+ }
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void drr_destroy_qdisc(struct Qdisc *sch)
+diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
+index 4c100d1052699..7da6dc38a3828 100644
+--- a/net/sched/sch_dsmark.c
++++ b/net/sched/sch_dsmark.c
+@@ -409,8 +409,6 @@ static void dsmark_reset(struct Qdisc *sch)
+ pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
+ if (p->q)
+ qdisc_reset(p->q);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void dsmark_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c
+index c48f91075b5c6..d96103b0e2bf5 100644
+--- a/net/sched/sch_etf.c
++++ b/net/sched/sch_etf.c
+@@ -445,9 +445,6 @@ static void etf_reset(struct Qdisc *sch)
+ timesortedlist_clear(sch);
+ __qdisc_reset_queue(&sch->q);
+
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+-
+ q->last = 0;
+ }
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index d733934935533..8de4365886e84 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -727,8 +727,6 @@ static void ets_qdisc_reset(struct Qdisc *sch)
+ }
+ for (band = 0; band < q->nbands; band++)
+ qdisc_reset(q->classes[band].qdisc);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void ets_qdisc_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
+index 839e1235db053..23a042adb74d8 100644
+--- a/net/sched/sch_fq_codel.c
++++ b/net/sched/sch_fq_codel.c
+@@ -347,8 +347,6 @@ static void fq_codel_reset(struct Qdisc *sch)
+ codel_vars_init(&flow->cvars);
+ }
+ memset(q->backlogs, 0, q->flows_cnt * sizeof(u32));
+- sch->q.qlen = 0;
+- sch->qstats.backlog = 0;
+ q->memory_usage = 0;
+ }
+
+diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
+index d6aba6edd16e5..35c35465226bd 100644
+--- a/net/sched/sch_fq_pie.c
++++ b/net/sched/sch_fq_pie.c
+@@ -521,9 +521,6 @@ static void fq_pie_reset(struct Qdisc *sch)
+ INIT_LIST_HEAD(&flow->flowchain);
+ pie_vars_init(&flow->vars);
+ }
+-
+- sch->q.qlen = 0;
+- sch->qstats.backlog = 0;
+ }
+
+ static void fq_pie_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
+index d3979a6000e7d..03efc40e42fc4 100644
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -1484,8 +1484,6 @@ hfsc_reset_qdisc(struct Qdisc *sch)
+ }
+ q->eligible = RB_ROOT;
+ qdisc_watchdog_cancel(&q->watchdog);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index 23a9d6242429f..cb5872d22ecf4 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1008,8 +1008,6 @@ static void htb_reset(struct Qdisc *sch)
+ }
+ qdisc_watchdog_cancel(&q->watchdog);
+ __qdisc_reset_queue(&q->direct_queue);
+- sch->q.qlen = 0;
+- sch->qstats.backlog = 0;
+ memset(q->hlevel, 0, sizeof(q->hlevel));
+ memset(q->row_mask, 0, sizeof(q->row_mask));
+ }
+diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
+index cd8ab90c4765d..f28050c7f12d6 100644
+--- a/net/sched/sch_multiq.c
++++ b/net/sched/sch_multiq.c
+@@ -152,7 +152,6 @@ multiq_reset(struct Qdisc *sch)
+
+ for (band = 0; band < q->bands; band++)
+ qdisc_reset(q->queues[band]);
+- sch->q.qlen = 0;
+ q->curband = 0;
+ }
+
+diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
+index 3b8d7197c06bf..c03a11dd990f4 100644
+--- a/net/sched/sch_prio.c
++++ b/net/sched/sch_prio.c
+@@ -135,8 +135,6 @@ prio_reset(struct Qdisc *sch)
+
+ for (prio = 0; prio < q->bands; prio++)
+ qdisc_reset(q->queues[prio]);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
+diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
+index d4ce58c90f9fb..13246a9dc5c1c 100644
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -1458,8 +1458,6 @@ static void qfq_reset_qdisc(struct Qdisc *sch)
+ qdisc_reset(cl->qdisc);
+ }
+ }
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void qfq_destroy_qdisc(struct Qdisc *sch)
+diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
+index 40adf1f07a82d..f1e013e3f04a9 100644
+--- a/net/sched/sch_red.c
++++ b/net/sched/sch_red.c
+@@ -176,8 +176,6 @@ static void red_reset(struct Qdisc *sch)
+ struct red_sched_data *q = qdisc_priv(sch);
+
+ qdisc_reset(q->qdisc);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ red_restart(&q->vars);
+ }
+
+diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
+index 2829455211f8c..0490eb5b98dee 100644
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -455,9 +455,8 @@ static void sfb_reset(struct Qdisc *sch)
+ {
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+- qdisc_reset(q->qdisc);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
++ if (likely(q->qdisc))
++ qdisc_reset(q->qdisc);
+ q->slot = 0;
+ q->double_buffering = false;
+ sfb_zero_all_buckets(q);
+diff --git a/net/sched/sch_skbprio.c b/net/sched/sch_skbprio.c
+index 7a5e4c4547156..df72fb83d9c7d 100644
+--- a/net/sched/sch_skbprio.c
++++ b/net/sched/sch_skbprio.c
+@@ -213,9 +213,6 @@ static void skbprio_reset(struct Qdisc *sch)
+ struct skbprio_sched_data *q = qdisc_priv(sch);
+ int prio;
+
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+-
+ for (prio = 0; prio < SKBPRIO_MAX_PRIORITY; prio++)
+ __skb_queue_purge(&q->qdiscs[prio]);
+
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 86675a79da1e4..5bffc37022e0b 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1638,8 +1638,6 @@ static void taprio_reset(struct Qdisc *sch)
+ if (q->qdiscs[i])
+ qdisc_reset(q->qdiscs[i]);
+ }
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ }
+
+ static void taprio_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index 36079fdde2cb5..e031c1a41ea6b 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -330,8 +330,6 @@ static void tbf_reset(struct Qdisc *sch)
+ struct tbf_sched_data *q = qdisc_priv(sch);
+
+ qdisc_reset(q->qdisc);
+- sch->qstats.backlog = 0;
+- sch->q.qlen = 0;
+ q->t_c = ktime_get_ns();
+ q->tokens = q->buffer;
+ q->ptokens = q->mtu;
+diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
+index 6af6b95bdb672..79aaab51cbf5c 100644
+--- a/net/sched/sch_teql.c
++++ b/net/sched/sch_teql.c
+@@ -124,7 +124,6 @@ teql_reset(struct Qdisc *sch)
+ struct teql_sched_data *dat = qdisc_priv(sch);
+
+ skb_queue_purge(&dat->q);
+- sch->q.qlen = 0;
+ }
+
+ static void
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
+index df89c2e08cbf4..828dd3a4126ab 100644
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -896,7 +896,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
+ }
+ memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1],
+ SMC_MAX_PNETID_LEN);
+- if (smc_wr_alloc_lgr_mem(lgr))
++ rc = smc_wr_alloc_lgr_mem(lgr);
++ if (rc)
+ goto free_wq;
+ smc_llc_lgr_init(lgr, smc);
+
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index da69e1abf68ff..e8630707901e3 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -148,8 +148,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
+ {
+ struct net *net = d->net;
+ struct tipc_net *tn = tipc_net(net);
+- bool trial = time_before(jiffies, tn->addr_trial_end);
+ u32 self = tipc_own_addr(net);
++ bool trial = time_before(jiffies, tn->addr_trial_end) && !self;
+
+ if (mtyp == DSC_TRIAL_FAIL_MSG) {
+ if (!trial)
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index 5522865deae95..14fd05fd6107d 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -568,7 +568,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+ sub.seq.upper = upper;
+ sub.timeout = TIPC_WAIT_FOREVER;
+ sub.filter = filter;
+- *(u32 *)&sub.usr_handle = port;
++ *(u64 *)&sub.usr_handle = (u64)port;
+
+ con = tipc_conn_alloc(tipc_topsrv(net));
+ if (IS_ERR(con))
+diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
+index 9b79e334dbd9e..955ac3e0bf4d3 100644
+--- a/net/tls/tls_strp.c
++++ b/net/tls/tls_strp.c
+@@ -273,7 +273,7 @@ static int tls_strp_read_copyin(struct tls_strparser *strp)
+ return desc.error;
+ }
+
+-static int tls_strp_read_short(struct tls_strparser *strp)
++static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
+ {
+ struct skb_shared_info *shinfo;
+ struct page *page;
+@@ -283,7 +283,7 @@ static int tls_strp_read_short(struct tls_strparser *strp)
+ * to read the data out. Otherwise the connection will stall.
+ * Without pressure threshold of INT_MAX will never be ready.
+ */
+- if (likely(!tcp_epollin_ready(strp->sk, INT_MAX)))
++ if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX)))
+ return 0;
+
+ shinfo = skb_shinfo(strp->anchor);
+@@ -315,6 +315,27 @@ static int tls_strp_read_short(struct tls_strparser *strp)
+ return 0;
+ }
+
++static bool tls_strp_check_no_dup(struct tls_strparser *strp)
++{
++ unsigned int len = strp->stm.offset + strp->stm.full_len;
++ struct sk_buff *skb;
++ u32 seq;
++
++ skb = skb_shinfo(strp->anchor)->frag_list;
++ seq = TCP_SKB_CB(skb)->seq;
++
++ while (skb->len < len) {
++ seq += skb->len;
++ len -= skb->len;
++ skb = skb->next;
++
++ if (TCP_SKB_CB(skb)->seq != seq)
++ return false;
++ }
++
++ return true;
++}
++
+ static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
+ {
+ struct tcp_sock *tp = tcp_sk(strp->sk);
+@@ -373,7 +394,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ return tls_strp_read_copyin(strp);
+
+ if (inq < strp->stm.full_len)
+- return tls_strp_read_short(strp);
++ return tls_strp_read_copy(strp, true);
+
+ if (!strp->stm.full_len) {
+ tls_strp_load_anchor_with_queue(strp, inq);
+@@ -387,9 +408,12 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ strp->stm.full_len = sz;
+
+ if (!strp->stm.full_len || inq < strp->stm.full_len)
+- return tls_strp_read_short(strp);
++ return tls_strp_read_copy(strp, true);
+ }
+
++ if (!tls_strp_check_no_dup(strp))
++ return tls_strp_read_copy(strp, false);
++
+ strp->msg_ready = 1;
+ tls_rx_msg_ready(strp);
+
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
+index fe5fcf571c564..64a6a37dc36d9 100644
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -2022,7 +2022,8 @@ static inline int convert_context_handle_invalid_context(
+ * in `newc'. Verify that the context is valid
+ * under the new policy.
+ */
+-static int convert_context(struct context *oldc, struct context *newc, void *p)
++static int convert_context(struct context *oldc, struct context *newc, void *p,
++ gfp_t gfp_flags)
+ {
+ struct convert_context_args *args;
+ struct ocontext *oc;
+@@ -2036,7 +2037,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
+ args = p;
+
+ if (oldc->str) {
+- s = kstrdup(oldc->str, GFP_KERNEL);
++ s = kstrdup(oldc->str, gfp_flags);
+ if (!s)
+ return -ENOMEM;
+
+diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
+index a54b8652bfb50..db5cce385bf86 100644
+--- a/security/selinux/ss/sidtab.c
++++ b/security/selinux/ss/sidtab.c
+@@ -325,7 +325,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
+ }
+
+ rc = convert->func(context, &dst_convert->context,
+- convert->args);
++ convert->args, GFP_ATOMIC);
+ if (rc) {
+ context_destroy(&dst->context);
+ goto out_unlock;
+@@ -404,7 +404,7 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst,
+ while (i < SIDTAB_LEAF_ENTRIES && *pos < count) {
+ rc = convert->func(&esrc->ptr_leaf->entries[i].context,
+ &edst->ptr_leaf->entries[i].context,
+- convert->args);
++ convert->args, GFP_KERNEL);
+ if (rc)
+ return rc;
+ (*pos)++;
+diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
+index 4eff0e49dcb22..9fce0d553fe2c 100644
+--- a/security/selinux/ss/sidtab.h
++++ b/security/selinux/ss/sidtab.h
+@@ -65,7 +65,7 @@ struct sidtab_isid_entry {
+ };
+
+ struct sidtab_convert_params {
+- int (*func)(struct context *oldc, struct context *newc, void *args);
++ int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags);
+ void *args;
+ struct sidtab *target;
+ };
+diff --git a/tools/verification/dot2/dot2c.py b/tools/verification/dot2/dot2c.py
+index fa73353f7e560..be8a364a469b9 100644
+--- a/tools/verification/dot2/dot2c.py
++++ b/tools/verification/dot2/dot2c.py
+@@ -111,7 +111,7 @@ class Dot2c(Automata):
+
+ def format_aut_init_header(self):
+ buff = []
+- buff.append("struct %s %s = {" % (self.struct_automaton_def, self.var_automaton_def))
++ buff.append("static struct %s %s = {" % (self.struct_automaton_def, self.var_automaton_def))
+ return buff
+
+ def __get_string_vector_per_line_content(self, buff):
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 584a5bab3af39..4c5259828efdc 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -4834,6 +4834,12 @@ struct compat_kvm_clear_dirty_log {
+ };
+ };
+
++long __weak kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++ unsigned long arg)
++{
++ return -ENOTTY;
++}
++
+ static long kvm_vm_compat_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+ {
+@@ -4842,6 +4848,11 @@ static long kvm_vm_compat_ioctl(struct file *filp,
+
+ if (kvm->mm != current->mm || kvm->vm_dead)
+ return -EIO;
++
++ r = kvm_arch_vm_compat_ioctl(filp, ioctl, arg);
++ if (r != -ENOTTY)
++ return r;
++
+ switch (ioctl) {
+ #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
+ case KVM_CLEAR_DIRTY_LOG: {
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-01 12:46 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-01 12:46 UTC (permalink / raw
To: gentoo-commits
commit: 5ceffccd28e7d4cc987afb63c276189d7d3925e0
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 1 12:45:24 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Nov 1 12:45:24 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5ceffccd
btrfs: don't use btrfs_chunk::sub_stripes from disk
Bug: https://bugs.gentoo.org/878023
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 8 ++-
1900_btrfs-chunk-sub_stripes-fix.patch | 92 ++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/0000_README b/0000_README
index 68ada3e5..a0b5ecc7 100644
--- a/0000_README
+++ b/0000_README
@@ -76,8 +76,12 @@ From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/
Desc: Enable link security restrictions by default.
Patch: 1700_sparc-address-warray-bound-warnings.patch
-From: https://github.com/KSPP/linux/issues/109
-Desc: Address -Warray-bounds warnings
+From: https://github.com/KSPP/linux/issues/109
+Desc: Address -Warray-bounds warnings
+
+Patch: 1900_btrfs-chunk-sub_stripes-fix.patch
+From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+Desc: btrfs: Don't use btrfs_chunk::sub_stripes from disk
Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch
new file mode 100644
index 00000000..2ffe02fe
--- /dev/null
+++ b/1900_btrfs-chunk-sub_stripes-fix.patch
@@ -0,0 +1,92 @@
+From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 21 Oct 2022 08:43:45 +0800
+Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk
+
+[BUG]
+There are two reports (the earliest one from LKP, a more recent one from
+kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
+
+This will cause divide-by-zero errors at btrfs_rmap_block, which is
+introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
+calculations for simple striped profiles in btrfs_rmap_block"):
+
+ if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+ BTRFS_BLOCK_GROUP_RAID10)) {
+ stripe_nr = stripe_nr * map->num_stripes + i;
+ stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
+ }
+
+[CAUSE]
+From the more recent report, it has been proven that we have some chunks
+with 0 as sub_stripes, mostly caused by older mkfs.
+
+It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
+("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
+which is included in v5.4 btrfs-progs release.
+
+So there would be quite some old filesystems with such 0 sub_stripes.
+
+[FIX]
+Just don't trust the sub_stripes values from disk.
+
+We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
+numbers for each profile and that are fixed.
+
+By this, we can keep the compatibility with older filesystems while
+still avoid divide-by-zero bugs.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Reported-by: Viktor Kuzmin <kvaster@gmail.com>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559
+Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
+CC: stable@vger.kernel.org # 6.0
+Reviewed-by: Su Yue <glass@fydeos.io>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/volumes.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+(limited to 'fs/btrfs/volumes.c')
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 94ba46d579205..a8d4bc6a19379 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ u64 devid;
+ u64 type;
+ u8 uuid[BTRFS_UUID_SIZE];
++ int index;
+ int num_stripes;
+ int ret;
+ int i;
+@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ logical = key->offset;
+ length = btrfs_chunk_length(leaf, chunk);
+ type = btrfs_chunk_type(leaf, chunk);
++ index = btrfs_bg_flags_to_raid_index(type);
+ num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+
+ #if BITS_PER_LONG == 32
+@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ map->io_align = btrfs_chunk_io_align(leaf, chunk);
+ map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+ map->type = type;
+- map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
++ /*
++ * We can't use the sub_stripes value, as for profiles other than
++ * RAID10, they may have 0 as sub_stripes for filesystems created by
++ * older mkfs (<v5.4).
++ * In that case, it can cause divide-by-zero errors later.
++ * Since currently sub_stripes is fixed for each profile, let's
++ * use the trusted value instead.
++ */
++ map->sub_stripes = btrfs_raid_array[index].sub_stripes;
+ map->verified_stripes = 0;
+ em->orig_block_len = btrfs_calc_stripe_length(em);
+ for (i = 0; i < num_stripes; i++) {
+--
+cgit
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-03 15:27 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-03 15:27 UTC (permalink / raw
To: gentoo-commits
commit: 7902df925836e53559cdf8bbc48da70d486faaf7
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 3 15:27:02 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 3 15:27:02 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=7902df92
Linux patch 6.0.7
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1006_linux-6.0.7.patch | 10948 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 10952 insertions(+)
diff --git a/0000_README b/0000_README
index a0b5ecc7..9f94b8ae 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,10 @@ Patch: 1005_linux-6.0.6.patch
From: http://www.kernel.org
Desc: Linux 6.0.6
+Patch: 1006_linux-6.0.7.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.7
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1006_linux-6.0.7.patch b/1006_linux-6.0.7.patch
new file mode 100644
index 00000000..d7ae366a
--- /dev/null
+++ b/1006_linux-6.0.7.patch
@@ -0,0 +1,10948 @@
+diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
+index 1e2b9b627b126..2722dc7bb03da 100644
+--- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
+@@ -274,10 +274,6 @@ patternProperties:
+ slew-rate:
+ enum: [0, 1]
+
+- output-enable:
+- description:
+- This will internally disable the tri-state for MIO pins.
+-
+ drive-strength:
+ description:
+ Selects the drive strength for MIO pins, in mA.
+diff --git a/Makefile b/Makefile
+index e6c10009d413a..c2144a4bb2efe 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
+index 8f777d6441a5d..80347382a3800 100644
+--- a/arch/arc/include/asm/io.h
++++ b/arch/arc/include/asm/io.h
+@@ -32,7 +32,7 @@ static inline void ioport_unmap(void __iomem *addr)
+ {
+ }
+
+-extern void iounmap(const void __iomem *addr);
++extern void iounmap(const volatile void __iomem *addr);
+
+ /*
+ * io{read,write}{16,32}be() macros
+diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
+index 64ca25d199bea..ef68758b69f7e 100644
+--- a/arch/arc/include/asm/pgtable-levels.h
++++ b/arch/arc/include/asm/pgtable-levels.h
+@@ -161,7 +161,7 @@
+ #define pmd_pfn(pmd) ((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT)
+ #define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
+ #define set_pmd(pmdp, pmd) (*(pmdp) = pmd)
+-#define pmd_pgtable(pmd) ((pgtable_t) pmd_page_vaddr(pmd))
++#define pmd_pgtable(pmd) ((pgtable_t) pmd_page(pmd))
+
+ /*
+ * 4th level paging: pte
+diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
+index 0ee75aca6e109..712c2311daefb 100644
+--- a/arch/arc/mm/ioremap.c
++++ b/arch/arc/mm/ioremap.c
+@@ -94,7 +94,7 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size,
+ EXPORT_SYMBOL(ioremap_prot);
+
+
+-void iounmap(const void __iomem *addr)
++void iounmap(const volatile void __iomem *addr)
+ {
+ /* weird double cast to handle phys_addr_t > 32 bits */
+ if (arc_uncached_addr_space((phys_addr_t)(u32)addr))
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index 8aa0d276a6362..abc418650fec0 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -60,6 +60,7 @@
+ #define ARM_CPU_IMP_FUJITSU 0x46
+ #define ARM_CPU_IMP_HISI 0x48
+ #define ARM_CPU_IMP_APPLE 0x61
++#define ARM_CPU_IMP_AMPERE 0xC0
+
+ #define ARM_CPU_PART_AEM_V8 0xD0F
+ #define ARM_CPU_PART_FOUNDATION 0xD00
+@@ -123,6 +124,8 @@
+ #define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028
+ #define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029
+
++#define AMPERE_CPU_PART_AMPERE1 0xAC3
++
+ #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+ #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+ #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
+@@ -172,6 +175,7 @@
+ #define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
+ #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
+ #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
++#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+
+ /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
+ #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX
+diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
+index 40be3a7c2c531..428cfabd11c49 100644
+--- a/arch/arm64/kernel/proton-pack.c
++++ b/arch/arm64/kernel/proton-pack.c
+@@ -868,6 +868,10 @@ u8 spectre_bhb_loop_affected(int scope)
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ {},
+ };
++ static const struct midr_range spectre_bhb_k11_list[] = {
++ MIDR_ALL_VERSIONS(MIDR_AMPERE1),
++ {},
++ };
+ static const struct midr_range spectre_bhb_k8_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+@@ -878,6 +882,8 @@ u8 spectre_bhb_loop_affected(int scope)
+ k = 32;
+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+ k = 24;
++ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
++ k = 11;
+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+ k = 8;
+
+diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
+index 2ca1c037ea258..4d54b90f46274 100644
+--- a/arch/powerpc/kernel/interrupt_64.S
++++ b/arch/powerpc/kernel/interrupt_64.S
+@@ -565,15 +565,24 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
+ * Returning to soft-disabled context.
+ * Check if a MUST_HARD_MASK interrupt has become pending, in which
+ * case we need to disable MSR[EE] in the return context.
++ *
++ * The MSR[EE] check catches among other things the short incoherency
++ * in hard_irq_disable() between clearing MSR[EE] and setting
++ * PACA_IRQ_HARD_DIS.
+ */
+ ld r12,_MSR(r1)
+ andi. r10,r12,MSR_EE
+ beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled
+ lbz r11,PACAIRQHAPPENED(r13)
+ andi. r10,r11,PACA_IRQ_MUST_HARD_MASK
+- beq .Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending
++ bne 1f // HARD_MASK is pending
++ // No HARD_MASK pending, clear possible HARD_DIS set by interrupt
++ andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
++ stb r11,PACAIRQHAPPENED(r13)
++ b .Lfast_kernel_interrupt_return_\srr\()
++
+
+- /* Must clear MSR_EE from _MSR */
++1: /* Must clear MSR_EE from _MSR */
+ #ifdef CONFIG_PPC_BOOK3S
+ li r10,0
+ /* Clear valid before changing _MSR */
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index cea22ccb57cb9..9d5b7fa1b6225 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -402,14 +402,16 @@ config RISCV_ISA_SVPBMT
+
+ If you don't know what to do here, say Y.
+
+-config CC_HAS_ZICBOM
++config TOOLCHAIN_HAS_ZICBOM
+ bool
+- default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
+- default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
++ default y
++ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
++ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
++ depends on LLD_VERSION >= 150000 || LD_VERSION >= 23800
+
+ config RISCV_ISA_ZICBOM
+ bool "Zicbom extension support for non-coherent DMA operation"
+- depends on CC_HAS_ZICBOM
++ depends on TOOLCHAIN_HAS_ZICBOM
+ depends on !XIP_KERNEL && MMU
+ select RISCV_DMA_NONCOHERENT
+ select RISCV_ALTERNATIVE
+@@ -424,6 +426,13 @@ config RISCV_ISA_ZICBOM
+
+ If you don't know what to do here, say Y.
+
++config TOOLCHAIN_HAS_ZIHINTPAUSE
++ bool
++ default y
++ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause)
++ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
++ depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
++
+ config FPU
+ bool "FPU support"
+ default y
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index e7d52a2301e26..e5a608e37f456 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -59,12 +59,10 @@ toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zi
+ riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
+
+ # Check if the toolchain supports Zicbom extension
+-toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom)
+-riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom
++riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZICBOM) := $(riscv-march-y)_zicbom
+
+ # Check if the toolchain supports Zihintpause extension
+-toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause)
+-riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause
++riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
+
+ KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
+ KBUILD_AFLAGS += -march=$(riscv-march-y)
+diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
+index 273ece6b622f6..1470e556cdb17 100644
+--- a/arch/riscv/include/asm/cacheflush.h
++++ b/arch/riscv/include/asm/cacheflush.h
+@@ -42,16 +42,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
+
+ #endif /* CONFIG_SMP */
+
+-/*
+- * The T-Head CMO errata internally probe the CBOM block size, but otherwise
+- * don't depend on Zicbom.
+- */
+ extern unsigned int riscv_cbom_block_size;
+-#ifdef CONFIG_RISCV_ISA_ZICBOM
+ void riscv_init_cbom_blocksize(void);
+-#else
+-static inline void riscv_init_cbom_blocksize(void) { }
+-#endif
+
+ #ifdef CONFIG_RISCV_DMA_NONCOHERENT
+ void riscv_noncoherent_supported(void);
+diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/jump_label.h
+index 38af2ec7b9bf9..6d58bbb5da467 100644
+--- a/arch/riscv/include/asm/jump_label.h
++++ b/arch/riscv/include/asm/jump_label.h
+@@ -14,8 +14,8 @@
+
+ #define JUMP_LABEL_NOP_SIZE 4
+
+-static __always_inline bool arch_static_branch(struct static_key *key,
+- bool branch)
++static __always_inline bool arch_static_branch(struct static_key * const key,
++ const bool branch)
+ {
+ asm_volatile_goto(
+ " .option push \n\t"
+@@ -35,8 +35,8 @@ label:
+ return true;
+ }
+
+-static __always_inline bool arch_static_branch_jump(struct static_key *key,
+- bool branch)
++static __always_inline bool arch_static_branch_jump(struct static_key * const key,
++ const bool branch)
+ {
+ asm_volatile_goto(
+ " .option push \n\t"
+diff --git a/arch/riscv/include/asm/kvm_vcpu_timer.h b/arch/riscv/include/asm/kvm_vcpu_timer.h
+index 0d8fdb8ec63aa..82f7260301da2 100644
+--- a/arch/riscv/include/asm/kvm_vcpu_timer.h
++++ b/arch/riscv/include/asm/kvm_vcpu_timer.h
+@@ -45,6 +45,7 @@ int kvm_riscv_vcpu_timer_deinit(struct kvm_vcpu *vcpu);
+ int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu);
+ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu);
+ void kvm_riscv_guest_timer_init(struct kvm *kvm);
++void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu);
+ void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu);
+ bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu);
+
+diff --git a/arch/riscv/include/asm/vdso/processor.h b/arch/riscv/include/asm/vdso/processor.h
+index 1e4f8b4aef79d..fa70cfe507aa1 100644
+--- a/arch/riscv/include/asm/vdso/processor.h
++++ b/arch/riscv/include/asm/vdso/processor.h
+@@ -21,7 +21,7 @@ static inline void cpu_relax(void)
+ * Reduce instruction retirement.
+ * This assumes the PC changes.
+ */
+-#ifdef __riscv_zihintpause
++#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE
+ __asm__ __volatile__ ("pause");
+ #else
+ /* Encoding of the pause instruction */
+diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
+index 7351417afd62e..b9a4cf36be4bf 100644
+--- a/arch/riscv/include/uapi/asm/kvm.h
++++ b/arch/riscv/include/uapi/asm/kvm.h
+@@ -48,6 +48,7 @@ struct kvm_sregs {
+ /* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+ struct kvm_riscv_config {
+ unsigned long isa;
++ unsigned long zicbom_block_size;
+ };
+
+ /* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
+index d0f08d5b42829..f692c0716aa7a 100644
+--- a/arch/riscv/kvm/vcpu.c
++++ b/arch/riscv/kvm/vcpu.c
+@@ -18,6 +18,7 @@
+ #include <linux/fs.h>
+ #include <linux/kvm_host.h>
+ #include <asm/csr.h>
++#include <asm/cacheflush.h>
+ #include <asm/hwcap.h>
+
+ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
+@@ -254,6 +255,11 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
+ case KVM_REG_RISCV_CONFIG_REG(isa):
+ reg_val = vcpu->arch.isa[0] & KVM_RISCV_BASE_ISA_MASK;
+ break;
++ case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
++ if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOM))
++ return -EINVAL;
++ reg_val = riscv_cbom_block_size;
++ break;
+ default:
+ return -EINVAL;
+ }
+@@ -311,6 +317,8 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
+ return -EOPNOTSUPP;
+ }
+ break;
++ case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
++ return -EOPNOTSUPP;
+ default:
+ return -EINVAL;
+ }
+@@ -690,6 +698,9 @@ void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu)
+ clear_bit(IRQ_VS_SOFT, &v->irqs_pending);
+ }
+ }
++
++ /* Sync-up timer CSRs */
++ kvm_riscv_vcpu_timer_sync(vcpu);
+ }
+
+ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
+diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
+index 185f2386a747e..ad34519c8a13d 100644
+--- a/arch/riscv/kvm/vcpu_timer.c
++++ b/arch/riscv/kvm/vcpu_timer.c
+@@ -320,20 +320,33 @@ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu)
+ kvm_riscv_vcpu_timer_unblocking(vcpu);
+ }
+
+-void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
++void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_vcpu_timer *t = &vcpu->arch.timer;
+
+ if (!t->sstc_enabled)
+ return;
+
+- t = &vcpu->arch.timer;
+ #if defined(CONFIG_32BIT)
+ t->next_cycles = csr_read(CSR_VSTIMECMP);
+ t->next_cycles |= (u64)csr_read(CSR_VSTIMECMPH) << 32;
+ #else
+ t->next_cycles = csr_read(CSR_VSTIMECMP);
+ #endif
++}
++
++void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
++{
++ struct kvm_vcpu_timer *t = &vcpu->arch.timer;
++
++ if (!t->sstc_enabled)
++ return;
++
++ /*
++ * The vstimecmp CSRs are saved by kvm_riscv_vcpu_timer_sync()
++ * upon every VM exit so no need to save here.
++ */
++
+ /* timer should be enabled for the remaining operations */
+ if (unlikely(!t->init_done))
+ return;
+diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
+index 6cb7d96ad9c7b..57b40a3504206 100644
+--- a/arch/riscv/mm/cacheflush.c
++++ b/arch/riscv/mm/cacheflush.c
+@@ -3,6 +3,7 @@
+ * Copyright (C) 2017 SiFive
+ */
+
++#include <linux/of.h>
+ #include <asm/cacheflush.h>
+
+ #ifdef CONFIG_SMP
+@@ -86,3 +87,40 @@ void flush_icache_pte(pte_t pte)
+ flush_icache_all();
+ }
+ #endif /* CONFIG_MMU */
++
++unsigned int riscv_cbom_block_size;
++EXPORT_SYMBOL_GPL(riscv_cbom_block_size);
++
++void riscv_init_cbom_blocksize(void)
++{
++ struct device_node *node;
++ unsigned long cbom_hartid;
++ u32 val, probed_block_size;
++ int ret;
++
++ probed_block_size = 0;
++ for_each_of_cpu_node(node) {
++ unsigned long hartid;
++
++ ret = riscv_of_processor_hartid(node, &hartid);
++ if (ret)
++ continue;
++
++ /* set block-size for cbom extension if available */
++ ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
++ if (ret)
++ continue;
++
++ if (!probed_block_size) {
++ probed_block_size = val;
++ cbom_hartid = hartid;
++ } else {
++ if (probed_block_size != val)
++ pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
++ cbom_hartid, hartid);
++ }
++ }
++
++ if (probed_block_size)
++ riscv_cbom_block_size = probed_block_size;
++}
+diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
+index e3f9bdf47c5ff..d919efab6ebad 100644
+--- a/arch/riscv/mm/dma-noncoherent.c
++++ b/arch/riscv/mm/dma-noncoherent.c
+@@ -8,11 +8,8 @@
+ #include <linux/dma-direct.h>
+ #include <linux/dma-map-ops.h>
+ #include <linux/mm.h>
+-#include <linux/of.h>
+-#include <linux/of_device.h>
+ #include <asm/cacheflush.h>
+
+-unsigned int riscv_cbom_block_size;
+ static bool noncoherent_supported;
+
+ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
+@@ -75,42 +72,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ dev->dma_coherent = coherent;
+ }
+
+-#ifdef CONFIG_RISCV_ISA_ZICBOM
+-void riscv_init_cbom_blocksize(void)
+-{
+- struct device_node *node;
+- unsigned long cbom_hartid;
+- u32 val, probed_block_size;
+- int ret;
+-
+- probed_block_size = 0;
+- for_each_of_cpu_node(node) {
+- unsigned long hartid;
+-
+- ret = riscv_of_processor_hartid(node, &hartid);
+- if (ret)
+- continue;
+-
+- /* set block-size for cbom extension if available */
+- ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
+- if (ret)
+- continue;
+-
+- if (!probed_block_size) {
+- probed_block_size = val;
+- cbom_hartid = hartid;
+- } else {
+- if (probed_block_size != val)
+- pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
+- cbom_hartid, hartid);
+- }
+- }
+-
+- if (probed_block_size)
+- riscv_cbom_block_size = probed_block_size;
+-}
+-#endif
+-
+ void riscv_noncoherent_supported(void)
+ {
+ WARN(!riscv_cbom_block_size,
+diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
+index a22e418dbd82c..e1226709490fa 100644
+--- a/arch/riscv/mm/kasan_init.c
++++ b/arch/riscv/mm/kasan_init.c
+@@ -113,6 +113,8 @@ static void __init kasan_populate_pud(pgd_t *pgd,
+ base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
+ } else if (pgd_none(*pgd)) {
+ base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
++ memcpy(base_pud, (void *)kasan_early_shadow_pud,
++ sizeof(pud_t) * PTRS_PER_PUD);
+ } else {
+ base_pud = (pud_t *)pgd_page_vaddr(*pgd);
+ if (base_pud == lm_alias(kasan_early_shadow_pud)) {
+@@ -173,8 +175,11 @@ static void __init kasan_populate_p4d(pgd_t *pgd,
+ base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgd)));
+ } else {
+ base_p4d = (p4d_t *)pgd_page_vaddr(*pgd);
+- if (base_p4d == lm_alias(kasan_early_shadow_p4d))
++ if (base_p4d == lm_alias(kasan_early_shadow_p4d)) {
+ base_p4d = memblock_alloc(PTRS_PER_PUD * sizeof(p4d_t), PAGE_SIZE);
++ memcpy(base_p4d, (void *)kasan_early_shadow_p4d,
++ sizeof(p4d_t) * PTRS_PER_P4D);
++ }
+ }
+
+ p4dp = base_p4d + p4d_index(vaddr);
+diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S
+index af5c6860e0a11..fa9d33b01b858 100644
+--- a/arch/s390/boot/vmlinux.lds.S
++++ b/arch/s390/boot/vmlinux.lds.S
+@@ -102,8 +102,17 @@ SECTIONS
+ _compressed_start = .;
+ *(.vmlinux.bin.compressed)
+ _compressed_end = .;
+- FILL(0xff);
+- . = ALIGN(4096);
++ }
++
++#define SB_TRAILER_SIZE 32
++ /* Trailer needed for Secure Boot */
++ . += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
++ . = ALIGN(4096) - SB_TRAILER_SIZE;
++ .sb.trailer : {
++ QUAD(0)
++ QUAD(0)
++ QUAD(0)
++ QUAD(0x000000207a49504c)
+ }
+ _end = .;
+
+diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h
+index e08c882dccaae..eaeaeb3ff0be3 100644
+--- a/arch/s390/include/asm/futex.h
++++ b/arch/s390/include/asm/futex.h
+@@ -17,7 +17,8 @@
+ "3: jl 1b\n" \
+ " lhi %0,0\n" \
+ "4: sacf 768\n" \
+- EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
++ EX_TABLE(0b,4b) EX_TABLE(1b,4b) \
++ EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
+ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
+ "=m" (*uaddr) \
+ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
+diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
+index d7b3b193d1088..be0f1b62c33b3 100644
+--- a/arch/s390/lib/uaccess.c
++++ b/arch/s390/lib/uaccess.c
+@@ -156,7 +156,7 @@ unsigned long __clear_user(void __user *to, unsigned long size)
+ asm volatile(
+ " lr 0,%[spec]\n"
+ "0: mvcos 0(%1),0(%4),%0\n"
+- " jz 4f\n"
++ "6: jz 4f\n"
+ "1: algr %0,%2\n"
+ " slgr %1,%2\n"
+ " j 0b\n"
+@@ -166,11 +166,11 @@ unsigned long __clear_user(void __user *to, unsigned long size)
+ " clgr %0,%3\n" /* copy crosses next page boundary? */
+ " jnh 5f\n"
+ "3: mvcos 0(%1),0(%4),%3\n"
+- " slgr %0,%3\n"
++ "7: slgr %0,%3\n"
+ " j 5f\n"
+ "4: slgr %0,%0\n"
+ "5:\n"
+- EX_TABLE(0b,2b) EX_TABLE(3b,5b)
++ EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b)
+ : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
+ : "a" (empty_zero_page), [spec] "d" (spec.val)
+ : "cc", "memory", "0");
+diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
+index 080c88620723a..5880893329310 100644
+--- a/arch/s390/pci/pci_mmio.c
++++ b/arch/s390/pci/pci_mmio.c
+@@ -64,7 +64,7 @@ static inline int __pcistg_mio_inuser(
+ asm volatile (
+ " sacf 256\n"
+ "0: llgc %[tmp],0(%[src])\n"
+- " sllg %[val],%[val],8\n"
++ "4: sllg %[val],%[val],8\n"
+ " aghi %[src],1\n"
+ " ogr %[val],%[tmp]\n"
+ " brctg %[cnt],0b\n"
+@@ -72,7 +72,7 @@ static inline int __pcistg_mio_inuser(
+ "2: ipm %[cc]\n"
+ " srl %[cc],28\n"
+ "3: sacf 768\n"
+- EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
++ EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
+ :
+ [src] "+a" (src), [cnt] "+d" (cnt),
+ [val] "+d" (val), [tmp] "=d" (tmp),
+@@ -215,10 +215,10 @@ static inline int __pcilg_mio_inuser(
+ "2: ahi %[shift],-8\n"
+ " srlg %[tmp],%[val],0(%[shift])\n"
+ "3: stc %[tmp],0(%[dst])\n"
+- " aghi %[dst],1\n"
++ "5: aghi %[dst],1\n"
+ " brctg %[cnt],2b\n"
+ "4: sacf 768\n"
+- EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b)
++ EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b)
+ :
+ [ioaddr_len] "+&d" (ioaddr_len.pair),
+ [cc] "+d" (cc), [val] "=d" (val),
+diff --git a/arch/x86/crypto/polyval-clmulni_glue.c b/arch/x86/crypto/polyval-clmulni_glue.c
+index b7664d0188510..8fa58b0f3cb3d 100644
+--- a/arch/x86/crypto/polyval-clmulni_glue.c
++++ b/arch/x86/crypto/polyval-clmulni_glue.c
+@@ -27,13 +27,17 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/simd.h>
+
++#define POLYVAL_ALIGN 16
++#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN)
++#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
++#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA)
+ #define NUM_KEY_POWERS 8
+
+ struct polyval_tfm_ctx {
+ /*
+ * These powers must be in the order h^8, ..., h^1.
+ */
+- u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE];
++ u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR;
+ };
+
+ struct polyval_desc_ctx {
+@@ -45,6 +49,11 @@ asmlinkage void clmul_polyval_update(const struct polyval_tfm_ctx *keys,
+ const u8 *in, size_t nblocks, u8 *accumulator);
+ asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2);
+
++static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm)
++{
++ return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN);
++}
++
+ static void internal_polyval_update(const struct polyval_tfm_ctx *keys,
+ const u8 *in, size_t nblocks, u8 *accumulator)
+ {
+@@ -72,7 +81,7 @@ static void internal_polyval_mul(u8 *op1, const u8 *op2)
+ static int polyval_x86_setkey(struct crypto_shash *tfm,
+ const u8 *key, unsigned int keylen)
+ {
+- struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm);
++ struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm);
+ int i;
+
+ if (keylen != POLYVAL_BLOCK_SIZE)
+@@ -102,7 +111,7 @@ static int polyval_x86_update(struct shash_desc *desc,
+ const u8 *src, unsigned int srclen)
+ {
+ struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+- const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
++ const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
+ u8 *pos;
+ unsigned int nblocks;
+ unsigned int n;
+@@ -143,7 +152,7 @@ static int polyval_x86_update(struct shash_desc *desc,
+ static int polyval_x86_final(struct shash_desc *desc, u8 *dst)
+ {
+ struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+- const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
++ const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
+
+ if (dctx->bytes) {
+ internal_polyval_mul(dctx->buffer,
+@@ -167,7 +176,7 @@ static struct shash_alg polyval_alg = {
+ .cra_driver_name = "polyval-clmulni",
+ .cra_priority = 200,
+ .cra_blocksize = POLYVAL_BLOCK_SIZE,
+- .cra_ctxsize = sizeof(struct polyval_tfm_ctx),
++ .cra_ctxsize = POLYVAL_CTX_SIZE,
+ .cra_module = THIS_MODULE,
+ },
+ };
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index 47fca6a7a8bcd..c811cb7d632f1 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -1869,7 +1869,7 @@ void __init intel_pmu_arch_lbr_init(void)
+ return;
+
+ clear_arch_lbr:
+- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_ARCH_LBR);
++ setup_clear_cpu_cap(X86_FEATURE_ARCH_LBR);
+ }
+
+ /**
+diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
+index 621f4b6cac4a3..8946f89761cc3 100644
+--- a/arch/x86/kernel/fpu/init.c
++++ b/arch/x86/kernel/fpu/init.c
+@@ -210,13 +210,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
+ fpstate_reset(¤t->thread.fpu);
+ }
+
+-static void __init fpu__init_init_fpstate(void)
+-{
+- /* Bring init_fpstate size and features up to date */
+- init_fpstate.size = fpu_kernel_cfg.max_size;
+- init_fpstate.xfeatures = fpu_kernel_cfg.max_features;
+-}
+-
+ /*
+ * Called on the boot CPU once per system bootup, to set up the initial
+ * FPU state that is later cloned into all processes:
+@@ -236,5 +229,4 @@ void __init fpu__init_system(struct cpuinfo_x86 *c)
+ fpu__init_system_xstate_size_legacy();
+ fpu__init_system_xstate(fpu_kernel_cfg.max_size);
+ fpu__init_task_struct_size();
+- fpu__init_init_fpstate();
+ }
+diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
+index c8340156bfd2a..59e543b95a3c6 100644
+--- a/arch/x86/kernel/fpu/xstate.c
++++ b/arch/x86/kernel/fpu/xstate.c
+@@ -360,7 +360,7 @@ static void __init setup_init_fpu_buf(void)
+
+ print_xstate_features();
+
+- xstate_init_xcomp_bv(&init_fpstate.regs.xsave, fpu_kernel_cfg.max_features);
++ xstate_init_xcomp_bv(&init_fpstate.regs.xsave, init_fpstate.xfeatures);
+
+ /*
+ * Init all the features state with header.xfeatures being 0x0
+@@ -678,20 +678,6 @@ static unsigned int __init get_xsave_size_user(void)
+ return ebx;
+ }
+
+-/*
+- * Will the runtime-enumerated 'xstate_size' fit in the init
+- * task's statically-allocated buffer?
+- */
+-static bool __init is_supported_xstate_size(unsigned int test_xstate_size)
+-{
+- if (test_xstate_size <= sizeof(init_fpstate.regs))
+- return true;
+-
+- pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
+- sizeof(init_fpstate.regs), test_xstate_size);
+- return false;
+-}
+-
+ static int __init init_xstate_size(void)
+ {
+ /* Recompute the context size for enabled features: */
+@@ -717,10 +703,6 @@ static int __init init_xstate_size(void)
+ kernel_default_size =
+ xstate_calculate_size(fpu_kernel_cfg.default_features, compacted);
+
+- /* Ensure we have the space to store all default enabled features. */
+- if (!is_supported_xstate_size(kernel_default_size))
+- return -EINVAL;
+-
+ if (!paranoid_xstate_size_valid(kernel_size))
+ return -EINVAL;
+
+@@ -875,6 +857,19 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
+ update_regset_xstate_info(fpu_user_cfg.max_size,
+ fpu_user_cfg.max_features);
+
++ /*
++ * init_fpstate excludes dynamic states as they are large but init
++ * state is zero.
++ */
++ init_fpstate.size = fpu_kernel_cfg.default_size;
++ init_fpstate.xfeatures = fpu_kernel_cfg.default_features;
++
++ if (init_fpstate.size > sizeof(init_fpstate.regs)) {
++ pr_warn("x86/fpu: init_fpstate buffer too small (%zu < %d), disabling XSAVE\n",
++ sizeof(init_fpstate.regs), init_fpstate.size);
++ goto out_disable;
++ }
++
+ setup_init_fpu_buf();
+
+ /*
+@@ -1130,6 +1125,15 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
+ */
+ mask = fpstate->user_xfeatures;
+
++ /*
++ * Dynamic features are not present in init_fpstate. When they are
++ * in an all zeros init state, remove those from 'mask' to zero
++ * those features in the user buffer instead of retrieving them
++ * from init_fpstate.
++ */
++ if (fpu_state_size_dynamic())
++ mask &= (header.xfeatures | xinit->header.xcomp_bv);
++
+ for_each_extended_xfeature(i, mask) {
+ /*
+ * If there was a feature or alignment gap, zero the space
+diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
+index 0ea57da929407..c059820dfaeaf 100644
+--- a/arch/x86/kernel/unwind_orc.c
++++ b/arch/x86/kernel/unwind_orc.c
+@@ -713,7 +713,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
+ /* Otherwise, skip ahead to the user-specified starting frame: */
+ while (!unwind_done(state) &&
+ (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
+- state->sp < (unsigned long)first_frame))
++ state->sp <= (unsigned long)first_frame))
+ unwind_next_frame(state);
+
+ return;
+diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c
+index ee4ce5ba1fb24..3e252be047b85 100644
+--- a/drivers/acpi/acpi_pcc.c
++++ b/drivers/acpi/acpi_pcc.c
+@@ -27,7 +27,7 @@
+ * Arbitrary retries in case the remote processor is slow to respond
+ * to PCC commands
+ */
+-#define PCC_CMD_WAIT_RETRIES_NUM 500
++#define PCC_CMD_WAIT_RETRIES_NUM 500ULL
+
+ struct pcc_data {
+ struct pcc_mbox_chan *pcc_chan;
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 55a10e6d4e2a7..b7bb9df386de9 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2950,6 +2950,10 @@ static int genpd_iterate_idle_states(struct device_node *dn,
+ np = it.node;
+ if (!of_match_node(idle_state_match, np))
+ continue;
++
++ if (!of_device_is_available(np))
++ continue;
++
+ if (states) {
+ ret = genpd_parse_state(&states[i], np);
+ if (ret) {
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 46d6100fa3a7f..a04098bc28c15 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -793,13 +793,13 @@ int __init random_init(const char *command_line)
+ #endif
+
+ for (i = 0, arch_bits = sizeof(entropy) * 8; i < ARRAY_SIZE(entropy);) {
+- longs = arch_get_random_seed_longs(entropy, ARRAY_SIZE(entropy) - i);
++ longs = arch_get_random_seed_longs_early(entropy, ARRAY_SIZE(entropy) - i);
+ if (longs) {
+ _mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ i += longs;
+ continue;
+ }
+- longs = arch_get_random_longs(entropy, ARRAY_SIZE(entropy) - i);
++ longs = arch_get_random_longs_early(entropy, ARRAY_SIZE(entropy) - i);
+ if (longs) {
+ _mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ i += longs;
+diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
+index 4407203e0c9b3..239f9a7dc5e76 100644
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -231,34 +231,45 @@ static const enum counter_function quad8_count_functions_list[] = {
+ COUNTER_FUNCTION_QUADRATURE_X4,
+ };
+
++static int quad8_function_get(const struct quad8 *const priv, const size_t id,
++ enum counter_function *const function)
++{
++ if (!priv->quadrature_mode[id]) {
++ *function = COUNTER_FUNCTION_PULSE_DIRECTION;
++ return 0;
++ }
++
++ switch (priv->quadrature_scale[id]) {
++ case 0:
++ *function = COUNTER_FUNCTION_QUADRATURE_X1_A;
++ return 0;
++ case 1:
++ *function = COUNTER_FUNCTION_QUADRATURE_X2_A;
++ return 0;
++ case 2:
++ *function = COUNTER_FUNCTION_QUADRATURE_X4;
++ return 0;
++ default:
++ /* should never reach this path */
++ return -EINVAL;
++ }
++}
++
+ static int quad8_function_read(struct counter_device *counter,
+ struct counter_count *count,
+ enum counter_function *function)
+ {
+ struct quad8 *const priv = counter_priv(counter);
+- const int id = count->id;
+ unsigned long irqflags;
++ int retval;
+
+ spin_lock_irqsave(&priv->lock, irqflags);
+
+- if (priv->quadrature_mode[id])
+- switch (priv->quadrature_scale[id]) {
+- case 0:
+- *function = COUNTER_FUNCTION_QUADRATURE_X1_A;
+- break;
+- case 1:
+- *function = COUNTER_FUNCTION_QUADRATURE_X2_A;
+- break;
+- case 2:
+- *function = COUNTER_FUNCTION_QUADRATURE_X4;
+- break;
+- }
+- else
+- *function = COUNTER_FUNCTION_PULSE_DIRECTION;
++ retval = quad8_function_get(priv, count->id, function);
+
+ spin_unlock_irqrestore(&priv->lock, irqflags);
+
+- return 0;
++ return retval;
+ }
+
+ static int quad8_function_write(struct counter_device *counter,
+@@ -358,6 +369,7 @@ static int quad8_action_read(struct counter_device *counter,
+ enum counter_synapse_action *action)
+ {
+ struct quad8 *const priv = counter_priv(counter);
++ unsigned long irqflags;
+ int err;
+ enum counter_function function;
+ const size_t signal_a_id = count->synapses[0].signal->id;
+@@ -373,9 +385,21 @@ static int quad8_action_read(struct counter_device *counter,
+ return 0;
+ }
+
+- err = quad8_function_read(counter, count, &function);
+- if (err)
++ spin_lock_irqsave(&priv->lock, irqflags);
++
++ /* Get Count function and direction atomically */
++ err = quad8_function_get(priv, count->id, &function);
++ if (err) {
++ spin_unlock_irqrestore(&priv->lock, irqflags);
++ return err;
++ }
++ err = quad8_direction_read(counter, count, &direction);
++ if (err) {
++ spin_unlock_irqrestore(&priv->lock, irqflags);
+ return err;
++ }
++
++ spin_unlock_irqrestore(&priv->lock, irqflags);
+
+ /* Default action mode */
+ *action = COUNTER_SYNAPSE_ACTION_NONE;
+@@ -388,10 +412,6 @@ static int quad8_action_read(struct counter_device *counter,
+ return 0;
+ case COUNTER_FUNCTION_QUADRATURE_X1_A:
+ if (synapse->signal->id == signal_a_id) {
+- err = quad8_direction_read(counter, count, &direction);
+- if (err)
+- return err;
+-
+ if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
+ *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
+ else
+diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
+index 00844445143b6..30c7813c8f438 100644
+--- a/drivers/counter/microchip-tcb-capture.c
++++ b/drivers/counter/microchip-tcb-capture.c
+@@ -28,7 +28,6 @@ struct mchp_tc_data {
+ int qdec_mode;
+ int num_channels;
+ int channel[2];
+- bool trig_inverted;
+ };
+
+ static const enum counter_function mchp_tc_count_functions[] = {
+@@ -153,7 +152,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
+
+ regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr);
+
+- if (priv->trig_inverted)
++ if (signal->id == 1)
+ sigstatus = (sr & ATMEL_TC_MTIOB);
+ else
+ sigstatus = (sr & ATMEL_TC_MTIOA);
+@@ -171,6 +170,17 @@ static int mchp_tc_count_action_read(struct counter_device *counter,
+ struct mchp_tc_data *const priv = counter_priv(counter);
+ u32 cmr;
+
++ if (priv->qdec_mode) {
++ *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
++ return 0;
++ }
++
++ /* Only TIOA signal is evaluated in non-QDEC mode */
++ if (synapse->signal->id != 0) {
++ *action = COUNTER_SYNAPSE_ACTION_NONE;
++ return 0;
++ }
++
+ regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
+
+ switch (cmr & ATMEL_TC_ETRGEDG) {
+@@ -199,8 +209,8 @@ static int mchp_tc_count_action_write(struct counter_device *counter,
+ struct mchp_tc_data *const priv = counter_priv(counter);
+ u32 edge = ATMEL_TC_ETRGEDG_NONE;
+
+- /* QDEC mode is rising edge only */
+- if (priv->qdec_mode)
++ /* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */
++ if (priv->qdec_mode || synapse->signal->id != 0)
+ return -EINVAL;
+
+ switch (action) {
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index fc3ebeb0bbe59..6ff73c30769fa 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -27,6 +27,7 @@
+ #include <linux/pm_qos.h>
+ #include <trace/events/power.h>
+
++#include <asm/cpu.h>
+ #include <asm/div64.h>
+ #include <asm/msr.h>
+ #include <asm/cpu_device_id.h>
+@@ -280,10 +281,10 @@ static struct cpudata **all_cpu_data;
+ * structure is used to store those callbacks.
+ */
+ struct pstate_funcs {
+- int (*get_max)(void);
+- int (*get_max_physical)(void);
+- int (*get_min)(void);
+- int (*get_turbo)(void);
++ int (*get_max)(int cpu);
++ int (*get_max_physical)(int cpu);
++ int (*get_min)(int cpu);
++ int (*get_turbo)(int cpu);
+ int (*get_scaling)(void);
+ int (*get_cpu_scaling)(int cpu);
+ int (*get_aperf_mperf_shift)(void);
+@@ -398,16 +399,6 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
+
+ return cppc_perf.nominal_perf;
+ }
+-
+-static u32 intel_pstate_cppc_nominal(int cpu)
+-{
+- u64 nominal_perf;
+-
+- if (cppc_get_nominal_perf(cpu, &nominal_perf))
+- return 0;
+-
+- return nominal_perf;
+-}
+ #else /* CONFIG_ACPI_CPPC_LIB */
+ static inline void intel_pstate_set_itmt_prio(int cpu)
+ {
+@@ -531,35 +522,18 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
+ {
+ int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
+ int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
+- int perf_ctl_turbo = pstate_funcs.get_turbo();
+- int turbo_freq = perf_ctl_turbo * perf_ctl_scaling;
++ int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
+ int scaling = cpu->pstate.scaling;
+
+ pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
+- pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max());
+ pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
+ pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling);
+ pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
+ pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate);
+ pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling);
+
+- /*
+- * If the product of the HWP performance scaling factor and the HWP_CAP
+- * highest performance is greater than the maximum turbo frequency
+- * corresponding to the pstate_funcs.get_turbo() return value, the
+- * scaling factor is too high, so recompute it to make the HWP_CAP
+- * highest performance correspond to the maximum turbo frequency.
+- */
+- cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling;
+- if (turbo_freq < cpu->pstate.turbo_freq) {
+- cpu->pstate.turbo_freq = turbo_freq;
+- scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate);
+- cpu->pstate.scaling = scaling;
+-
+- pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n",
+- cpu->cpu, scaling);
+- }
+-
++ cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling,
++ perf_ctl_scaling);
+ cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
+ perf_ctl_scaling);
+
+@@ -1740,7 +1714,7 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
+ intel_pstate_update_epp_defaults(cpudata);
+ }
+
+-static int atom_get_min_pstate(void)
++static int atom_get_min_pstate(int not_used)
+ {
+ u64 value;
+
+@@ -1748,7 +1722,7 @@ static int atom_get_min_pstate(void)
+ return (value >> 8) & 0x7F;
+ }
+
+-static int atom_get_max_pstate(void)
++static int atom_get_max_pstate(int not_used)
+ {
+ u64 value;
+
+@@ -1756,7 +1730,7 @@ static int atom_get_max_pstate(void)
+ return (value >> 16) & 0x7F;
+ }
+
+-static int atom_get_turbo_pstate(void)
++static int atom_get_turbo_pstate(int not_used)
+ {
+ u64 value;
+
+@@ -1834,23 +1808,23 @@ static void atom_get_vid(struct cpudata *cpudata)
+ cpudata->vid.turbo = value & 0x7f;
+ }
+
+-static int core_get_min_pstate(void)
++static int core_get_min_pstate(int cpu)
+ {
+ u64 value;
+
+- rdmsrl(MSR_PLATFORM_INFO, value);
++ rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
+ return (value >> 40) & 0xFF;
+ }
+
+-static int core_get_max_pstate_physical(void)
++static int core_get_max_pstate_physical(int cpu)
+ {
+ u64 value;
+
+- rdmsrl(MSR_PLATFORM_INFO, value);
++ rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
+ return (value >> 8) & 0xFF;
+ }
+
+-static int core_get_tdp_ratio(u64 plat_info)
++static int core_get_tdp_ratio(int cpu, u64 plat_info)
+ {
+ /* Check how many TDP levels present */
+ if (plat_info & 0x600000000) {
+@@ -1860,13 +1834,13 @@ static int core_get_tdp_ratio(u64 plat_info)
+ int err;
+
+ /* Get the TDP level (0, 1, 2) to get ratios */
+- err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
++ err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
+ if (err)
+ return err;
+
+ /* TDP MSR are continuous starting at 0x648 */
+ tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03);
+- err = rdmsrl_safe(tdp_msr, &tdp_ratio);
++ err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio);
+ if (err)
+ return err;
+
+@@ -1883,7 +1857,7 @@ static int core_get_tdp_ratio(u64 plat_info)
+ return -ENXIO;
+ }
+
+-static int core_get_max_pstate(void)
++static int core_get_max_pstate(int cpu)
+ {
+ u64 tar;
+ u64 plat_info;
+@@ -1891,10 +1865,10 @@ static int core_get_max_pstate(void)
+ int tdp_ratio;
+ int err;
+
+- rdmsrl(MSR_PLATFORM_INFO, plat_info);
++ rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info);
+ max_pstate = (plat_info >> 8) & 0xFF;
+
+- tdp_ratio = core_get_tdp_ratio(plat_info);
++ tdp_ratio = core_get_tdp_ratio(cpu, plat_info);
+ if (tdp_ratio <= 0)
+ return max_pstate;
+
+@@ -1903,7 +1877,7 @@ static int core_get_max_pstate(void)
+ return tdp_ratio;
+ }
+
+- err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar);
++ err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar);
+ if (!err) {
+ int tar_levels;
+
+@@ -1918,13 +1892,13 @@ static int core_get_max_pstate(void)
+ return max_pstate;
+ }
+
+-static int core_get_turbo_pstate(void)
++static int core_get_turbo_pstate(int cpu)
+ {
+ u64 value;
+ int nont, ret;
+
+- rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
+- nont = core_get_max_pstate();
++ rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
++ nont = core_get_max_pstate(cpu);
+ ret = (value) & 255;
+ if (ret <= nont)
+ ret = nont;
+@@ -1952,50 +1926,37 @@ static int knl_get_aperf_mperf_shift(void)
+ return 10;
+ }
+
+-static int knl_get_turbo_pstate(void)
++static int knl_get_turbo_pstate(int cpu)
+ {
+ u64 value;
+ int nont, ret;
+
+- rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
+- nont = core_get_max_pstate();
++ rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
++ nont = core_get_max_pstate(cpu);
+ ret = (((value) >> 8) & 0xFF);
+ if (ret <= nont)
+ ret = nont;
+ return ret;
+ }
+
+-#ifdef CONFIG_ACPI_CPPC_LIB
+-static u32 hybrid_ref_perf;
+-
+-static int hybrid_get_cpu_scaling(int cpu)
++static void hybrid_get_type(void *data)
+ {
+- return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf,
+- intel_pstate_cppc_nominal(cpu));
++ u8 *cpu_type = data;
++
++ *cpu_type = get_this_hybrid_cpu_type();
+ }
+
+-static void intel_pstate_cppc_set_cpu_scaling(void)
++static int hybrid_get_cpu_scaling(int cpu)
+ {
+- u32 min_nominal_perf = U32_MAX;
+- int cpu;
++ u8 cpu_type = 0;
+
+- for_each_present_cpu(cpu) {
+- u32 nominal_perf = intel_pstate_cppc_nominal(cpu);
++ smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
++ /* P-cores have a smaller perf level-to-freqency scaling factor. */
++ if (cpu_type == 0x40)
++ return 78741;
+
+- if (nominal_perf && nominal_perf < min_nominal_perf)
+- min_nominal_perf = nominal_perf;
+- }
+-
+- if (min_nominal_perf < U32_MAX) {
+- hybrid_ref_perf = min_nominal_perf;
+- pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
+- }
++ return core_get_scaling();
+ }
+-#else
+-static inline void intel_pstate_cppc_set_cpu_scaling(void)
+-{
+-}
+-#endif /* CONFIG_ACPI_CPPC_LIB */
+
+ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+ {
+@@ -2025,10 +1986,10 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
+
+ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ {
+- int perf_ctl_max_phys = pstate_funcs.get_max_physical();
++ int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
+ int perf_ctl_scaling = pstate_funcs.get_scaling();
+
+- cpu->pstate.min_pstate = pstate_funcs.get_min();
++ cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
+ cpu->pstate.max_pstate_physical = perf_ctl_max_phys;
+ cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
+
+@@ -2044,8 +2005,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ }
+ } else {
+ cpu->pstate.scaling = perf_ctl_scaling;
+- cpu->pstate.max_pstate = pstate_funcs.get_max();
+- cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
++ cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
++ cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
+ }
+
+ if (cpu->pstate.scaling == perf_ctl_scaling) {
+@@ -3221,9 +3182,9 @@ static unsigned int force_load __initdata;
+
+ static int __init intel_pstate_msrs_not_valid(void)
+ {
+- if (!pstate_funcs.get_max() ||
+- !pstate_funcs.get_min() ||
+- !pstate_funcs.get_turbo())
++ if (!pstate_funcs.get_max(0) ||
++ !pstate_funcs.get_min(0) ||
++ !pstate_funcs.get_turbo(0))
+ return -ENODEV;
+
+ return 0;
+@@ -3450,7 +3411,7 @@ static int __init intel_pstate_init(void)
+ default_driver = &intel_pstate;
+
+ if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
+- intel_pstate_cppc_set_cpu_scaling();
++ pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
+
+ goto hwp_cpu_matched;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 2170db83e41d9..93ad00453f4b3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -509,13 +509,13 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
+ struct ttm_tt *ttm = bo->tbo.ttm;
+ int ret;
+
++ if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
++ return -EINVAL;
++
+ ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL);
+ if (unlikely(!ttm->sg))
+ return -ENOMEM;
+
+- if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
+- return -EINVAL;
+-
+ /* Same sequence as in amdgpu_ttm_tt_pin_userptr */
+ ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages,
+ ttm->num_pages, 0,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index 8ee4e8491f391..4048ba1b661e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -327,7 +327,10 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
+ if (r)
+ return r;
+
+- ctx->stable_pstate = current_stable_pstate;
++ if (mgr->adev->pm.stable_pstate_ctx)
++ ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
++ else
++ ctx->stable_pstate = current_stable_pstate;
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 91665fe44e7ca..9170aeaad93e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -3208,6 +3208,15 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
+ return r;
+ }
+ adev->ip_blocks[i].status.hw = true;
++
++ if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
++ /* disable gfxoff for IP resume. The gfxoff will be re-enabled in
++ * amdgpu_device_resume() after IP resume.
++ */
++ amdgpu_gfx_off_ctrl(adev, false);
++ DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
++ }
++
+ }
+
+ return 0;
+@@ -4180,6 +4189,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
+ /* Make sure IB tests flushed */
+ flush_delayed_work(&adev->delayed_init_work);
+
++ if (adev->in_s0ix) {
++ /* re-enable gfxoff after IP resume. This re-enables gfxoff after
++ * it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
++ */
++ amdgpu_gfx_off_ctrl(adev, true);
++ DRM_DEBUG("will enable gfxoff for the mission mode\n");
++ }
+ if (fbcon)
+ drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 134575a3893c5..9e6c23266a1a0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -424,8 +424,9 @@ error:
+ static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+ struct ttm_resource *mem)
+ {
+- uint64_t mem_size = (u64)mem->num_pages << PAGE_SHIFT;
++ u64 mem_size = (u64)mem->num_pages << PAGE_SHIFT;
+ struct amdgpu_res_cursor cursor;
++ u64 end;
+
+ if (mem->mem_type == TTM_PL_SYSTEM ||
+ mem->mem_type == TTM_PL_TT)
+@@ -434,12 +435,21 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+ return false;
+
+ amdgpu_res_first(mem, 0, mem_size, &cursor);
++ end = cursor.start + cursor.size;
++ while (cursor.remaining) {
++ amdgpu_res_next(&cursor, cursor.size);
+
+- /* ttm_resource_ioremap only supports contiguous memory */
+- if (cursor.size != mem_size)
+- return false;
++ if (!cursor.remaining)
++ break;
++
++ /* ttm_resource_ioremap only supports contiguous memory */
++ if (end != cursor.start)
++ return false;
++
++ end = cursor.start + cursor.size;
++ }
+
+- return cursor.start + cursor.size <= adev->gmc.visible_vram_size;
++ return end <= adev->gmc.visible_vram_size;
+ }
+
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+index 4d304f22889e4..998b5d17b271b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+@@ -32,8 +32,6 @@
+ #include "gc/gc_10_1_0_offset.h"
+ #include "soc15_common.h"
+
+-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid 0x064d
+-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX 0
+ #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid 0x0070
+ #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX 0
+
+@@ -574,7 +572,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
+ case IP_VERSION(2, 1, 0):
+ case IP_VERSION(2, 1, 1):
+ case IP_VERSION(2, 1, 2):
+- def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
+ def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
+ break;
+ default:
+@@ -608,8 +605,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
+ case IP_VERSION(2, 1, 0):
+ case IP_VERSION(2, 1, 1):
+ case IP_VERSION(2, 1, 2):
+- if (def != data)
+- WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
+ if (def1 != data1)
+ WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1);
+ break;
+@@ -634,8 +629,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
+ case IP_VERSION(2, 1, 0):
+ case IP_VERSION(2, 1, 1):
+ case IP_VERSION(2, 1, 2):
+- def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
+- break;
++ /* There is no ATCL2 in MMHUB for 2.1.x */
++ return;
+ default:
+ def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
+ break;
+@@ -646,18 +641,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
+ else
+ data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
+
+- if (def != data) {
+- switch (adev->ip_versions[MMHUB_HWIP][0]) {
+- case IP_VERSION(2, 1, 0):
+- case IP_VERSION(2, 1, 1):
+- case IP_VERSION(2, 1, 2):
+- WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
+- break;
+- default:
+- WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+- break;
+- }
+- }
++ if (def != data)
++ WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+ }
+
+ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
+@@ -695,7 +680,10 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
+ case IP_VERSION(2, 1, 0):
+ case IP_VERSION(2, 1, 1):
+ case IP_VERSION(2, 1, 2):
+- data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
++ /* There is no ATCL2 in MMHUB for 2.1.x. Keep the status
++ * based on DAGB
++ */
++ data = MM_ATC_L2_MISC_CG__ENABLE_MASK;
+ data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
+ break;
+ default:
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+index a5409531a2fdf..64f2412812624 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+@@ -795,6 +795,102 @@ static struct kfd_gpu_cache_info yellow_carp_cache_info[] = {
+ },
+ };
+
++static struct kfd_gpu_cache_info gfx1037_cache_info[] = {
++ {
++ /* TCP L1 Cache per CU */
++ .cache_size = 16,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 1,
++ },
++ {
++ /* Scalar L1 Instruction Cache per SQC */
++ .cache_size = 32,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_INST_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* Scalar L1 Data Cache per SQC */
++ .cache_size = 16,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* GL1 Data Cache per SA */
++ .cache_size = 128,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* L2 Data Cache per GPU (Total Tex Cache) */
++ .cache_size = 256,
++ .cache_level = 2,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++};
++
++static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = {
++ {
++ /* TCP L1 Cache per CU */
++ .cache_size = 16,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 1,
++ },
++ {
++ /* Scalar L1 Instruction Cache per SQC */
++ .cache_size = 32,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_INST_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* Scalar L1 Data Cache per SQC */
++ .cache_size = 16,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* GL1 Data Cache per SA */
++ .cache_size = 128,
++ .cache_level = 1,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++ {
++ /* L2 Data Cache per GPU (Total Tex Cache) */
++ .cache_size = 256,
++ .cache_level = 2,
++ .flags = (CRAT_CACHE_FLAGS_ENABLED |
++ CRAT_CACHE_FLAGS_DATA_CACHE |
++ CRAT_CACHE_FLAGS_SIMD_CACHE),
++ .num_cu_shared = 2,
++ },
++};
++
+ static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
+ struct crat_subtype_computeunit *cu)
+ {
+@@ -1514,11 +1610,17 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
+ num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
+ break;
+ case IP_VERSION(10, 3, 3):
+- case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
+- case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
+ pcache_info = yellow_carp_cache_info;
+ num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
+ break;
++ case IP_VERSION(10, 3, 6):
++ pcache_info = gc_10_3_6_cache_info;
++ num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info);
++ break;
++ case IP_VERSION(10, 3, 7):
++ pcache_info = gfx1037_cache_info;
++ num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info);
++ break;
+ case IP_VERSION(11, 0, 0):
+ case IP_VERSION(11, 0, 1):
+ case IP_VERSION(11, 0, 2):
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index 987bde4dca3db..af239b5565ae9 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -1369,7 +1369,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ {
+ struct amdgpu_device *adev = drm_to_adev(plane->dev);
+ const struct drm_format_info *info = drm_format_info(format);
+- struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id;
++ int i;
+
+ enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
+
+@@ -1386,49 +1386,13 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ return true;
+ }
+
+- /* check if swizzle mode is supported by this version of DCN */
+- switch (asic_id.chip_family) {
+- case FAMILY_SI:
+- case FAMILY_CI:
+- case FAMILY_KV:
+- case FAMILY_CZ:
+- case FAMILY_VI:
+- /* asics before AI does not have modifier support */
+- return false;
+- case FAMILY_AI:
+- case FAMILY_RV:
+- case FAMILY_NV:
+- case FAMILY_VGH:
+- case FAMILY_YELLOW_CARP:
+- case AMDGPU_FAMILY_GC_10_3_6:
+- case AMDGPU_FAMILY_GC_10_3_7:
+- switch (AMD_FMT_MOD_GET(TILE, modifier)) {
+- case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_D:
+- return true;
+- default:
+- return false;
+- }
+- break;
+- case AMDGPU_FAMILY_GC_11_0_0:
+- case AMDGPU_FAMILY_GC_11_0_1:
+- switch (AMD_FMT_MOD_GET(TILE, modifier)) {
+- case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
+- case AMD_FMT_MOD_TILE_GFX9_64K_D:
+- return true;
+- default:
+- return false;
+- }
+- break;
+- default:
+- ASSERT(0); /* Unknown asic */
+- break;
++ /* Check that the modifier is on the list of the plane's supported modifiers. */
++ for (i = 0; i < plane->modifier_count; i++) {
++ if (modifier == plane->modifiers[i])
++ break;
+ }
++ if (i == plane->modifier_count)
++ return false;
+
+ /*
+ * For D swizzle the canonical modifier depends on the bpp, so check
+diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
+index 49107a6cdac18..0dacbdb49a306 100644
+--- a/drivers/gpu/drm/bridge/parade-ps8640.c
++++ b/drivers/gpu/drm/bridge/parade-ps8640.c
+@@ -105,6 +105,7 @@ struct ps8640 {
+ struct gpio_desc *gpio_powerdown;
+ struct device_link *link;
+ bool pre_enabled;
++ bool need_post_hpd_delay;
+ };
+
+ static const struct regmap_config ps8640_regmap_config[] = {
+@@ -173,14 +174,31 @@ static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long wai
+ {
+ struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
+ int status;
++ int ret;
+
+ /*
+ * Apparently something about the firmware in the chip signals that
+ * HPD goes high by reporting GPIO9 as high (even though HPD isn't
+ * actually connected to GPIO9).
+ */
+- return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+- status & PS_GPIO9, wait_us / 10, wait_us);
++ ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
++ status & PS_GPIO9, wait_us / 10, wait_us);
++
++ /*
++ * The first time we see HPD go high after a reset we delay an extra
++ * 50 ms. The best guess is that the MCU is doing "stuff" during this
++ * time (maybe talking to the panel) and we don't want to interrupt it.
++ *
++ * No locking is done around "need_post_hpd_delay". If we're here we
++ * know we're holding a PM Runtime reference and the only other place
++ * that touches this is PM Runtime resume.
++ */
++ if (!ret && ps_bridge->need_post_hpd_delay) {
++ ps_bridge->need_post_hpd_delay = false;
++ msleep(50);
++ }
++
++ return ret;
+ }
+
+ static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
+@@ -376,6 +394,9 @@ static int __maybe_unused ps8640_resume(struct device *dev)
+ usleep_range(2000, 2500);
+ gpiod_set_value(ps_bridge->gpio_reset, 0);
+
++ /* We just reset things, so we need a delay after the first HPD */
++ ps_bridge->need_post_hpd_delay = true;
++
+ /*
+ * Mystery 200 ms delay for the "MCU to be ready". It's unclear if
+ * this is truly necessary since the MCU will already signal that
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 3ed7eeacc706b..d4492b6d23d25 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -3923,6 +3923,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
+
+ drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
+
++ intel_dp->frl.is_trained = false;
++
+ /* Restart FRL training or fall back to TMDS mode */
+ intel_dp_check_frl_training(intel_dp);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+index e8111fce56d03..dfa9a7c4ebc61 100644
+--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
++++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+@@ -2301,11 +2301,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
+ }
+
+ if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
+- IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
++ IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
+ /*
+ * Wa_1607030317:tgl
+ * Wa_1607186500:tgl
+- * Wa_1607297627:tgl,rkl,dg1[a0]
++ * Wa_1607297627:tgl,rkl,dg1[a0],adlp
+ *
+ * On TGL and RKL there are multiple entries for this WA in the
+ * BSpec; some indicate this is an A0-only WA, others indicate
+diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
+index 6ed5786bcd299..744cca507946b 100644
+--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
++++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
+@@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
+ pm_runtime_use_autosuspend(kdev);
+ }
+
+- /* Enable by default */
+- pm_runtime_allow(kdev);
++ /*
++ * FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
++ * As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
++ * function will be unsupported in case PCIe endpoint function is in D3.
++ * Let's keep i915 autosuspend control 'on' till we fix all known issue
++ * with lmem access in D3.
++ */
++ if (!IS_DGFX(i915))
++ pm_runtime_allow(kdev);
+
+ /*
+ * The core calls the driver load handler with an RPM reference held.
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+index 55f443328d8e7..730355f9e2d48 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+@@ -91,7 +91,7 @@ struct a6xx_state_memobj {
+ static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
+ {
+ struct a6xx_state_memobj *obj =
+- kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
++ kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
+
+ if (!obj)
+ return NULL;
+@@ -1040,8 +1040,11 @@ static void a6xx_gpu_state_destroy(struct kref *kref)
+ if (a6xx_state->gmu_hfi)
+ kvfree(a6xx_state->gmu_hfi->data);
+
++ if (a6xx_state->gmu_debug)
++ kvfree(a6xx_state->gmu_debug->data);
++
+ list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node)
+- kfree(obj);
++ kvfree(obj);
+
+ adreno_gpu_state_destroy(state);
+ kfree(a6xx_state);
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+index 382fb7f9e4976..5a0e8491cd3a0 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+@@ -729,7 +729,12 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
+ return buf;
+ }
+
+-/* len is expected to be in bytes */
++/* len is expected to be in bytes
++ *
++ * WARNING: *ptr should be allocated with kvmalloc or friends. It can be free'd
++ * with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
++ * when the unencoded raw data is encoded
++ */
+ void adreno_show_object(struct drm_printer *p, void **ptr, int len,
+ bool *encoded)
+ {
+diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
+index 7288041dd86ad..7444b75c42157 100644
+--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
+@@ -56,8 +56,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
+ return ret;
+ }
+
+-static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ struct mdp4_lvds_connector *mdp4_lvds_connector =
+ to_mdp4_lvds_connector(connector);
+diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+index 013ca02e17cbf..3ac139a4bbe8a 100644
+--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+@@ -1245,8 +1245,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
+ {
+ int ret = 0;
+ const u8 *dpcd = ctrl->panel->dpcd;
+- u8 encoding = DP_SET_ANSI_8B10B;
+- u8 ssc;
++ u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
+ u8 assr;
+ struct dp_link_info link_info = {0};
+
+@@ -1258,13 +1257,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
+
+ dp_aux_link_configure(ctrl->aux, &link_info);
+
+- if (drm_dp_max_downspread(dpcd)) {
+- ssc = DP_SPREAD_AMP_0_5;
+- drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1);
+- }
++ if (drm_dp_max_downspread(dpcd))
++ encoding[0] |= DP_SPREAD_AMP_0_5;
+
+- drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
+- &encoding, 1);
++ /* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
++ drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
+
+ if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
+ assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index bfd0aeff3f0d0..a49f6dbbe8883 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -1249,7 +1249,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
+ return -EINVAL;
+ }
+
+- rc = devm_request_irq(&dp->pdev->dev, dp->irq,
++ rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
+ dp_display_irq_handler,
+ IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
+ if (rc < 0) {
+@@ -1528,6 +1528,11 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
+ }
+ }
+
++static void of_dp_aux_depopulate_bus_void(void *data)
++{
++ of_dp_aux_depopulate_bus(data);
++}
++
+ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ {
+ int rc;
+@@ -1552,10 +1557,16 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ * panel driver is probed asynchronously but is the best we
+ * can do without a bigger driver reorganization.
+ */
+- rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
++ rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
+ of_node_put(aux_bus);
+ if (rc)
+ goto error;
++
++ rc = devm_add_action_or_reset(dp->drm_dev->dev,
++ of_dp_aux_depopulate_bus_void,
++ dp_priv->aux);
++ if (rc)
++ goto error;
+ } else if (dp->is_edp) {
+ DRM_ERROR("eDP aux_bus not found\n");
+ return -ENODEV;
+@@ -1568,7 +1579,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ * For DisplayPort interfaces external bridges are optional, so
+ * silently ignore an error if one is not present (-ENODEV).
+ */
+- rc = dp_parser_find_next_bridge(dp_priv->parser);
++ rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
+ if (!dp->is_edp && rc == -ENODEV)
+ return 0;
+
+@@ -1597,6 +1608,12 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
+ return -EINVAL;
+
+ priv = dev->dev_private;
++
++ if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++ DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++ return -ENOSPC;
++ }
++
+ dp_display->drm_dev = dev;
+
+ dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
+diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
+index 6df25f7662e79..6db82f9b03afb 100644
+--- a/drivers/gpu/drm/msm/dp/dp_drm.c
++++ b/drivers/gpu/drm/msm/dp/dp_drm.c
+@@ -31,6 +31,36 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
+ connector_status_disconnected;
+ }
+
++static int dp_bridge_atomic_check(struct drm_bridge *bridge,
++ struct drm_bridge_state *bridge_state,
++ struct drm_crtc_state *crtc_state,
++ struct drm_connector_state *conn_state)
++{
++ struct msm_dp *dp;
++
++ dp = to_dp_bridge(bridge)->dp_display;
++
++ drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
++ (dp->is_connected) ? "true" : "false");
++
++ /*
++ * There is no protection in the DRM framework to check if the display
++ * pipeline has been already disabled before trying to disable it again.
++ * Hence if the sink is unplugged, the pipeline gets disabled, but the
++ * crtc->active is still true. Any attempt to set the mode or manually
++ * disable this encoder will result in the crash.
++ *
++ * TODO: add support for telling the DRM subsystem that the pipeline is
++ * disabled by the hardware and thus all access to it should be forbidden.
++ * After that this piece of code can be removed.
++ */
++ if (bridge->ops & DRM_BRIDGE_OP_HPD)
++ return (dp->is_connected) ? 0 : -ENOTCONN;
++
++ return 0;
++}
++
++
+ /**
+ * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * @bridge: Poiner to drm bridge
+@@ -61,6 +91,9 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
+ }
+
+ static const struct drm_bridge_funcs dp_bridge_ops = {
++ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
++ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
++ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .enable = dp_bridge_enable,
+ .disable = dp_bridge_disable,
+ .post_disable = dp_bridge_post_disable,
+@@ -68,6 +101,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
+ .mode_valid = dp_bridge_mode_valid,
+ .get_modes = dp_bridge_get_modes,
+ .detect = dp_bridge_detect,
++ .atomic_check = dp_bridge_atomic_check,
+ };
+
+ struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
+index dd732215d55b4..dcbe893d66d7b 100644
+--- a/drivers/gpu/drm/msm/dp/dp_parser.c
++++ b/drivers/gpu/drm/msm/dp/dp_parser.c
+@@ -240,12 +240,12 @@ static int dp_parser_clock(struct dp_parser *parser)
+ return 0;
+ }
+
+-int dp_parser_find_next_bridge(struct dp_parser *parser)
++int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
+ {
+- struct device *dev = &parser->pdev->dev;
++ struct platform_device *pdev = parser->pdev;
+ struct drm_bridge *bridge;
+
+- bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
++ bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
+index 866c1a82bf1af..d30ab773db46d 100644
+--- a/drivers/gpu/drm/msm/dp/dp_parser.h
++++ b/drivers/gpu/drm/msm/dp/dp_parser.h
+@@ -138,8 +138,9 @@ struct dp_parser {
+ struct dp_parser *dp_parser_get(struct platform_device *pdev);
+
+ /**
+- * dp_parser_find_next_bridge() - find an additional bridge to DP
++ * devm_dp_parser_find_next_bridge() - find an additional bridge to DP
+ *
++ * @dev: device to tie bridge lifetime to
+ * @parser: dp_parser data from client
+ *
+ * This function is used to find any additional bridge attached to
+@@ -147,6 +148,6 @@ struct dp_parser *dp_parser_get(struct platform_device *pdev);
+ *
+ * Return: 0 if able to get the bridge, otherwise negative errno for failure.
+ */
+-int dp_parser_find_next_bridge(struct dp_parser *parser);
++int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser);
+
+ #endif
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
+index 1625328fa4302..3db85b5c0febd 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.c
++++ b/drivers/gpu/drm/msm/dsi/dsi.c
+@@ -227,6 +227,12 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
+ return -EINVAL;
+
+ priv = dev->dev_private;
++
++ if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++ DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++ return -ENOSPC;
++ }
++
+ msm_dsi->dev = dev;
+
+ ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index 93fe61b869670..f28fb21e38911 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -300,6 +300,11 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+ struct platform_device *pdev = hdmi->pdev;
+ int ret;
+
++ if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++ DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++ return -ENOSPC;
++ }
++
+ hdmi->dev = dev;
+ hdmi->encoder = encoder;
+
+@@ -339,7 +344,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+ goto fail;
+ }
+
+- ret = devm_request_irq(&pdev->dev, hdmi->irq,
++ ret = devm_request_irq(dev->dev, hdmi->irq,
+ msm_hdmi_irq, IRQF_TRIGGER_HIGH,
+ "hdmi_isr", hdmi);
+ if (ret < 0) {
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index 0759e2d99f59c..869ba58f02544 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -241,6 +241,7 @@ static int msm_drm_uninit(struct device *dev)
+
+ for (i = 0; i < priv->num_bridges; i++)
+ drm_bridge_remove(priv->bridges[i]);
++ priv->num_bridges = 0;
+
+ pm_runtime_get_sync(dev);
+ msm_irq_uninstall(ddev);
+diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
+index 8988b2ed2ea6f..dcd607a0c41a1 100644
+--- a/drivers/hwtracing/coresight/coresight-cti-core.c
++++ b/drivers/hwtracing/coresight/coresight-cti-core.c
+@@ -90,11 +90,9 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
+ static int cti_enable_hw(struct cti_drvdata *drvdata)
+ {
+ struct cti_config *config = &drvdata->config;
+- struct device *dev = &drvdata->csdev->dev;
+ unsigned long flags;
+ int rc = 0;
+
+- pm_runtime_get_sync(dev->parent);
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+
+ /* no need to do anything if enabled or unpowered*/
+@@ -119,7 +117,6 @@ cti_state_unchanged:
+ /* cannot enable due to error */
+ cti_err_not_enabled:
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+- pm_runtime_put(dev->parent);
+ return rc;
+ }
+
+@@ -153,7 +150,6 @@ cti_hp_not_enabled:
+ static int cti_disable_hw(struct cti_drvdata *drvdata)
+ {
+ struct cti_config *config = &drvdata->config;
+- struct device *dev = &drvdata->csdev->dev;
+ struct coresight_device *csdev = drvdata->csdev;
+
+ spin_lock(&drvdata->spinlock);
+@@ -175,7 +171,6 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
+ coresight_disclaim_device_unlocked(csdev);
+ CS_LOCK(drvdata->base);
+ spin_unlock(&drvdata->spinlock);
+- pm_runtime_put(dev->parent);
+ return 0;
+
+ /* not disabled this call */
+diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c
+index 47feb375b70be..7c7d780407937 100644
+--- a/drivers/iio/accel/adxl367.c
++++ b/drivers/iio/accel/adxl367.c
+@@ -1185,17 +1185,30 @@ static ssize_t adxl367_get_fifo_watermark(struct device *dev,
+ return sysfs_emit(buf, "%d\n", fifo_watermark);
+ }
+
+-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+-static IIO_CONST_ATTR(hwfifo_watermark_max,
+- __stringify(ADXL367_FIFO_MAX_WATERMARK));
++static ssize_t hwfifo_watermark_min_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "%s\n", "1");
++}
++
++static ssize_t hwfifo_watermark_max_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK));
++}
++
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
+ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+ adxl367_get_fifo_watermark, NULL, 0);
+ static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ adxl367_get_fifo_enabled, NULL, 0);
+
+ static const struct attribute *adxl367_fifo_attributes[] = {
+- &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+- &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
++ &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
++ &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ NULL,
+diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
+index e3ecbaee61f70..bc53af809d5de 100644
+--- a/drivers/iio/accel/adxl372.c
++++ b/drivers/iio/accel/adxl372.c
+@@ -998,17 +998,30 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev,
+ return sprintf(buf, "%d\n", st->watermark);
+ }
+
+-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+-static IIO_CONST_ATTR(hwfifo_watermark_max,
+- __stringify(ADXL372_FIFO_SIZE));
++static ssize_t hwfifo_watermark_min_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "%s\n", "1");
++}
++
++static ssize_t hwfifo_watermark_max_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE));
++}
++
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
+ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+ adxl372_get_fifo_watermark, NULL, 0);
+ static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ adxl372_get_fifo_enabled, NULL, 0);
+
+ static const struct attribute *adxl372_fifo_attributes[] = {
+- &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+- &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
++ &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
++ &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ NULL,
+diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c
+index 82662dab87c0f..94d75ec687c38 100644
+--- a/drivers/iio/light/tsl2583.c
++++ b/drivers/iio/light/tsl2583.c
+@@ -858,7 +858,7 @@ static int tsl2583_probe(struct i2c_client *clientp,
+ TSL2583_POWER_OFF_DELAY_MS);
+ pm_runtime_use_autosuspend(&clientp->dev);
+
+- ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
++ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&clientp->dev, "%s: iio registration failed\n",
+ __func__);
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index b652d2b39bcf2..a60ccf1836872 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -1385,13 +1385,6 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
+ return ret;
+ }
+
+- st->iio_chan = devm_kzalloc(&st->spi->dev,
+- st->iio_channels * sizeof(*st->iio_chan),
+- GFP_KERNEL);
+-
+- if (!st->iio_chan)
+- return -ENOMEM;
+-
+ ret = regmap_update_bits(st->regmap, LTC2983_GLOBAL_CONFIG_REG,
+ LTC2983_NOTCH_FREQ_MASK,
+ LTC2983_NOTCH_FREQ(st->filter_notch_freq));
+@@ -1514,6 +1507,12 @@ static int ltc2983_probe(struct spi_device *spi)
+ gpiod_set_value_cansleep(gpio, 0);
+ }
+
++ st->iio_chan = devm_kzalloc(&spi->dev,
++ st->iio_channels * sizeof(*st->iio_chan),
++ GFP_KERNEL);
++ if (!st->iio_chan)
++ return -ENOMEM;
++
+ ret = ltc2983_setup(st, true);
+ if (ret)
+ return ret;
+diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c
+index c7bdfc69b9be8..5c9c7c52cfc40 100644
+--- a/drivers/media/i2c/ar0521.c
++++ b/drivers/media/i2c/ar0521.c
+@@ -756,10 +756,12 @@ static int ar0521_power_on(struct device *dev)
+ gpiod_set_value(sensor->reset_gpio, 0);
+ usleep_range(4500, 5000); /* min 45000 clocks */
+
+- for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++)
+- if (ar0521_write_regs(sensor, initial_regs[cnt].data,
+- initial_regs[cnt].count))
++ for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) {
++ ret = ar0521_write_regs(sensor, initial_regs[cnt].data,
++ initial_regs[cnt].count);
++ if (ret)
+ goto off;
++ }
+
+ ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT,
+ AR0521_REG_SERIAL_FORMAT_MIPI |
+diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
+index b8f4f0d3e33d7..15d0f79231dd6 100644
+--- a/drivers/media/i2c/ov8865.c
++++ b/drivers/media/i2c/ov8865.c
+@@ -3034,11 +3034,13 @@ static int ov8865_probe(struct i2c_client *client)
+ &rate);
+ if (!ret && sensor->extclk) {
+ ret = clk_set_rate(sensor->extclk, rate);
+- if (ret)
+- return dev_err_probe(dev, ret,
+- "failed to set clock rate\n");
++ if (ret) {
++ dev_err_probe(dev, ret, "failed to set clock rate\n");
++ goto error_endpoint;
++ }
+ } else if (ret && !sensor->extclk) {
+- return dev_err_probe(dev, ret, "invalid clock config\n");
++ dev_err_probe(dev, ret, "invalid clock config\n");
++ goto error_endpoint;
+ }
+
+ sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 8a3eed957ae6e..b779e0ba916ca 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -603,6 +603,10 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
+ inst->workqueue = NULL;
+ }
+
++ if (inst->fh.m2m_ctx) {
++ v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
++ inst->fh.m2m_ctx = NULL;
++ }
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
+ mutex_destroy(&inst->lock);
+ v4l2_fh_del(&inst->fh);
+@@ -685,13 +689,6 @@ int vpu_v4l2_close(struct file *file)
+
+ vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+
+- vpu_inst_lock(inst);
+- if (inst->fh.m2m_ctx) {
+- v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+- inst->fh.m2m_ctx = NULL;
+- }
+- vpu_inst_unlock(inst);
+-
+ call_void_vop(inst, release);
+ vpu_inst_unregister(inst);
+ vpu_inst_put(inst);
+diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
+index 7960e6836f415..60610c04d6a76 100644
+--- a/drivers/media/platform/sunxi/sun4i-csi/Kconfig
++++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
+@@ -3,7 +3,7 @@
+ config VIDEO_SUN4I_CSI
+ tristate "Allwinner A10 CMOS Sensor Interface Support"
+ depends on V4L_PLATFORM_DRIVERS
+- depends on VIDEO_DEV && COMMON_CLK && HAS_DMA
++ depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA
+ depends on ARCH_SUNXI || COMPILE_TEST
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+diff --git a/drivers/media/platform/sunxi/sun6i-csi/Kconfig b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
+index 0345901617d41..e5b6991ce7f04 100644
+--- a/drivers/media/platform/sunxi/sun6i-csi/Kconfig
++++ b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
+@@ -2,7 +2,7 @@
+ config VIDEO_SUN6I_CSI
+ tristate "Allwinner V3s Camera Sensor Interface driver"
+ depends on V4L_PLATFORM_DRIVERS
+- depends on VIDEO_DEV && COMMON_CLK && HAS_DMA
++ depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA
+ depends on ARCH_SUNXI || COMPILE_TEST
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig b/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
+index eb982466abd30..08852f63692b6 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
+@@ -3,11 +3,11 @@ config VIDEO_SUN6I_MIPI_CSI2
+ tristate "Allwinner A31 MIPI CSI-2 Controller Driver"
+ depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV
+ depends on ARCH_SUNXI || COMPILE_TEST
+- depends on PM && COMMON_CLK
++ depends on PM && COMMON_CLK && RESET_CONTROLLER
++ depends on PHY_SUN6I_MIPI_DPHY
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
+- select PHY_SUN6I_MIPI_DPHY
+ select GENERIC_PHY_MIPI_DPHY
+ select REGMAP_MMIO
+ help
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+index a4e3f9a6b2ff2..30d6c0c5161f4 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+@@ -661,7 +661,8 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ csi2_dev->reset = devm_reset_control_get_shared(dev, NULL);
+ if (IS_ERR(csi2_dev->reset)) {
+ dev_err(dev, "failed to get reset controller\n");
+- return PTR_ERR(csi2_dev->reset);
++ ret = PTR_ERR(csi2_dev->reset);
++ goto error_clock_rate_exclusive;
+ }
+
+ /* D-PHY */
+@@ -669,13 +670,14 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ csi2_dev->dphy = devm_phy_get(dev, "dphy");
+ if (IS_ERR(csi2_dev->dphy)) {
+ dev_err(dev, "failed to get MIPI D-PHY\n");
+- return PTR_ERR(csi2_dev->dphy);
++ ret = PTR_ERR(csi2_dev->dphy);
++ goto error_clock_rate_exclusive;
+ }
+
+ ret = phy_init(csi2_dev->dphy);
+ if (ret) {
+ dev_err(dev, "failed to initialize MIPI D-PHY\n");
+- return ret;
++ goto error_clock_rate_exclusive;
+ }
+
+ /* Runtime PM */
+@@ -683,6 +685,11 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ pm_runtime_enable(dev);
+
+ return 0;
++
++error_clock_rate_exclusive:
++ clk_rate_exclusive_put(csi2_dev->clock_mod);
++
++ return ret;
+ }
+
+ static void
+@@ -712,9 +719,14 @@ static int sun6i_mipi_csi2_probe(struct platform_device *platform_dev)
+
+ ret = sun6i_mipi_csi2_bridge_setup(csi2_dev);
+ if (ret)
+- return ret;
++ goto error_resources;
+
+ return 0;
++
++error_resources:
++ sun6i_mipi_csi2_resources_cleanup(csi2_dev);
++
++ return ret;
+ }
+
+ static int sun6i_mipi_csi2_remove(struct platform_device *platform_dev)
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
+index 789d58ee12ea9..47a8c0fb7eb9f 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
+@@ -3,7 +3,7 @@ config VIDEO_SUN8I_A83T_MIPI_CSI2
+ tristate "Allwinner A83T MIPI CSI-2 Controller and D-PHY Driver"
+ depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV
+ depends on ARCH_SUNXI || COMPILE_TEST
+- depends on PM && COMMON_CLK
++ depends on PM && COMMON_CLK && RESET_CONTROLLER
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+index d052ee77ef0aa..b032ec13a683a 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+@@ -719,13 +719,15 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ csi2_dev->clock_mipi = devm_clk_get(dev, "mipi");
+ if (IS_ERR(csi2_dev->clock_mipi)) {
+ dev_err(dev, "failed to acquire mipi clock\n");
+- return PTR_ERR(csi2_dev->clock_mipi);
++ ret = PTR_ERR(csi2_dev->clock_mipi);
++ goto error_clock_rate_exclusive;
+ }
+
+ csi2_dev->clock_misc = devm_clk_get(dev, "misc");
+ if (IS_ERR(csi2_dev->clock_misc)) {
+ dev_err(dev, "failed to acquire misc clock\n");
+- return PTR_ERR(csi2_dev->clock_misc);
++ ret = PTR_ERR(csi2_dev->clock_misc);
++ goto error_clock_rate_exclusive;
+ }
+
+ /* Reset */
+@@ -733,7 +735,8 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ csi2_dev->reset = devm_reset_control_get_shared(dev, NULL);
+ if (IS_ERR(csi2_dev->reset)) {
+ dev_err(dev, "failed to get reset controller\n");
+- return PTR_ERR(csi2_dev->reset);
++ ret = PTR_ERR(csi2_dev->reset);
++ goto error_clock_rate_exclusive;
+ }
+
+ /* D-PHY */
+@@ -741,7 +744,7 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ ret = sun8i_a83t_dphy_register(csi2_dev);
+ if (ret) {
+ dev_err(dev, "failed to initialize MIPI D-PHY\n");
+- return ret;
++ goto error_clock_rate_exclusive;
+ }
+
+ /* Runtime PM */
+@@ -749,6 +752,11 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ pm_runtime_enable(dev);
+
+ return 0;
++
++error_clock_rate_exclusive:
++ clk_rate_exclusive_put(csi2_dev->clock_mod);
++
++ return ret;
+ }
+
+ static void
+@@ -778,9 +786,14 @@ static int sun8i_a83t_mipi_csi2_probe(struct platform_device *platform_dev)
+
+ ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev);
+ if (ret)
+- return ret;
++ goto error_resources;
+
+ return 0;
++
++error_resources:
++ sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev);
++
++ return ret;
+ }
+
+ static int sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev)
+diff --git a/drivers/media/platform/sunxi/sun8i-di/Kconfig b/drivers/media/platform/sunxi/sun8i-di/Kconfig
+index ff71e06ee2dfe..f688396913b79 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-di/Kconfig
+@@ -4,7 +4,7 @@ config VIDEO_SUN8I_DEINTERLACE
+ depends on V4L_MEM2MEM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_SUNXI || COMPILE_TEST
+- depends on COMMON_CLK && OF
++ depends on COMMON_CLK && RESET_CONTROLLER && OF
+ depends on PM
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+diff --git a/drivers/media/platform/sunxi/sun8i-rotate/Kconfig b/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
+index cfba29072d752..ee2c1f248c646 100644
+--- a/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
+@@ -5,7 +5,7 @@ config VIDEO_SUN8I_ROTATE
+ depends on V4L_MEM2MEM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_SUNXI || COMPILE_TEST
+- depends on COMMON_CLK && OF
++ depends on COMMON_CLK && RESET_CONTROLLER && OF
+ depends on PM
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
+index 04b75666bad4d..f28440e6c9f89 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.c
++++ b/drivers/media/test-drivers/vivid/vivid-core.c
+@@ -339,6 +339,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
+ return vivid_vid_out_g_fbuf(file, fh, a);
+ }
+
++/*
++ * Only support the framebuffer of one of the vivid instances.
++ * Anything else is rejected.
++ */
++bool vivid_validate_fb(const struct v4l2_framebuffer *a)
++{
++ struct vivid_dev *dev;
++ int i;
++
++ for (i = 0; i < n_devs; i++) {
++ dev = vivid_devs[i];
++ if (!dev || !dev->video_pbase)
++ continue;
++ if ((unsigned long)a->base == dev->video_pbase &&
++ a->fmt.width <= dev->display_width &&
++ a->fmt.height <= dev->display_height &&
++ a->fmt.bytesperline <= dev->display_byte_stride)
++ return true;
++ }
++ return false;
++}
++
+ static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
+ {
+ struct video_device *vdev = video_devdata(file);
+@@ -920,8 +942,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
+
+ /* how many inputs do we have and of what type? */
+ dev->num_inputs = num_inputs[inst];
+- if (dev->num_inputs < 1)
+- dev->num_inputs = 1;
++ if (node_type & 0x20007) {
++ if (dev->num_inputs < 1)
++ dev->num_inputs = 1;
++ } else {
++ dev->num_inputs = 0;
++ }
+ if (dev->num_inputs >= MAX_INPUTS)
+ dev->num_inputs = MAX_INPUTS;
+ for (i = 0; i < dev->num_inputs; i++) {
+@@ -938,8 +964,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
+
+ /* how many outputs do we have and of what type? */
+ dev->num_outputs = num_outputs[inst];
+- if (dev->num_outputs < 1)
+- dev->num_outputs = 1;
++ if (node_type & 0x40300) {
++ if (dev->num_outputs < 1)
++ dev->num_outputs = 1;
++ } else {
++ dev->num_outputs = 0;
++ }
+ if (dev->num_outputs >= MAX_OUTPUTS)
+ dev->num_outputs = MAX_OUTPUTS;
+ for (i = 0; i < dev->num_outputs; i++) {
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h
+index 176b72cb143b6..5def9b2a359ad 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.h
++++ b/drivers/media/test-drivers/vivid/vivid-core.h
+@@ -610,4 +610,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
+ return dev->output_type[dev->output] == HDMI;
+ }
+
++bool vivid_validate_fb(const struct v4l2_framebuffer *a);
++
+ #endif
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index b9caa4b26209e..99139a8cd4c4f 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -452,6 +452,12 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
+ tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
+ dev->crop_cap = dev->src_rect;
+ dev->crop_bounds_cap = dev->src_rect;
++ if (dev->bitmap_cap &&
++ (dev->compose_cap.width != dev->crop_cap.width ||
++ dev->compose_cap.height != dev->crop_cap.height)) {
++ vfree(dev->bitmap_cap);
++ dev->bitmap_cap = NULL;
++ }
+ dev->compose_cap = dev->crop_cap;
+ if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
+ dev->compose_cap.height /= 2;
+@@ -909,6 +915,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ struct vivid_dev *dev = video_drvdata(file);
+ struct v4l2_rect *crop = &dev->crop_cap;
+ struct v4l2_rect *compose = &dev->compose_cap;
++ unsigned orig_compose_w = compose->width;
++ unsigned orig_compose_h = compose->height;
+ unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
+ int ret;
+
+@@ -1025,17 +1033,17 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ s->r.height /= factor;
+ }
+ v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
+- if (dev->bitmap_cap && (compose->width != s->r.width ||
+- compose->height != s->r.height)) {
+- vfree(dev->bitmap_cap);
+- dev->bitmap_cap = NULL;
+- }
+ *compose = s->r;
+ break;
+ default:
+ return -EINVAL;
+ }
+
++ if (dev->bitmap_cap && (compose->width != orig_compose_w ||
++ compose->height != orig_compose_h)) {
++ vfree(dev->bitmap_cap);
++ dev->bitmap_cap = NULL;
++ }
+ tpg_s_crop_compose(&dev->tpg, crop, compose);
+ return 0;
+ }
+@@ -1272,7 +1280,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
+ return -EINVAL;
+ if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
+ return -EINVAL;
+- if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
++ if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
++ return -EINVAL;
++
++ /*
++ * Only support the framebuffer of one of the vivid instances.
++ * Anything else is rejected.
++ */
++ if (!vivid_validate_fb(a))
+ return -EINVAL;
+
+ dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
+diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
+index af48705c704f8..003c32fed3f75 100644
+--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
++++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
+@@ -161,6 +161,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
+ (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
+ return false;
++
++ /* sanity checks for the blanking timings */
++ if (!bt->interlaced &&
++ (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
++ return false;
++ if (bt->hfrontporch > 2 * bt->width ||
++ bt->hsync > 1024 || bt->hbackporch > 1024)
++ return false;
++ if (bt->vfrontporch > 4096 ||
++ bt->vsync > 128 || bt->vbackporch > 4096)
++ return false;
++ if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
++ bt->il_vsync > 128 || bt->il_vbackporch > 4096))
++ return false;
+ return fnc == NULL || fnc(t, fnc_handle);
+ }
+ EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings);
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index 54cd009aee50e..db6d8a0999100 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -134,6 +134,7 @@ struct mmc_blk_data {
+ * track of the current selected device partition.
+ */
+ unsigned int part_curr;
++#define MMC_BLK_PART_INVALID UINT_MAX /* Unknown partition active */
+ int area_type;
+
+ /* debugfs files (only in main mmc_blk_data) */
+@@ -987,33 +988,39 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
+ return ms;
+ }
+
++/*
++ * Attempts to reset the card and get back to the requested partition.
++ * Therefore any error here must result in cancelling the block layer
++ * request, it must not be reattempted without going through the mmc_blk
++ * partition sanity checks.
++ */
+ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
+ int type)
+ {
+ int err;
++ struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev);
+
+ if (md->reset_done & type)
+ return -EEXIST;
+
+ md->reset_done |= type;
+ err = mmc_hw_reset(host->card);
++ /*
++ * A successful reset will leave the card in the main partition, but
++ * upon failure it might not be, so set it to MMC_BLK_PART_INVALID
++ * in that case.
++ */
++ main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
++ if (err)
++ return err;
+ /* Ensure we switch back to the correct partition */
+- if (err) {
+- struct mmc_blk_data *main_md =
+- dev_get_drvdata(&host->card->dev);
+- int part_err;
+-
+- main_md->part_curr = main_md->part_type;
+- part_err = mmc_blk_part_switch(host->card, md->part_type);
+- if (part_err) {
+- /*
+- * We have failed to get back into the correct
+- * partition, so we need to abort the whole request.
+- */
+- return -ENODEV;
+- }
+- }
+- return err;
++ if (mmc_blk_part_switch(host->card, md->part_type))
++ /*
++ * We have failed to get back into the correct
++ * partition, so we need to abort the whole request.
++ */
++ return -ENODEV;
++ return 0;
+ }
+
+ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
+@@ -1871,8 +1878,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
+ return;
+
+ /* Reset before last retry */
+- if (mqrq->retries + 1 == MMC_MAX_RETRIES)
+- mmc_blk_reset(md, card->host, type);
++ if (mqrq->retries + 1 == MMC_MAX_RETRIES &&
++ mmc_blk_reset(md, card->host, type))
++ return;
+
+ /* Command errors fail fast, so use all MMC_MAX_RETRIES */
+ if (brq->sbc.error || brq->cmd.error)
+diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
+index fefaa901b50f3..b396e39007177 100644
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -48,6 +48,7 @@ static enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
+ case REQ_OP_DRV_OUT:
+ case REQ_OP_DISCARD:
+ case REQ_OP_SECURE_ERASE:
++ case REQ_OP_WRITE_ZEROES:
+ return MMC_ISSUE_SYNC;
+ case REQ_OP_FLUSH:
+ return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
+@@ -493,6 +494,13 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
+ if (blk_queue_quiesced(q))
+ blk_mq_unquiesce_queue(q);
+
++ /*
++ * If the recovery completes the last (and only remaining) request in
++ * the queue, and the card has been removed, we could end up here with
++ * the recovery not quite finished yet, so cancel it.
++ */
++ cancel_work_sync(&mq->recovery_work);
++
+ blk_mq_free_tag_set(&mq->tag_set);
+
+ /*
+diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
+index c6268c38c69e5..babf21a0adeb6 100644
+--- a/drivers/mmc/core/sdio_bus.c
++++ b/drivers/mmc/core/sdio_bus.c
+@@ -291,7 +291,8 @@ static void sdio_release_func(struct device *dev)
+ {
+ struct sdio_func *func = dev_to_sdio_func(dev);
+
+- sdio_free_func_cis(func);
++ if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
++ sdio_free_func_cis(func);
+
+ kfree(func->info);
+ kfree(func->tmpbuf);
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index e63608834411a..97a6ea4a3ac79 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -1074,9 +1074,10 @@ config MMC_SDHCI_OMAP
+
+ config MMC_SDHCI_AM654
+ tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
+- depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
++ depends on MMC_SDHCI_PLTFM && OF
+ select MMC_SDHCI_IO_ACCESSORS
+ select MMC_CQHCI
++ select REGMAP_MMIO
+ help
+ This selects the Secure Digital Host Controller Interface (SDHCI)
+ support present in TI's AM654 SOCs. The controller supports
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 55981b0f0b10c..747df79d90eef 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1660,6 +1660,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ host->mmc_host_ops.execute_tuning = usdhc_execute_tuning;
+ }
+
++ err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
++ if (err)
++ goto disable_ahb_clk;
++
+ if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
+ sdhci_esdhc_ops.platform_execute_tuning =
+ esdhc_executing_tuning;
+@@ -1667,13 +1671,15 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
+ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+
+- if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
++ if (host->caps & MMC_CAP_8_BIT_DATA &&
++ imx_data->socdata->flags & ESDHC_FLAG_HS400)
+ host->mmc->caps2 |= MMC_CAP2_HS400;
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
+ host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
+
+- if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
++ if (host->caps & MMC_CAP_8_BIT_DATA &&
++ imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+ host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+ host->mmc_host_ops.hs400_enhanced_strobe =
+ esdhc_hs400_enhanced_strobe;
+@@ -1695,10 +1701,6 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ goto disable_ahb_clk;
+ }
+
+- err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
+- if (err)
+- goto disable_ahb_clk;
+-
+ sdhci_esdhc_imx_hwinit(host);
+
+ err = sdhci_add_host(host);
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index 622b7de96c7f6..b6f4bd3d93cd8 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -893,6 +893,12 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
+ dmi_match(DMI_SYS_VENDOR, "IRBIS"));
+ }
+
++static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot)
++{
++ return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC &&
++ dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC.");
++}
++
+ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ {
+ int ret = byt_emmc_probe_slot(slot);
+@@ -901,9 +907,11 @@ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ slot->host->mmc->caps2 |= MMC_CAP2_CQE;
+
+ if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
+- slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+- slot->host->mmc_host_ops.hs400_enhanced_strobe =
+- intel_hs400_enhanced_strobe;
++ if (!jsl_broken_hs400es(slot)) {
++ slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
++ slot->host->mmc_host_ops.hs400_enhanced_strobe =
++ intel_hs400_enhanced_strobe;
++ }
+ slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;
+ }
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index a9b8be9f40dc2..477707bcad972 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -562,7 +562,7 @@ static void mtd_check_of_node(struct mtd_info *mtd)
+ if (!mtd_is_partition(mtd))
+ return;
+ parent = mtd->parent;
+- parent_dn = dev_of_node(&parent->dev);
++ parent_dn = of_node_get(dev_of_node(&parent->dev));
+ if (!parent_dn)
+ return;
+
+diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
+index 056835fd45622..4c721704d2fdb 100644
+--- a/drivers/mtd/nand/raw/intel-nand-controller.c
++++ b/drivers/mtd/nand/raw/intel-nand-controller.c
+@@ -108,7 +108,6 @@
+
+ struct ebu_nand_cs {
+ void __iomem *chipaddr;
+- dma_addr_t nand_pa;
+ u32 addr_sel;
+ };
+
+@@ -596,13 +595,11 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ ebu_host->dev = dev;
+ nand_controller_init(&ebu_host->controller);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebunand");
+- ebu_host->ebu = devm_ioremap_resource(&pdev->dev, res);
++ ebu_host->ebu = devm_platform_ioremap_resource_byname(pdev, "ebunand");
+ if (IS_ERR(ebu_host->ebu))
+ return PTR_ERR(ebu_host->ebu);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsnand");
+- ebu_host->hsnand = devm_ioremap_resource(&pdev->dev, res);
++ ebu_host->hsnand = devm_platform_ioremap_resource_byname(pdev, "hsnand");
+ if (IS_ERR(ebu_host->hsnand))
+ return PTR_ERR(ebu_host->hsnand);
+
+@@ -614,31 +611,35 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ ret = of_property_read_u32(chip_np, "reg", &cs);
+ if (ret) {
+ dev_err(dev, "failed to get chip select: %d\n", ret);
+- return ret;
++ goto err_of_node_put;
+ }
+ if (cs >= MAX_CS) {
+ dev_err(dev, "got invalid chip select: %d\n", cs);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err_of_node_put;
+ }
+
+ ebu_host->cs_num = cs;
+
+ resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
+- ebu_host->cs[cs].chipaddr = devm_ioremap_resource(dev, res);
+- if (IS_ERR(ebu_host->cs[cs].chipaddr))
+- return PTR_ERR(ebu_host->cs[cs].chipaddr);
+- ebu_host->cs[cs].nand_pa = res->start;
++ ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
++ resname);
++ if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
++ ret = PTR_ERR(ebu_host->cs[cs].chipaddr);
++ goto err_of_node_put;
++ }
+
+ ebu_host->clk = devm_clk_get(dev, NULL);
+- if (IS_ERR(ebu_host->clk))
+- return dev_err_probe(dev, PTR_ERR(ebu_host->clk),
+- "failed to get clock\n");
++ if (IS_ERR(ebu_host->clk)) {
++ ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk),
++ "failed to get clock\n");
++ goto err_of_node_put;
++ }
+
+ ret = clk_prepare_enable(ebu_host->clk);
+ if (ret) {
+ dev_err(dev, "failed to enable clock: %d\n", ret);
+- return ret;
++ goto err_of_node_put;
+ }
+ ebu_host->clk_rate = clk_get_rate(ebu_host->clk);
+
+@@ -703,6 +704,8 @@ err_cleanup_dma:
+ ebu_dma_cleanup(ebu_host);
+ err_disable_unprepare_clk:
+ clk_disable_unprepare(ebu_host->clk);
++err_of_node_put:
++ of_node_put(chip_np);
+
+ return ret;
+ }
+diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
+index 2455a581fd70c..b248c5f657d56 100644
+--- a/drivers/mtd/nand/raw/marvell_nand.c
++++ b/drivers/mtd/nand/raw/marvell_nand.c
+@@ -2672,7 +2672,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
+ chip->controller = &nfc->controller;
+ nand_set_flash_node(chip, np);
+
+- if (!of_property_read_bool(np, "marvell,nand-keep-config"))
++ if (of_property_read_bool(np, "marvell,nand-keep-config"))
+ chip->options |= NAND_KEEP_TIMINGS;
+
+ mtd = nand_to_mtd(chip);
+diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
+index e12f9f580a15f..a9b9031ce6167 100644
+--- a/drivers/mtd/nand/raw/tegra_nand.c
++++ b/drivers/mtd/nand/raw/tegra_nand.c
+@@ -1181,7 +1181,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+ err = pm_runtime_resume_and_get(&pdev->dev);
+ if (err)
+- return err;
++ goto err_dis_pm;
+
+ err = reset_control_reset(rst);
+ if (err) {
+@@ -1215,6 +1215,8 @@ static int tegra_nand_probe(struct platform_device *pdev)
+ err_put_pm:
+ pm_runtime_put_sync_suspend(ctrl->dev);
+ pm_runtime_force_suspend(ctrl->dev);
++err_dis_pm:
++ pm_runtime_disable(&pdev->dev);
+ return err;
+ }
+
+diff --git a/drivers/mtd/parsers/bcm47xxpart.c b/drivers/mtd/parsers/bcm47xxpart.c
+index 50fcf4c2174ba..13daf9bffd081 100644
+--- a/drivers/mtd/parsers/bcm47xxpart.c
++++ b/drivers/mtd/parsers/bcm47xxpart.c
+@@ -233,11 +233,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
+ }
+
+ /* Read middle of the block */
+- err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
++ err = mtd_read(master, offset + (blocksize / 2), 0x4, &bytes_read,
+ (uint8_t *)buf);
+ if (err && !mtd_is_bitflip(err)) {
+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
+- offset + 0x8000, err);
++ offset + (blocksize / 2), err);
+ continue;
+ }
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index f2c64006f8d75..bee8fc4c9f078 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2724,7 +2724,9 @@ static int spi_nor_init(struct spi_nor *nor)
+ */
+ WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
+ "enabling reset hack; may not recover from unexpected reboots\n");
+- return nor->params->set_4byte_addr_mode(nor, true);
++ err = nor->params->set_4byte_addr_mode(nor, true);
++ if (err && err != -ENOTSUPP)
++ return err;
+ }
+
+ return 0;
+diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
+index c469b2f3e57d5..b0ed798ae70fe 100644
+--- a/drivers/net/can/mscan/mpc5xxx_can.c
++++ b/drivers/net/can/mscan/mpc5xxx_can.c
+@@ -322,14 +322,14 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
+ &mscan_clksrc);
+ if (!priv->can.clock.freq) {
+ dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
+- goto exit_free_mscan;
++ goto exit_put_clock;
+ }
+
+ err = register_mscandev(dev, mscan_clksrc);
+ if (err) {
+ dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+- goto exit_free_mscan;
++ goto exit_put_clock;
+ }
+
+ dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
+@@ -337,7 +337,9 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
+
+ return 0;
+
+-exit_free_mscan:
++exit_put_clock:
++ if (data->put_clock)
++ data->put_clock(ofdev);
+ free_candev(dev);
+ exit_dispose_irq:
+ irq_dispose_mapping(irq);
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 27085b796e752..d77c8d6d191a6 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1157,11 +1157,13 @@ static void rcar_canfd_handle_global_receive(struct rcar_canfd_global *gpriv, u3
+ {
+ struct rcar_canfd_channel *priv = gpriv->ch[ch];
+ u32 ridx = ch + RCANFD_RFFIFO_IDX;
+- u32 sts;
++ u32 sts, cc;
+
+ /* Handle Rx interrupts */
+ sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx));
+- if (likely(sts & RCANFD_RFSTS_RFIF)) {
++ cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx));
++ if (likely(sts & RCANFD_RFSTS_RFIF &&
++ cc & RCANFD_RFCC_RFIE)) {
+ if (napi_schedule_prep(&priv->napi)) {
+ /* Disable Rx FIFO interrupts */
+ rcar_canfd_clear_bit(priv->base,
+@@ -1244,11 +1246,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch
+
+ static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)
+ {
+- struct rcar_canfd_global *gpriv = dev_id;
+- u32 ch;
++ struct rcar_canfd_channel *priv = dev_id;
+
+- for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
+- rcar_canfd_handle_channel_tx(gpriv, ch);
++ rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel);
+
+ return IRQ_HANDLED;
+ }
+@@ -1276,11 +1276,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c
+
+ static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id)
+ {
+- struct rcar_canfd_global *gpriv = dev_id;
+- u32 ch;
++ struct rcar_canfd_channel *priv = dev_id;
+
+- for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
+- rcar_canfd_handle_channel_err(gpriv, ch);
++ rcar_canfd_handle_channel_err(priv->gpriv, priv->channel);
+
+ return IRQ_HANDLED;
+ }
+@@ -1721,6 +1719,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ priv->ndev = ndev;
+ priv->base = gpriv->base;
+ priv->channel = ch;
++ priv->gpriv = gpriv;
+ priv->can.clock.freq = fcan_freq;
+ dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq);
+
+@@ -1749,7 +1748,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ }
+ err = devm_request_irq(&pdev->dev, err_irq,
+ rcar_canfd_channel_err_interrupt, 0,
+- irq_name, gpriv);
++ irq_name, priv);
+ if (err) {
+ dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n",
+ err_irq, err);
+@@ -1763,7 +1762,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ }
+ err = devm_request_irq(&pdev->dev, tx_irq,
+ rcar_canfd_channel_tx_interrupt, 0,
+- irq_name, gpriv);
++ irq_name, priv);
+ if (err) {
+ dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n",
+ tx_irq, err);
+@@ -1789,7 +1788,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+
+ priv->can.do_set_mode = rcar_canfd_do_set_mode;
+ priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter;
+- priv->gpriv = gpriv;
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll,
+diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
+index c320de474f406..24883a65ca66a 100644
+--- a/drivers/net/can/spi/mcp251x.c
++++ b/drivers/net/can/spi/mcp251x.c
+@@ -1415,11 +1415,14 @@ static int mcp251x_can_probe(struct spi_device *spi)
+
+ ret = mcp251x_gpio_setup(priv);
+ if (ret)
+- goto error_probe;
++ goto out_unregister_candev;
+
+ netdev_info(net, "MCP%x successfully initialized.\n", priv->model);
+ return 0;
+
++out_unregister_candev:
++ unregister_candev(net);
++
+ error_probe:
+ destroy_workqueue(priv->wq);
+ priv->wq = NULL;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 3dcd35979e6fd..3abfaa77e8935 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -1875,7 +1875,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
+ {
+ int err;
+
+- init_completion(&priv->start_comp);
++ reinit_completion(&priv->start_comp);
+
+ err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ,
+ priv->channel);
+@@ -1893,7 +1893,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
+ int err;
+
+- init_completion(&priv->stop_comp);
++ reinit_completion(&priv->stop_comp);
+
+ /* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT
+ * see comment in kvaser_usb_hydra_update_state()
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 50f2ac8319ff8..19958037720f4 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -1320,7 +1320,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
+ {
+ int err;
+
+- init_completion(&priv->start_comp);
++ reinit_completion(&priv->start_comp);
+
+ err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP,
+ priv->channel);
+@@ -1338,7 +1338,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
+ int err;
+
+- init_completion(&priv->stop_comp);
++ reinit_completion(&priv->stop_comp);
+
+ err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
+ priv->channel);
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+index 2af3da4b2d053..f409d7bd1f1ee 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+@@ -285,6 +285,9 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+
+ /* Yellow Carp devices do not need cdr workaround */
+ pdata->vdata->an_cdr_workaround = 0;
++
++ /* Yellow Carp devices do not need rrc */
++ pdata->vdata->enable_rrc = 0;
+ } else {
+ pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
+ pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
+@@ -483,6 +486,7 @@ static struct xgbe_version_data xgbe_v2a = {
+ .tx_desc_prefetch = 5,
+ .rx_desc_prefetch = 5,
+ .an_cdr_workaround = 1,
++ .enable_rrc = 1,
+ };
+
+ static struct xgbe_version_data xgbe_v2b = {
+@@ -498,6 +502,7 @@ static struct xgbe_version_data xgbe_v2b = {
+ .tx_desc_prefetch = 5,
+ .rx_desc_prefetch = 5,
+ .an_cdr_workaround = 1,
++ .enable_rrc = 1,
+ };
+
+ static const struct pci_device_id xgbe_pci_table[] = {
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 2156600641b6c..601a9f2fa9bfc 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -239,6 +239,7 @@ enum xgbe_sfp_speed {
+ #define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d
+ #define XGBE_SFP_BASE_BR_10GBE_MIN 0x64
+ #define XGBE_SFP_BASE_BR_10GBE_MAX 0x68
++#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX 0x78
+
+ #define XGBE_SFP_BASE_CU_CABLE_LEN 18
+
+@@ -284,6 +285,8 @@ struct xgbe_sfp_eeprom {
+ #define XGBE_BEL_FUSE_VENDOR "BEL-FUSE "
+ #define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 "
+
++#define XGBE_MOLEX_VENDOR "Molex Inc. "
++
+ struct xgbe_sfp_ascii {
+ union {
+ char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
+@@ -834,7 +837,11 @@ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
+ break;
+ case XGBE_SFP_SPEED_10000:
+ min = XGBE_SFP_BASE_BR_10GBE_MIN;
+- max = XGBE_SFP_BASE_BR_10GBE_MAX;
++ if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
++ XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
++ max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
++ else
++ max = XGBE_SFP_BASE_BR_10GBE_MAX;
+ break;
+ default:
+ return false;
+@@ -1151,7 +1158,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ }
+
+ /* Determine the type of SFP */
+- if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
++ if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
++ xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
++ phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
++ else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+ phy_data->sfp_base = XGBE_SFP_BASE_10000_SR;
+ else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR)
+ phy_data->sfp_base = XGBE_SFP_BASE_10000_LR;
+@@ -1167,9 +1177,6 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ phy_data->sfp_base = XGBE_SFP_BASE_1000_CX;
+ else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T)
+ phy_data->sfp_base = XGBE_SFP_BASE_1000_T;
+- else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) &&
+- xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+- phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+
+ switch (phy_data->sfp_base) {
+ case XGBE_SFP_BASE_1000_T:
+@@ -2640,7 +2647,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
+ }
+
+ /* No link, attempt a receiver reset cycle */
+- if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
++ if (pdata->vdata->enable_rrc && phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
+ phy_data->rrc_count = 0;
+ xgbe_phy_rrc(pdata);
+ }
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index b875c430222e5..49d23abce73d2 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -1013,6 +1013,7 @@ struct xgbe_version_data {
+ unsigned int tx_desc_prefetch;
+ unsigned int rx_desc_prefetch;
+ unsigned int an_cdr_workaround;
++ unsigned int enable_rrc;
+ };
+
+ struct xgbe_prv_data {
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+index 02058fe79f52b..8b53d6688a4bd 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+@@ -1451,26 +1451,57 @@ static void aq_check_txsa_expiration(struct aq_nic_s *nic)
+ egress_sa_threshold_expired);
+ }
+
++#define AQ_LOCKED_MDO_DEF(mdo) \
++static int aq_locked_mdo_##mdo(struct macsec_context *ctx) \
++{ \
++ struct aq_nic_s *nic = netdev_priv(ctx->netdev); \
++ int ret; \
++ mutex_lock(&nic->macsec_mutex); \
++ ret = aq_mdo_##mdo(ctx); \
++ mutex_unlock(&nic->macsec_mutex); \
++ return ret; \
++}
++
++AQ_LOCKED_MDO_DEF(dev_open)
++AQ_LOCKED_MDO_DEF(dev_stop)
++AQ_LOCKED_MDO_DEF(add_secy)
++AQ_LOCKED_MDO_DEF(upd_secy)
++AQ_LOCKED_MDO_DEF(del_secy)
++AQ_LOCKED_MDO_DEF(add_rxsc)
++AQ_LOCKED_MDO_DEF(upd_rxsc)
++AQ_LOCKED_MDO_DEF(del_rxsc)
++AQ_LOCKED_MDO_DEF(add_rxsa)
++AQ_LOCKED_MDO_DEF(upd_rxsa)
++AQ_LOCKED_MDO_DEF(del_rxsa)
++AQ_LOCKED_MDO_DEF(add_txsa)
++AQ_LOCKED_MDO_DEF(upd_txsa)
++AQ_LOCKED_MDO_DEF(del_txsa)
++AQ_LOCKED_MDO_DEF(get_dev_stats)
++AQ_LOCKED_MDO_DEF(get_tx_sc_stats)
++AQ_LOCKED_MDO_DEF(get_tx_sa_stats)
++AQ_LOCKED_MDO_DEF(get_rx_sc_stats)
++AQ_LOCKED_MDO_DEF(get_rx_sa_stats)
++
+ const struct macsec_ops aq_macsec_ops = {
+- .mdo_dev_open = aq_mdo_dev_open,
+- .mdo_dev_stop = aq_mdo_dev_stop,
+- .mdo_add_secy = aq_mdo_add_secy,
+- .mdo_upd_secy = aq_mdo_upd_secy,
+- .mdo_del_secy = aq_mdo_del_secy,
+- .mdo_add_rxsc = aq_mdo_add_rxsc,
+- .mdo_upd_rxsc = aq_mdo_upd_rxsc,
+- .mdo_del_rxsc = aq_mdo_del_rxsc,
+- .mdo_add_rxsa = aq_mdo_add_rxsa,
+- .mdo_upd_rxsa = aq_mdo_upd_rxsa,
+- .mdo_del_rxsa = aq_mdo_del_rxsa,
+- .mdo_add_txsa = aq_mdo_add_txsa,
+- .mdo_upd_txsa = aq_mdo_upd_txsa,
+- .mdo_del_txsa = aq_mdo_del_txsa,
+- .mdo_get_dev_stats = aq_mdo_get_dev_stats,
+- .mdo_get_tx_sc_stats = aq_mdo_get_tx_sc_stats,
+- .mdo_get_tx_sa_stats = aq_mdo_get_tx_sa_stats,
+- .mdo_get_rx_sc_stats = aq_mdo_get_rx_sc_stats,
+- .mdo_get_rx_sa_stats = aq_mdo_get_rx_sa_stats,
++ .mdo_dev_open = aq_locked_mdo_dev_open,
++ .mdo_dev_stop = aq_locked_mdo_dev_stop,
++ .mdo_add_secy = aq_locked_mdo_add_secy,
++ .mdo_upd_secy = aq_locked_mdo_upd_secy,
++ .mdo_del_secy = aq_locked_mdo_del_secy,
++ .mdo_add_rxsc = aq_locked_mdo_add_rxsc,
++ .mdo_upd_rxsc = aq_locked_mdo_upd_rxsc,
++ .mdo_del_rxsc = aq_locked_mdo_del_rxsc,
++ .mdo_add_rxsa = aq_locked_mdo_add_rxsa,
++ .mdo_upd_rxsa = aq_locked_mdo_upd_rxsa,
++ .mdo_del_rxsa = aq_locked_mdo_del_rxsa,
++ .mdo_add_txsa = aq_locked_mdo_add_txsa,
++ .mdo_upd_txsa = aq_locked_mdo_upd_txsa,
++ .mdo_del_txsa = aq_locked_mdo_del_txsa,
++ .mdo_get_dev_stats = aq_locked_mdo_get_dev_stats,
++ .mdo_get_tx_sc_stats = aq_locked_mdo_get_tx_sc_stats,
++ .mdo_get_tx_sa_stats = aq_locked_mdo_get_tx_sa_stats,
++ .mdo_get_rx_sc_stats = aq_locked_mdo_get_rx_sc_stats,
++ .mdo_get_rx_sa_stats = aq_locked_mdo_get_rx_sa_stats,
+ };
+
+ int aq_macsec_init(struct aq_nic_s *nic)
+@@ -1492,6 +1523,7 @@ int aq_macsec_init(struct aq_nic_s *nic)
+
+ nic->ndev->features |= NETIF_F_HW_MACSEC;
+ nic->ndev->macsec_ops = &aq_macsec_ops;
++ mutex_init(&nic->macsec_mutex);
+
+ return 0;
+ }
+@@ -1515,7 +1547,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
+ if (!nic->macsec_cfg)
+ return 0;
+
+- rtnl_lock();
++ mutex_lock(&nic->macsec_mutex);
+
+ if (nic->aq_fw_ops->send_macsec_req) {
+ struct macsec_cfg_request cfg = { 0 };
+@@ -1564,7 +1596,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
+ ret = aq_apply_macsec_cfg(nic);
+
+ unlock:
+- rtnl_unlock();
++ mutex_unlock(&nic->macsec_mutex);
+ return ret;
+ }
+
+@@ -1576,9 +1608,9 @@ void aq_macsec_work(struct aq_nic_s *nic)
+ if (!netif_carrier_ok(nic->ndev))
+ return;
+
+- rtnl_lock();
++ mutex_lock(&nic->macsec_mutex);
+ aq_check_txsa_expiration(nic);
+- rtnl_unlock();
++ mutex_unlock(&nic->macsec_mutex);
+ }
+
+ int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
+@@ -1589,21 +1621,30 @@ int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
+ if (!cfg)
+ return 0;
+
++ mutex_lock(&nic->macsec_mutex);
++
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!test_bit(i, &cfg->rxsc_idx_busy))
+ continue;
+ cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy);
+ }
+
++ mutex_unlock(&nic->macsec_mutex);
+ return cnt;
+ }
+
+ int aq_macsec_tx_sc_cnt(struct aq_nic_s *nic)
+ {
++ int cnt;
++
+ if (!nic->macsec_cfg)
+ return 0;
+
+- return hweight_long(nic->macsec_cfg->txsc_idx_busy);
++ mutex_lock(&nic->macsec_mutex);
++ cnt = hweight_long(nic->macsec_cfg->txsc_idx_busy);
++ mutex_unlock(&nic->macsec_mutex);
++
++ return cnt;
+ }
+
+ int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
+@@ -1614,12 +1655,15 @@ int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
+ if (!cfg)
+ return 0;
+
++ mutex_lock(&nic->macsec_mutex);
++
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!test_bit(i, &cfg->txsc_idx_busy))
+ continue;
+ cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy);
+ }
+
++ mutex_unlock(&nic->macsec_mutex);
+ return cnt;
+ }
+
+@@ -1691,6 +1735,8 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
+ if (!cfg)
+ return data;
+
++ mutex_lock(&nic->macsec_mutex);
++
+ aq_macsec_update_stats(nic);
+
+ common_stats = &cfg->stats;
+@@ -1773,5 +1819,7 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
+
+ data += i;
+
++ mutex_unlock(&nic->macsec_mutex);
++
+ return data;
+ }
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+index 935ba889bd9a8..ad33f8586532b 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+@@ -157,6 +157,8 @@ struct aq_nic_s {
+ struct mutex fwreq_mutex;
+ #if IS_ENABLED(CONFIG_MACSEC)
+ struct aq_macsec_cfg *macsec_cfg;
++ /* mutex to protect data in macsec_cfg */
++ struct mutex macsec_mutex;
+ #endif
+ /* PTP support */
+ struct aq_ptp_s *aq_ptp;
+diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+index c131d81184893..5ec429663f4c2 100644
+--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+@@ -561,8 +561,6 @@ static int bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_device *netde
+
+ if (++ring->write_idx == ring->length - 1)
+ ring->write_idx = 0;
+- enet->netdev->stats.tx_bytes += skb->len;
+- enet->netdev->stats.tx_packets++;
+
+ return NETDEV_TX_OK;
+ }
+@@ -635,6 +633,7 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
+ struct bcm4908_enet_dma_ring_bd *buf_desc;
+ struct bcm4908_enet_dma_ring_slot *slot;
+ struct device *dev = enet->dev;
++ unsigned int bytes = 0;
+ int handled = 0;
+
+ while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) {
+@@ -645,12 +644,17 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
+
+ dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE);
+ dev_kfree_skb(slot->skb);
+- if (++tx_ring->read_idx == tx_ring->length)
+- tx_ring->read_idx = 0;
+
+ handled++;
++ bytes += slot->len;
++
++ if (++tx_ring->read_idx == tx_ring->length)
++ tx_ring->read_idx = 0;
+ }
+
++ enet->netdev->stats.tx_packets += handled;
++ enet->netdev->stats.tx_bytes += bytes;
++
+ if (handled < weight) {
+ napi_complete_done(napi, handled);
+ bcm4908_enet_dma_ring_intrs_on(enet, tx_ring);
+diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
+index 47fc8e6963d59..2f01d4b0a9aa1 100644
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -1991,6 +1991,9 @@ static int bcm_sysport_open(struct net_device *dev)
+ goto out_clk_disable;
+ }
+
++ /* Indicate that the MAC is responsible for PHY PM */
++ phydev->mac_managed_pm = true;
++
+ /* Reset house keeping link status */
+ priv->old_duplex = -1;
+ priv->old_link = -1;
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index a2897549f9c4d..aa1b03f8bfe91 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -805,6 +805,7 @@ static int macb_mii_probe(struct net_device *dev)
+
+ bp->phylink_config.dev = &dev->dev;
+ bp->phylink_config.type = PHYLINK_NETDEV;
++ bp->phylink_config.mac_managed_pm = true;
+
+ if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ bp->phylink_config.poll_fixed_state = true;
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 9f5b921039bd4..d0fd3045ce111 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2090,7 +2090,12 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+ else
+ enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE);
+
++ /* Also prepare the consumer index in case page allocation never
++ * succeeds. In that case, hardware will never advance producer index
++ * to match consumer index, and will drop all frames.
++ */
+ enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
++ enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1);
+
+ /* enable Rx ints by setting pkt thr to 1 */
+ enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1);
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 92c55e1a55076..a486435ceee2c 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -2347,6 +2347,31 @@ static u32 fec_enet_register_offset[] = {
+ IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
+ IEEE_R_FDXFC, IEEE_R_OCTETS_OK
+ };
++/* for i.MX6ul */
++static u32 fec_enet_register_offset_6ul[] = {
++ FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
++ FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
++ FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0,
++ FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH,
++ FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0,
++ FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM,
++ FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC,
++ RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
++ RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
++ RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
++ RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047,
++ RMON_T_P_GTE2048, RMON_T_OCTETS,
++ IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF,
++ IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE,
++ IEEE_T_FDXFC, IEEE_T_OCTETS_OK,
++ RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN,
++ RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB,
++ RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255,
++ RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047,
++ RMON_R_P_GTE2048, RMON_R_OCTETS,
++ IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
++ IEEE_R_FDXFC, IEEE_R_OCTETS_OK
++};
+ #else
+ static __u32 fec_enet_register_version = 1;
+ static u32 fec_enet_register_offset[] = {
+@@ -2371,7 +2396,24 @@ static void fec_enet_get_regs(struct net_device *ndev,
+ u32 *buf = (u32 *)regbuf;
+ u32 i, off;
+ int ret;
++#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
++ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
++ defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST)
++ u32 *reg_list;
++ u32 reg_cnt;
+
++ if (!of_machine_is_compatible("fsl,imx6ul")) {
++ reg_list = fec_enet_register_offset;
++ reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
++ } else {
++ reg_list = fec_enet_register_offset_6ul;
++ reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul);
++ }
++#else
++ /* coldfire */
++ static u32 *reg_list = fec_enet_register_offset;
++ static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
++#endif
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ return;
+@@ -2380,8 +2422,8 @@ static void fec_enet_get_regs(struct net_device *ndev,
+
+ memset(buf, 0, regs->len);
+
+- for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) {
+- off = fec_enet_register_offset[i];
++ for (i = 0; i < reg_cnt; i++) {
++ off = reg_list[i];
+
+ if ((off == FEC_R_BOUND || off == FEC_R_FSTART) &&
+ !(fep->quirks & FEC_QUIRK_HAS_FRREG))
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
+index 19eb839177ec2..061952c6c21a4 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
+@@ -85,6 +85,7 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
+ struct tag_sml_funcfg_tbl *funcfg_table_elem;
+ struct hinic_cmd_lt_rd *read_data;
+ u16 out_size = sizeof(*read_data);
++ int ret = ~0;
+ int err;
+
+ read_data = kzalloc(sizeof(*read_data), GFP_KERNEL);
+@@ -111,20 +112,25 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
+
+ switch (idx) {
+ case VALID:
+- return funcfg_table_elem->dw0.bs.valid;
++ ret = funcfg_table_elem->dw0.bs.valid;
++ break;
+ case RX_MODE:
+- return funcfg_table_elem->dw0.bs.nic_rx_mode;
++ ret = funcfg_table_elem->dw0.bs.nic_rx_mode;
++ break;
+ case MTU:
+- return funcfg_table_elem->dw1.bs.mtu;
++ ret = funcfg_table_elem->dw1.bs.mtu;
++ break;
+ case RQ_DEPTH:
+- return funcfg_table_elem->dw13.bs.cfg_rq_depth;
++ ret = funcfg_table_elem->dw13.bs.cfg_rq_depth;
++ break;
+ case QUEUE_NUM:
+- return funcfg_table_elem->dw13.bs.cfg_q_num;
++ ret = funcfg_table_elem->dw13.bs.cfg_q_num;
++ break;
+ }
+
+ kfree(read_data);
+
+- return ~0;
++ return ret;
+ }
+
+ static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count,
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+index a627237f694bb..afa816cfcdf4a 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+@@ -929,7 +929,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
+
+ err_set_cmdq_depth:
+ hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);
+-
++ free_cmdq(&cmdqs->cmdq[HINIC_CMDQ_SYNC]);
+ err_cmdq_ctxt:
+ hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
+ HINIC_MAX_CMDQ_TYPES);
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+index 2127a48749a8c..1cd812c566724 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+@@ -883,7 +883,7 @@ int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
+ if (err)
+ return -EINVAL;
+
+- interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt;
++ interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt;
+ interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;
+
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+index df555847afb56..61c1da0c52a0b 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+@@ -1175,7 +1175,6 @@ int hinic_vf_func_init(struct hinic_hwdev *hwdev)
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.status, out_size);
+- hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
+ return -EIO;
+ }
+ } else {
+diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+index 5dc302880f5f6..acecf25a60413 100644
+--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+@@ -2900,6 +2900,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
+ ret = of_device_register(&port->ofdev);
+ if (ret) {
+ pr_err("failed to register device. ret=%d\n", ret);
++ put_device(&port->ofdev.dev);
+ goto out;
+ }
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index af5fe84db5961..6f0d4160ff82f 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -3185,10 +3185,17 @@ static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
+
+ if (cmd->flow_type == TCP_V4_FLOW ||
+ cmd->flow_type == UDP_V4_FLOW) {
+- if (i_set & I40E_L3_SRC_MASK)
+- cmd->data |= RXH_IP_SRC;
+- if (i_set & I40E_L3_DST_MASK)
+- cmd->data |= RXH_IP_DST;
++ if (hw->mac.type == I40E_MAC_X722) {
++ if (i_set & I40E_X722_L3_SRC_MASK)
++ cmd->data |= RXH_IP_SRC;
++ if (i_set & I40E_X722_L3_DST_MASK)
++ cmd->data |= RXH_IP_DST;
++ } else {
++ if (i_set & I40E_L3_SRC_MASK)
++ cmd->data |= RXH_IP_SRC;
++ if (i_set & I40E_L3_DST_MASK)
++ cmd->data |= RXH_IP_DST;
++ }
+ } else if (cmd->flow_type == TCP_V6_FLOW ||
+ cmd->flow_type == UDP_V6_FLOW) {
+ if (i_set & I40E_L3_V6_SRC_MASK)
+@@ -3546,12 +3553,15 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+
+ /**
+ * i40e_get_rss_hash_bits - Read RSS Hash bits from register
++ * @hw: hw structure
+ * @nfc: pointer to user request
+ * @i_setc: bits currently set
+ *
+ * Returns value of bits to be set per user request
+ **/
+-static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
++static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
++ struct ethtool_rxnfc *nfc,
++ u64 i_setc)
+ {
+ u64 i_set = i_setc;
+ u64 src_l3 = 0, dst_l3 = 0;
+@@ -3570,8 +3580,13 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
+ dst_l3 = I40E_L3_V6_DST_MASK;
+ } else if (nfc->flow_type == TCP_V4_FLOW ||
+ nfc->flow_type == UDP_V4_FLOW) {
+- src_l3 = I40E_L3_SRC_MASK;
+- dst_l3 = I40E_L3_DST_MASK;
++ if (hw->mac.type == I40E_MAC_X722) {
++ src_l3 = I40E_X722_L3_SRC_MASK;
++ dst_l3 = I40E_X722_L3_DST_MASK;
++ } else {
++ src_l3 = I40E_L3_SRC_MASK;
++ dst_l3 = I40E_L3_DST_MASK;
++ }
+ } else {
+ /* Any other flow type are not supported here */
+ return i_set;
+@@ -3589,6 +3604,7 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
+ return i_set;
+ }
+
++#define FLOW_PCTYPES_SIZE 64
+ /**
+ * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
+ * @pf: pointer to the physical function struct
+@@ -3601,9 +3617,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+ struct i40e_hw *hw = &pf->hw;
+ u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
+ ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
+- u8 flow_pctype = 0;
++ DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
+ u64 i_set, i_setc;
+
++ bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
++
+ if (pf->flags & I40E_FLAG_MFP_ENABLED) {
+ dev_err(&pf->pdev->dev,
+ "Change of RSS hash input set is not supported when MFP mode is enabled\n");
+@@ -3619,36 +3637,35 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+
+ switch (nfc->flow_type) {
+ case TCP_V4_FLOW:
+- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
+ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+- hena |=
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
++ flow_pctypes);
+ break;
+ case TCP_V6_FLOW:
+- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+- hena |=
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
+ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+- hena |=
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
++ flow_pctypes);
+ break;
+ case UDP_V4_FLOW:
+- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+- hena |=
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+-
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
++ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
++ set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
++ flow_pctypes);
++ set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
++ flow_pctypes);
++ }
+ hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
+ break;
+ case UDP_V6_FLOW:
+- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
+- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+- hena |=
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
+- BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+-
++ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
++ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
++ set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
++ flow_pctypes);
++ set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
++ flow_pctypes);
++ }
+ hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
+ break;
+ case AH_ESP_V4_FLOW:
+@@ -3681,17 +3698,20 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+ return -EINVAL;
+ }
+
+- if (flow_pctype) {
+- i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
+- flow_pctype)) |
+- ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
+- flow_pctype)) << 32);
+- i_set = i40e_get_rss_hash_bits(nfc, i_setc);
+- i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
+- (u32)i_set);
+- i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
+- (u32)(i_set >> 32));
+- hena |= BIT_ULL(flow_pctype);
++ if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
++ u8 flow_id;
++
++ for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
++ i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
++ ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
++ i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
++
++ i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
++ (u32)i_set);
++ i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
++ (u32)(i_set >> 32));
++ hena |= BIT_ULL(flow_id);
++ }
+ }
+
+ i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
+index 7b3f30beb757a..388c3d36d96a5 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
+@@ -1404,6 +1404,10 @@ struct i40e_lldp_variables {
+ #define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
+
+ /* INPUT SET MASK for RSS, flow director, and flexible payload */
++#define I40E_X722_L3_SRC_SHIFT 49
++#define I40E_X722_L3_SRC_MASK (0x3ULL << I40E_X722_L3_SRC_SHIFT)
++#define I40E_X722_L3_DST_SHIFT 41
++#define I40E_X722_L3_DST_MASK (0x3ULL << I40E_X722_L3_DST_SHIFT)
+ #define I40E_L3_SRC_SHIFT 47
+ #define I40E_L3_SRC_MASK (0x3ULL << I40E_L3_SRC_SHIFT)
+ #define I40E_L3_V6_SRC_SHIFT 43
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 7e9f6a69eb10c..72ddcefc45b1e 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1536,10 +1536,12 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state))
+ return true;
+
+- /* If the VFs have been disabled, this means something else is
+- * resetting the VF, so we shouldn't continue.
+- */
+- if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
++ /* Bail out if VFs are disabled. */
++ if (test_bit(__I40E_VF_DISABLE, pf->state))
++ return true;
++
++ /* If VF is being reset already we don't need to continue. */
++ if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+ return true;
+
+ i40e_trigger_vf_reset(vf, flr);
+@@ -1576,7 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ i40e_cleanup_reset_vf(vf);
+
+ i40e_flush(hw);
+- clear_bit(__I40E_VF_DISABLE, pf->state);
++ clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
+
+ return true;
+ }
+@@ -1609,8 +1611,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ return false;
+
+ /* Begin reset on all VFs at once */
+- for (v = 0; v < pf->num_alloc_vfs; v++)
+- i40e_trigger_vf_reset(&pf->vf[v], flr);
++ for (v = 0; v < pf->num_alloc_vfs; v++) {
++ vf = &pf->vf[v];
++ /* If VF is being reset no need to trigger reset again */
++ if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++ i40e_trigger_vf_reset(&pf->vf[v], flr);
++ }
+
+ /* HW requires some time to make sure it can flush the FIFO for a VF
+ * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in
+@@ -1626,9 +1632,11 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ */
+ while (v < pf->num_alloc_vfs) {
+ vf = &pf->vf[v];
+- reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
+- if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
+- break;
++ if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
++ reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
++ if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
++ break;
++ }
+
+ /* If the current VF has finished resetting, move on
+ * to the next VF in sequence.
+@@ -1656,6 +1664,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ if (pf->vf[v].lan_vsi_idx == 0)
+ continue;
+
++ /* If VF is reset in another thread just continue */
++ if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++ continue;
++
+ i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
+ }
+
+@@ -1667,6 +1679,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ if (pf->vf[v].lan_vsi_idx == 0)
+ continue;
+
++ /* If VF is reset in another thread just continue */
++ if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++ continue;
++
+ i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
+ }
+
+@@ -1676,8 +1692,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ mdelay(50);
+
+ /* Finish the reset on each VF */
+- for (v = 0; v < pf->num_alloc_vfs; v++)
++ for (v = 0; v < pf->num_alloc_vfs; v++) {
++ /* If VF is reset in another thread just continue */
++ if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++ continue;
++
+ i40e_cleanup_reset_vf(&pf->vf[v]);
++ }
+
+ i40e_flush(hw);
+ clear_bit(__I40E_VF_DISABLE, pf->state);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+index a554d0a0b09bd..358bbdb587951 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+@@ -39,6 +39,7 @@ enum i40e_vf_states {
+ I40E_VF_STATE_MC_PROMISC,
+ I40E_VF_STATE_UC_PROMISC,
+ I40E_VF_STATE_PRE_ENABLE,
++ I40E_VF_STATE_RESETTING
+ };
+
+ /* VF capabilities */
+diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
+index 7cedbe1fdfd77..bd04d9f333495 100644
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -485,7 +485,6 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
+ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+- dev_kfree_skb_any(skb);
+ netdev_err(dev, "tx ring full\n");
+ netif_tx_stop_queue(txq);
+ return NETDEV_TX_BUSY;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 0377392848d92..46ba4c2faad21 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -2004,7 +2004,7 @@ void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,
+ ctx->dev = dev;
+ /* Starts at 1 to avoid doing wake_up if we are not cleaning up */
+ atomic_set(&ctx->num_inflight, 1);
+- init_waitqueue_head(&ctx->wait);
++ init_completion(&ctx->inflight_done);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
+
+@@ -2018,8 +2018,8 @@ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
+ */
+ void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx)
+ {
+- atomic_dec(&ctx->num_inflight);
+- wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0);
++ if (!atomic_dec_and_test(&ctx->num_inflight))
++ wait_for_completion(&ctx->inflight_done);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx);
+
+@@ -2032,7 +2032,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
+ status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
+ work->user_callback(status, work);
+ if (atomic_dec_and_test(&ctx->num_inflight))
+- wake_up(&ctx->wait);
++ complete(&ctx->inflight_done);
+ }
+
+ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+@@ -2050,7 +2050,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+ ret = cmd_exec(ctx->dev, in, in_size, out, out_size,
+ mlx5_cmd_exec_cb_handler, work, false);
+ if (ret && atomic_dec_and_test(&ctx->num_inflight))
+- wake_up(&ctx->wait);
++ complete(&ctx->inflight_done);
+
+ return ret;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+index 92dbbec472ec6..f324a0c6f8695 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+@@ -6,6 +6,7 @@
+
+ #include "en.h"
+ #include "en_stats.h"
++#include "en/txrx.h"
+ #include <linux/ptp_classify.h>
+
+ #define MLX5E_PTP_CHANNEL_IX 0
+@@ -68,6 +69,14 @@ static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
+ fk.ports.dst == htons(PTP_EV_PORT));
+ }
+
++static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq)
++{
++ if (!sq->ptpsq)
++ return true;
++
++ return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo);
++}
++
+ int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
+ u8 lag_port, struct mlx5e_ptp **cp);
+ void mlx5e_ptp_close(struct mlx5e_ptp *c);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
+index 10c9a8a79d005..2e42d7c5451e9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
+@@ -96,6 +96,7 @@ struct mlx5e_tc_flow {
+ struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
+ struct mlx5e_tc_flow *peer_flow;
+ struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
++ struct mlx5e_mod_hdr_handle *slow_mh; /* attached mod header instance for slow path */
+ struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
+ struct list_head hairpin; /* flows sharing the same hairpin */
+ struct list_head peer; /* flows with peer flow */
+@@ -111,6 +112,7 @@ struct mlx5e_tc_flow {
+ struct completion del_hw_done;
+ struct mlx5_flow_attr *attr;
+ struct list_head attrs;
++ u32 chain_mapping;
+ };
+
+ struct mlx5_flow_handle *
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index c208ea307bffb..ff8ca7a7e1036 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -57,6 +57,12 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
+ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
+ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
+
++static inline bool
++mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo)
++{
++ return (*fifo->pc - *fifo->cc) < fifo->mask;
++}
++
+ static inline bool
+ mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 2a8fd70206220..a715601865d31 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -101,7 +101,6 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
+ struct xfrm_replay_state_esn *replay_esn;
+ u32 seq_bottom = 0;
+ u8 overlap;
+- u32 *esn;
+
+ if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) {
+ sa_entry->esn_state.trigger = 0;
+@@ -116,11 +115,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
+
+ sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
+ htonl(seq_bottom));
+- esn = &sa_entry->esn_state.esn;
+
+ sa_entry->esn_state.trigger = 1;
+ if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
+- ++(*esn);
+ sa_entry->esn_state.overlap = 0;
+ return true;
+ } else if (unlikely(!overlap &&
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index f154bda668adf..a687f047e3aeb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1394,8 +1394,13 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
+ struct mlx5e_tc_flow *flow,
+ struct mlx5_flow_spec *spec)
+ {
++ struct mlx5e_tc_mod_hdr_acts mod_acts = {};
++ struct mlx5e_mod_hdr_handle *mh = NULL;
+ struct mlx5_flow_attr *slow_attr;
+ struct mlx5_flow_handle *rule;
++ bool fwd_and_modify_cap;
++ u32 chain_mapping = 0;
++ int err;
+
+ slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB);
+ if (!slow_attr)
+@@ -1406,13 +1411,56 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
+ slow_attr->esw_attr->split_count = 0;
+ slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
+
++ fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table);
++ if (!fwd_and_modify_cap)
++ goto skip_restore;
++
++ err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping);
++ if (err)
++ goto err_get_chain;
++
++ err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB,
++ CHAIN_TO_REG, chain_mapping);
++ if (err)
++ goto err_reg_set;
++
++ mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow),
++ MLX5_FLOW_NAMESPACE_FDB, &mod_acts);
++ if (IS_ERR(mh)) {
++ err = PTR_ERR(mh);
++ goto err_attach;
++ }
++
++ slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
++ slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh);
++
++skip_restore:
+ rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr);
+- if (!IS_ERR(rule))
+- flow_flag_set(flow, SLOW);
++ if (IS_ERR(rule)) {
++ err = PTR_ERR(rule);
++ goto err_offload;
++ }
+
++ flow->slow_mh = mh;
++ flow->chain_mapping = chain_mapping;
++ flow_flag_set(flow, SLOW);
++
++ mlx5e_mod_hdr_dealloc(&mod_acts);
+ kfree(slow_attr);
+
+ return rule;
++
++err_offload:
++ if (fwd_and_modify_cap)
++ mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh);
++err_attach:
++err_reg_set:
++ if (fwd_and_modify_cap)
++ mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping);
++err_get_chain:
++ mlx5e_mod_hdr_dealloc(&mod_acts);
++ kfree(slow_attr);
++ return ERR_PTR(err);
+ }
+
+ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
+@@ -1430,7 +1478,17 @@ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
+ slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ slow_attr->esw_attr->split_count = 0;
+ slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
++ if (flow->slow_mh) {
++ slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
++ slow_attr->modify_hdr = mlx5e_mod_hdr_get(flow->slow_mh);
++ }
+ mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr);
++ if (flow->slow_mh) {
++ mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), flow->slow_mh);
++ mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping);
++ flow->chain_mapping = 0;
++ flow->slow_mh = NULL;
++ }
+ flow_flag_clear(flow, SLOW);
+ kfree(slow_attr);
+ }
+@@ -3994,6 +4052,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow_parse_attr *parse_attr;
+ struct mlx5_flow_attr *attr = flow->attr;
+ struct mlx5_esw_flow_attr *esw_attr;
++ struct net_device *filter_dev;
+ int err;
+
+ err = flow_action_supported(flow_action, extack);
+@@ -4002,6 +4061,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+
+ esw_attr = attr->esw_attr;
+ parse_attr = attr->parse_attr;
++ filter_dev = parse_attr->filter_dev;
+ parse_state = &parse_attr->parse_state;
+ mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack);
+ parse_state->ct_priv = get_ct_priv(priv);
+@@ -4011,13 +4071,21 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+ return err;
+
+ /* Forward to/from internal port can only have 1 dest */
+- if ((netif_is_ovs_master(parse_attr->filter_dev) || esw_attr->dest_int_port) &&
++ if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) &&
+ esw_attr->out_count > 1) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Rules with internal port can have only one destination");
+ return -EOPNOTSUPP;
+ }
+
++ /* Forward from tunnel/internal port to internal port is not supported */
++ if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) &&
++ esw_attr->dest_int_port) {
++ NL_SET_ERR_MSG_MOD(extack,
++ "Forwarding from tunnel/internal port to internal port is not supported");
++ return -EOPNOTSUPP;
++ }
++
+ err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack);
+ if (err)
+ return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+index 27f791feb5174..4d45150a3f8ef 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+@@ -391,6 +391,11 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
+ if (unlikely(sq->ptpsq)) {
+ mlx5e_skb_cb_hwtstamp_init(skb);
+ mlx5e_skb_fifo_push(&sq->ptpsq->skb_fifo, skb);
++ if (!netif_tx_queue_stopped(sq->txq) &&
++ !mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo)) {
++ netif_tx_stop_queue(sq->txq);
++ sq->stats->stopped++;
++ }
+ skb_get(skb);
+ }
+
+@@ -867,6 +872,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
+
+ if (netif_tx_queue_stopped(sq->txq) &&
+ mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) &&
++ mlx5e_ptpsq_fifo_has_room(sq) &&
+ !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
+ netif_tx_wake_queue(sq->txq);
+ stats->wake++;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index e8896f3683626..07c583996c297 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -358,6 +358,23 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+ err = -ETIMEDOUT;
+ }
+
++ do {
++ err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, ®16);
++ if (err)
++ return err;
++ if (reg16 == dev_id)
++ break;
++ msleep(20);
++ } while (!time_after(jiffies, timeout));
++
++ if (reg16 == dev_id) {
++ mlx5_core_info(dev, "Firmware responds to PCI config cycles again\n");
++ } else {
++ mlx5_core_err(dev, "Firmware is not responsive (0x%04x) after %llu ms\n",
++ reg16, mlx5_tout_ms(dev, PCI_TOGGLE));
++ err = -ETIMEDOUT;
++ }
++
+ restore:
+ list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
+ pci_cfg_access_unlock(sdev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+index 21e14507ff5c0..7cd9dda53774a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+@@ -3,6 +3,7 @@
+
+ #include <linux/mlx5/device.h>
+ #include <linux/mlx5/transobj.h>
++#include "clock.h"
+ #include "aso.h"
+ #include "wq.h"
+
+@@ -179,6 +180,7 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
+ {
+ void *in, *sqc, *wq;
+ int inlen, err;
++ u8 ts_format;
+
+ inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
+ sizeof(u64) * sq->wq_ctrl.buf.npages;
+@@ -195,6 +197,11 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
+ MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
+ MLX5_SET(sqc, sqc, flush_in_error_en, 1);
+
++ ts_format = mlx5_is_real_time_sq(mdev) ?
++ MLX5_TIMESTAMP_FORMAT_REAL_TIME :
++ MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
++ MLX5_SET(sqc, sqc, ts_format, ts_format);
++
+ MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
+ MLX5_SET(wq, wq, uar_page, mdev->mlx5e_res.hw_objs.bfreg.index);
+ MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift -
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
+index 839a01da110f3..8ff16318e32dc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
+@@ -122,7 +122,7 @@ void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_mpfs *mpfs = dev->priv.mpfs;
+
+- if (!MLX5_ESWITCH_MANAGER(dev))
++ if (!mpfs)
+ return;
+
+ WARN_ON(!hlist_empty(mpfs->hash));
+@@ -137,7 +137,7 @@ int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
+ int err = 0;
+ u32 index;
+
+- if (!MLX5_ESWITCH_MANAGER(dev))
++ if (!mpfs)
+ return 0;
+
+ mutex_lock(&mpfs->lock);
+@@ -185,7 +185,7 @@ int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
+ int err = 0;
+ u32 index;
+
+- if (!MLX5_ESWITCH_MANAGER(dev))
++ if (!mpfs)
+ return 0;
+
+ mutex_lock(&mpfs->lock);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 89b2d9cea33f0..e5e32430b6afd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1833,6 +1833,10 @@ static void mlx5_pci_resume(struct pci_dev *pdev)
+
+ err = mlx5_load_one(dev, false);
+
++ if (!err)
++ devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
++ DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
++
+ mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err,
+ !err ? "recovered" : "Failed");
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+index ddfaf78911881..91ff19f676951 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+@@ -1200,7 +1200,8 @@ free_rule:
+ }
+
+ remove_from_nic_tbl:
+- mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
++ if (!nic_matcher->rules)
++ mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
+
+ free_hw_ste:
+ mlx5dr_domain_nic_unlock(nic_dmn);
+diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
+index 2b3eb5ed82338..97839f1b456c6 100644
+--- a/drivers/net/ethernet/micrel/ksz884x.c
++++ b/drivers/net/ethernet/micrel/ksz884x.c
+@@ -6851,7 +6851,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
+ char banner[sizeof(version)];
+ struct ksz_switch *sw = NULL;
+
+- result = pci_enable_device(pdev);
++ result = pcim_enable_device(pdev);
+ if (result)
+ return result;
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+index e58a27fd8b508..fea42542be280 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+@@ -656,7 +656,15 @@ void lan966x_stats_get(struct net_device *dev,
+ stats->rx_dropped = dev->stats.rx_dropped +
+ lan966x->stats[idx + SYS_COUNT_RX_LONG] +
+ lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
+- lan966x->stats[idx + SYS_COUNT_DR_TAIL];
++ lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
++ lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
+
+ for (i = 0; i < LAN966X_NUM_TC; i++) {
+ stats->rx_dropped +=
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+index 51f8a08163777..69f741db25b1f 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+@@ -309,6 +309,7 @@ static void lan966x_fdma_tx_disable(struct lan966x_tx *tx)
+ lan966x, FDMA_CH_DB_DISCARD);
+
+ tx->activated = false;
++ tx->last_in_use = -1;
+ }
+
+ static void lan966x_fdma_tx_reload(struct lan966x_tx *tx)
+@@ -687,17 +688,14 @@ static int lan966x_qsys_sw_status(struct lan966x *lan966x)
+
+ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
+ {
+- void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf;
+- dma_addr_t rx_dma, tx_dma;
++ dma_addr_t rx_dma;
++ void *rx_dcbs;
+ u32 size;
+ int err;
+
+ /* Store these for later to free them */
+ rx_dma = lan966x->rx.dma;
+- tx_dma = lan966x->tx.dma;
+ rx_dcbs = lan966x->rx.dcbs;
+- tx_dcbs = lan966x->tx.dcbs;
+- tx_dcbs_buf = lan966x->tx.dcbs_buf;
+
+ napi_synchronize(&lan966x->napi);
+ napi_disable(&lan966x->napi);
+@@ -715,17 +713,6 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
+ size = ALIGN(size, PAGE_SIZE);
+ dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma);
+
+- lan966x_fdma_tx_disable(&lan966x->tx);
+- err = lan966x_fdma_tx_alloc(&lan966x->tx);
+- if (err)
+- goto restore_tx;
+-
+- size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX;
+- size = ALIGN(size, PAGE_SIZE);
+- dma_free_coherent(lan966x->dev, size, tx_dcbs, tx_dma);
+-
+- kfree(tx_dcbs_buf);
+-
+ lan966x_fdma_wakeup_netdev(lan966x);
+ napi_enable(&lan966x->napi);
+
+@@ -735,11 +722,6 @@ restore:
+ lan966x->rx.dcbs = rx_dcbs;
+ lan966x_fdma_rx_start(&lan966x->rx);
+
+-restore_tx:
+- lan966x->tx.dma = tx_dma;
+- lan966x->tx.dcbs = tx_dcbs;
+- lan966x->tx.dcbs_buf = tx_dcbs_buf;
+-
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
+index b0c5a44785fa4..386c8640381b8 100644
+--- a/drivers/net/ethernet/socionext/netsec.c
++++ b/drivers/net/ethernet/socionext/netsec.c
+@@ -1961,11 +1961,13 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr)
+ ret = PTR_ERR(priv->phydev);
+ dev_err(priv->dev, "get_phy_device err(%d)\n", ret);
+ priv->phydev = NULL;
++ mdiobus_unregister(bus);
+ return -ENODEV;
+ }
+
+ ret = phy_device_register(priv->phydev);
+ if (ret) {
++ phy_device_free(priv->phydev);
+ mdiobus_unregister(bus);
+ dev_err(priv->dev,
+ "phy_device_register err(%d)\n", ret);
+diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
+index f0c8de2c60755..db80a17a7e210 100644
+--- a/drivers/net/ethernet/socionext/sni_ave.c
++++ b/drivers/net/ethernet/socionext/sni_ave.c
+@@ -1229,6 +1229,8 @@ static int ave_init(struct net_device *ndev)
+
+ phy_support_asym_pause(phydev);
+
++ phydev->mac_managed_pm = true;
++
+ phy_attached_info(phydev);
+
+ return 0;
+@@ -1757,6 +1759,10 @@ static int ave_resume(struct device *dev)
+
+ ave_global_reset(ndev);
+
++ ret = phy_init_hw(ndev->phydev);
++ if (ret)
++ return ret;
++
+ ave_ethtool_get_wol(ndev, &wol);
+ wol.wolopts = priv->wolopts;
+ __ave_ethtool_set_wol(ndev, &wol);
+diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
+index b5f4df1a07a3d..0052968e881e7 100644
+--- a/drivers/net/netdevsim/bus.c
++++ b/drivers/net/netdevsim/bus.c
+@@ -117,6 +117,10 @@ static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
+
+ static void nsim_bus_dev_release(struct device *dev)
+ {
++ struct nsim_bus_dev *nsim_bus_dev;
++
++ nsim_bus_dev = container_of(dev, struct nsim_bus_dev, dev);
++ kfree(nsim_bus_dev);
+ }
+
+ static struct device_type nsim_bus_dev_type = {
+@@ -291,6 +295,8 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
+
+ err_nsim_bus_dev_id_free:
+ ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
++ put_device(&nsim_bus_dev->dev);
++ nsim_bus_dev = NULL;
+ err_nsim_bus_dev_free:
+ kfree(nsim_bus_dev);
+ return ERR_PTR(err);
+@@ -300,9 +306,8 @@ static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
+ {
+ /* Disallow using nsim_bus_dev */
+ smp_store_release(&nsim_bus_dev->init, false);
+- device_unregister(&nsim_bus_dev->dev);
+ ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
+- kfree(nsim_bus_dev);
++ device_unregister(&nsim_bus_dev->dev);
+ }
+
+ static struct device_driver nsim_driver = {
+diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
+index e88f783c297eb..b17e4e94a060e 100644
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -309,8 +309,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ if (IS_ERR(nsim_dev->ddir))
+ return PTR_ERR(nsim_dev->ddir);
+ nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
+- if (IS_ERR(nsim_dev->ports_ddir))
+- return PTR_ERR(nsim_dev->ports_ddir);
++ if (IS_ERR(nsim_dev->ports_ddir)) {
++ err = PTR_ERR(nsim_dev->ports_ddir);
++ goto err_ddir;
++ }
+ debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
+ &nsim_dev->fw_update_status);
+ debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
+@@ -346,7 +348,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
+ if (IS_ERR(nsim_dev->nodes_ddir)) {
+ err = PTR_ERR(nsim_dev->nodes_ddir);
+- goto err_out;
++ goto err_ports_ddir;
+ }
+ debugfs_create_bool("fail_trap_drop_counter_get", 0600,
+ nsim_dev->ddir,
+@@ -354,8 +356,9 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ nsim_udp_tunnels_debugfs_create(nsim_dev);
+ return 0;
+
+-err_out:
++err_ports_ddir:
+ debugfs_remove_recursive(nsim_dev->ports_ddir);
++err_ddir:
+ debugfs_remove_recursive(nsim_dev->ddir);
+ return err;
+ }
+@@ -442,7 +445,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv4 top resource\n");
+- goto out;
++ goto err_out;
+ }
+
+ err = devl_resource_register(devlink, "fib", (u64)-1,
+@@ -450,7 +453,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ NSIM_RESOURCE_IPV4, ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv4 FIB resource\n");
+- return err;
++ goto err_out;
+ }
+
+ err = devl_resource_register(devlink, "fib-rules", (u64)-1,
+@@ -458,7 +461,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ NSIM_RESOURCE_IPV4, ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv4 FIB rules resource\n");
+- return err;
++ goto err_out;
+ }
+
+ /* Resources for IPv6 */
+@@ -468,7 +471,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv6 top resource\n");
+- goto out;
++ goto err_out;
+ }
+
+ err = devl_resource_register(devlink, "fib", (u64)-1,
+@@ -476,7 +479,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ NSIM_RESOURCE_IPV6, ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv6 FIB resource\n");
+- return err;
++ goto err_out;
+ }
+
+ err = devl_resource_register(devlink, "fib-rules", (u64)-1,
+@@ -484,7 +487,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ NSIM_RESOURCE_IPV6, ¶ms);
+ if (err) {
+ pr_err("Failed to register IPv6 FIB rules resource\n");
+- return err;
++ goto err_out;
+ }
+
+ /* Resources for nexthops */
+@@ -492,8 +495,14 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ NSIM_RESOURCE_NEXTHOPS,
+ DEVLINK_RESOURCE_ID_PARENT_TOP,
+ ¶ms);
++ if (err) {
++ pr_err("Failed to register NEXTHOPS resource\n");
++ goto err_out;
++ }
++ return 0;
+
+-out:
++err_out:
++ devl_resources_unregister(devlink);
+ return err;
+ }
+
+diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
+index f577449e49350..85c06dbb2c449 100644
+--- a/drivers/nfc/virtual_ncidev.c
++++ b/drivers/nfc/virtual_ncidev.c
+@@ -54,16 +54,19 @@ static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ mutex_lock(&nci_mutex);
+ if (state != virtual_ncidev_enabled) {
+ mutex_unlock(&nci_mutex);
++ kfree_skb(skb);
+ return 0;
+ }
+
+ if (send_buff) {
+ mutex_unlock(&nci_mutex);
++ kfree_skb(skb);
+ return -1;
+ }
+ send_buff = skb_copy(skb, GFP_KERNEL);
+ mutex_unlock(&nci_mutex);
+ wake_up_interruptible(&wq);
++ consume_skb(skb);
+
+ return 0;
+ }
+diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
+index 3a9ee9c8af116..2991fe0bb0f2c 100644
+--- a/drivers/pinctrl/pinctrl-ingenic.c
++++ b/drivers/pinctrl/pinctrl-ingenic.c
+@@ -667,7 +667,7 @@ static u8 jz4755_lcd_24bit_funcs[] = { 1, 1, 1, 1, 0, 0, };
+ static const struct group_desc jz4755_groups[] = {
+ INGENIC_PIN_GROUP("uart0-data", jz4755_uart0_data, 0),
+ INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0),
+- INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0),
++ INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 1),
+ INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1),
+ INGENIC_PIN_GROUP("ssi-dt-b", jz4755_ssi_dt_b, 0),
+ INGENIC_PIN_GROUP("ssi-dt-f", jz4755_ssi_dt_f, 0),
+@@ -721,7 +721,7 @@ static const char *jz4755_ssi_groups[] = {
+ "ssi-ce1-b", "ssi-ce1-f",
+ };
+ static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
+-static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", };
++static const char *jz4755_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
+ static const char *jz4755_i2c_groups[] = { "i2c-data", };
+ static const char *jz4755_cim_groups[] = { "cim-data", };
+ static const char *jz4755_lcd_groups[] = {
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index c7df8c5fe5854..105771ff82e62 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -1863,19 +1863,28 @@ static void ocelot_irq_unmask_level(struct irq_data *data)
+ if (val & bit)
+ ack = true;
+
++ /* Try to clear any rising edges */
++ if (!active && ack)
++ regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio),
++ bit, bit);
++
+ /* Enable the interrupt now */
+ gpiochip_enable_irq(chip, gpio);
+ regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
+ bit, bit);
+
+ /*
+- * In case the interrupt line is still active and the interrupt
+- * controller has not seen any changes in the interrupt line, then it
+- * means that there happen another interrupt while the line was active.
++ * In case the interrupt line is still active then it means that
++ * there happen another interrupt while the line was active.
+ * So we missed that one, so we need to kick the interrupt again
+ * handler.
+ */
+- if (active && !ack) {
++ regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val);
++ if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) ||
++ (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH))
++ active = true;
++
++ if (active) {
+ struct ocelot_irq_work *work;
+
+ work = kmalloc(sizeof(*work), GFP_ATOMIC);
+diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
+index 7d2fbf8a02cd6..c98f35ad89217 100644
+--- a/drivers/pinctrl/pinctrl-zynqmp.c
++++ b/drivers/pinctrl/pinctrl-zynqmp.c
+@@ -412,10 +412,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
+
+ break;
+ case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+- param = PM_PINCTRL_CONFIG_TRI_STATE;
+- arg = PM_PINCTRL_TRI_STATE_ENABLE;
+- ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
+- break;
+ case PIN_CONFIG_MODE_LOW_POWER:
+ /*
+ * These cases are mentioned in dts but configurable
+@@ -424,11 +420,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
+ */
+ ret = 0;
+ break;
+- case PIN_CONFIG_OUTPUT_ENABLE:
+- param = PM_PINCTRL_CONFIG_TRI_STATE;
+- arg = PM_PINCTRL_TRI_STATE_DISABLE;
+- ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
+- break;
+ default:
+ dev_warn(pctldev->dev,
+ "unsupported configuration parameter '%u'\n",
+diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
+index a2abfe987ab12..8bf8b21954fe4 100644
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -51,6 +51,7 @@
+ * detection.
+ * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
+ * @disabled_for_mux: These IRQs were disabled because we muxed away.
++ * @ever_gpio: This bit is set the first time we mux a pin to gpio_func.
+ * @soc: Reference to soc_data of platform specific data.
+ * @regs: Base addresses for the TLMM tiles.
+ * @phys_base: Physical base address
+@@ -72,6 +73,7 @@ struct msm_pinctrl {
+ DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+ DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
+ DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
++ DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
+
+ const struct msm_pinctrl_soc_data *soc;
+ void __iomem *regs[MAX_NR_TILES];
+@@ -218,6 +220,25 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
+
+ val = msm_readl_ctl(pctrl, g);
+
++ /*
++ * If this is the first time muxing to GPIO and the direction is
++ * output, make sure that we're not going to be glitching the pin
++ * by reading the current state of the pin and setting it as the
++ * output.
++ */
++ if (i == gpio_func && (val & BIT(g->oe_bit)) &&
++ !test_and_set_bit(group, pctrl->ever_gpio)) {
++ u32 io_val = msm_readl_io(pctrl, g);
++
++ if (io_val & BIT(g->in_bit)) {
++ if (!(io_val & BIT(g->out_bit)))
++ msm_writel_io(io_val | BIT(g->out_bit), pctrl, g);
++ } else {
++ if (io_val & BIT(g->out_bit))
++ msm_writel_io(io_val & ~BIT(g->out_bit), pctrl, g);
++ }
++ }
++
+ if (egpio_func && i == egpio_func) {
+ if (val & BIT(g->egpio_present))
+ val &= ~BIT(g->egpio_enable);
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index fc326fdf483fb..6ccb9b38483ca 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -151,9 +151,7 @@ struct amd_pmc_dev {
+ struct device *dev;
+ struct pci_dev *rdev;
+ struct mutex lock; /* generic mutex lock */
+-#if IS_ENABLED(CONFIG_DEBUG_FS)
+ struct dentry *dbgfs_dir;
+-#endif /* CONFIG_DEBUG_FS */
+ };
+
+ static bool enable_stb;
+@@ -369,7 +367,6 @@ static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
+ }
+ #endif
+
+-#ifdef CONFIG_DEBUG_FS
+ static int smu_fw_info_show(struct seq_file *s, void *unused)
+ {
+ struct amd_pmc_dev *dev = s->private;
+@@ -504,15 +501,6 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+ &amd_pmc_stb_debugfs_fops);
+ }
+ }
+-#else
+-static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+-{
+-}
+-
+-static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
+-{
+-}
+-#endif /* CONFIG_DEBUG_FS */
+
+ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
+ {
+diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
+index 913b6ddd040b8..c7db953985002 100644
+--- a/drivers/s390/cio/css.c
++++ b/drivers/s390/cio/css.c
+@@ -753,13 +753,9 @@ static int __unset_online(struct device *dev, void *data)
+ {
+ struct idset *set = data;
+ struct subchannel *sch = to_subchannel(dev);
+- struct ccw_device *cdev;
+
+- if (sch->st == SUBCHANNEL_TYPE_IO) {
+- cdev = sch_get_cdev(sch);
+- if (cdev && cdev->online)
+- idset_sch_del(set, sch->schid);
+- }
++ if (sch->st == SUBCHANNEL_TYPE_IO && sch->config.ena)
++ idset_sch_del(set, sch->schid);
+
+ return 0;
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index fa1fcbfb946f9..6188f6e214648 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -3330,11 +3330,34 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
+ .bsg_timeout = qla24xx_bsg_timeout,
+ };
+
++static uint
++qla2x00_get_host_supported_speeds(scsi_qla_host_t *vha, uint speeds)
++{
++ uint supported_speeds = FC_PORTSPEED_UNKNOWN;
++
++ if (speeds & FDMI_PORT_SPEED_64GB)
++ supported_speeds |= FC_PORTSPEED_64GBIT;
++ if (speeds & FDMI_PORT_SPEED_32GB)
++ supported_speeds |= FC_PORTSPEED_32GBIT;
++ if (speeds & FDMI_PORT_SPEED_16GB)
++ supported_speeds |= FC_PORTSPEED_16GBIT;
++ if (speeds & FDMI_PORT_SPEED_8GB)
++ supported_speeds |= FC_PORTSPEED_8GBIT;
++ if (speeds & FDMI_PORT_SPEED_4GB)
++ supported_speeds |= FC_PORTSPEED_4GBIT;
++ if (speeds & FDMI_PORT_SPEED_2GB)
++ supported_speeds |= FC_PORTSPEED_2GBIT;
++ if (speeds & FDMI_PORT_SPEED_1GB)
++ supported_speeds |= FC_PORTSPEED_1GBIT;
++
++ return supported_speeds;
++}
++
+ void
+ qla2x00_init_host_attr(scsi_qla_host_t *vha)
+ {
+ struct qla_hw_data *ha = vha->hw;
+- u32 speeds = FC_PORTSPEED_UNKNOWN;
++ u32 speeds = 0, fdmi_speed = 0;
+
+ fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count;
+ fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
+@@ -3344,7 +3367,8 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
+ fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
+ fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
+
+- speeds = qla25xx_fdmi_port_speed_capability(ha);
++ fdmi_speed = qla25xx_fdmi_port_speed_capability(ha);
++ speeds = qla2x00_get_host_supported_speeds(vha, fdmi_speed);
+
+ fc_host_supported_speeds(vha->host) = speeds;
+ }
+diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
+index 3e891bf22470e..5a995b5653f1b 100644
+--- a/drivers/spi/spi-aspeed-smc.c
++++ b/drivers/spi/spi-aspeed-smc.c
+@@ -398,7 +398,7 @@ static void aspeed_spi_get_windows(struct aspeed_spi *aspi,
+ windows[cs].cs = cs;
+ windows[cs].size = data->segment_end(aspi, reg_val) -
+ data->segment_start(aspi, reg_val);
+- windows[cs].offset = cs ? windows[cs - 1].offset + windows[cs - 1].size : 0;
++ windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy;
+ dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs,
+ windows[cs].offset, windows[cs].size);
+ }
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 7d89510dc3f00..678dc51ef0174 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1057,6 +1057,8 @@ static int spi_qup_probe(struct platform_device *pdev)
+ else
+ master->num_chipselect = num_cs;
+
++ master->use_gpio_descriptors = true;
++ master->max_native_cs = SPI_NUM_CHIPSELECTS;
+ master->bus_num = pdev->id;
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
+index 0e7c38b2bfe32..67915d76a87f2 100644
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
+@@ -950,8 +950,8 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
+ params->fpn_config.data = NULL;
+ }
+ if (!params->fpn_config.data) {
+- params->fpn_config.data = kvmalloc(height * width *
+- sizeof(short), GFP_KERNEL);
++ params->fpn_config.data = kvmalloc(array3_size(height, width, sizeof(short)),
++ GFP_KERNEL);
+ if (!params->fpn_config.data) {
+ IA_CSS_ERROR("out of memory");
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig
+index 21c13f9b6e333..621944f9907a6 100644
+--- a/drivers/staging/media/sunxi/cedrus/Kconfig
++++ b/drivers/staging/media/sunxi/cedrus/Kconfig
+@@ -2,6 +2,7 @@
+ config VIDEO_SUNXI_CEDRUS
+ tristate "Allwinner Cedrus VPU driver"
+ depends on VIDEO_DEV
++ depends on RESET_CONTROLLER
+ depends on HAS_DMA
+ depends on OF
+ select MEDIA_CONTROLLER
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 999b7c9697fcd..0722d21313055 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -388,6 +388,15 @@ static const struct usb_device_id usb_quirk_list[] = {
+ /* Kingston DataTraveler 3.0 */
+ { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM },
+
++ /* NVIDIA Jetson devices in Force Recovery mode */
++ { USB_DEVICE(0x0955, 0x7018), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7019), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7418), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7721), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7c18), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7e19), .driver_info = USB_QUIRK_RESET_RESUME },
++ { USB_DEVICE(0x0955, 0x7f21), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
+ { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 68d986361c495..d03e1a9c144c1 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/of.h>
++#include <linux/of_graph.h>
+ #include <linux/acpi.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+@@ -85,7 +86,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
+ * mode. If the controller supports DRD but the dr_mode is not
+ * specified or set to OTG, then set the mode to peripheral.
+ */
+- if (mode == USB_DR_MODE_OTG &&
++ if (mode == USB_DR_MODE_OTG && !dwc->edev &&
+ (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
+ !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
+ !DWC3_VER_IS_PRIOR(DWC3, 330A))
+@@ -1690,6 +1691,46 @@ static void dwc3_check_params(struct dwc3 *dwc)
+ }
+ }
+
++static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
++{
++ struct device *dev = dwc->dev;
++ struct device_node *np_phy;
++ struct extcon_dev *edev = NULL;
++ const char *name;
++
++ if (device_property_read_bool(dev, "extcon"))
++ return extcon_get_edev_by_phandle(dev, 0);
++
++ /*
++ * Device tree platforms should get extcon via phandle.
++ * On ACPI platforms, we get the name from a device property.
++ * This device property is for kernel internal use only and
++ * is expected to be set by the glue code.
++ */
++ if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
++ return extcon_get_extcon_dev(name);
++
++ /*
++ * Try to get an extcon device from the USB PHY controller's "port"
++ * node. Check if it has the "port" node first, to avoid printing the
++ * error message from underlying code, as it's a valid case: extcon
++ * device (and "port" node) may be missing in case of "usb-role-switch"
++ * or OTG mode.
++ */
++ np_phy = of_parse_phandle(dev->of_node, "phys", 0);
++ if (of_graph_is_present(np_phy)) {
++ struct device_node *np_conn;
++
++ np_conn = of_graph_get_remote_node(np_phy, -1, -1);
++ if (np_conn)
++ edev = extcon_find_edev_by_node(np_conn);
++ of_node_put(np_conn);
++ }
++ of_node_put(np_phy);
++
++ return edev;
++}
++
+ static int dwc3_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1840,6 +1881,12 @@ static int dwc3_probe(struct platform_device *pdev)
+ goto err2;
+ }
+
++ dwc->edev = dwc3_get_extcon(dwc);
++ if (IS_ERR(dwc->edev)) {
++ ret = dev_err_probe(dwc->dev, PTR_ERR(dwc->edev), "failed to get extcon\n");
++ goto err3;
++ }
++
+ ret = dwc3_get_dr_mode(dwc);
+ if (ret)
+ goto err3;
+diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
+index 8cad9e7d33687..039bf241769af 100644
+--- a/drivers/usb/dwc3/drd.c
++++ b/drivers/usb/dwc3/drd.c
+@@ -8,7 +8,6 @@
+ */
+
+ #include <linux/extcon.h>
+-#include <linux/of_graph.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/property.h>
+@@ -439,51 +438,6 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
+ return NOTIFY_DONE;
+ }
+
+-static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+-{
+- struct device *dev = dwc->dev;
+- struct device_node *np_phy;
+- struct extcon_dev *edev = NULL;
+- const char *name;
+-
+- if (device_property_read_bool(dev, "extcon"))
+- return extcon_get_edev_by_phandle(dev, 0);
+-
+- /*
+- * Device tree platforms should get extcon via phandle.
+- * On ACPI platforms, we get the name from a device property.
+- * This device property is for kernel internal use only and
+- * is expected to be set by the glue code.
+- */
+- if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
+- edev = extcon_get_extcon_dev(name);
+- if (!edev)
+- return ERR_PTR(-EPROBE_DEFER);
+-
+- return edev;
+- }
+-
+- /*
+- * Try to get an extcon device from the USB PHY controller's "port"
+- * node. Check if it has the "port" node first, to avoid printing the
+- * error message from underlying code, as it's a valid case: extcon
+- * device (and "port" node) may be missing in case of "usb-role-switch"
+- * or OTG mode.
+- */
+- np_phy = of_parse_phandle(dev->of_node, "phys", 0);
+- if (of_graph_is_present(np_phy)) {
+- struct device_node *np_conn;
+-
+- np_conn = of_graph_get_remote_node(np_phy, -1, -1);
+- if (np_conn)
+- edev = extcon_find_edev_by_node(np_conn);
+- of_node_put(np_conn);
+- }
+- of_node_put(np_phy);
+-
+- return edev;
+-}
+-
+ #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
+ #define ROLE_SWITCH 1
+ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
+@@ -588,10 +542,6 @@ int dwc3_drd_init(struct dwc3 *dwc)
+ device_property_read_bool(dwc->dev, "usb-role-switch"))
+ return dwc3_setup_role_switch(dwc);
+
+- dwc->edev = dwc3_get_extcon(dwc);
+- if (IS_ERR(dwc->edev))
+- return PTR_ERR(dwc->edev);
+-
+ if (dwc->edev) {
+ dwc->edev_nb.notifier_call = dwc3_drd_notifier;
+ ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
+diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
+index 6c14a79279f9a..fea5290de83fb 100644
+--- a/drivers/usb/dwc3/dwc3-st.c
++++ b/drivers/usb/dwc3/dwc3-st.c
+@@ -251,7 +251,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
+ /* Manage SoftReset */
+ reset_control_deassert(dwc3_data->rstc_rst);
+
+- child = of_get_child_by_name(node, "usb");
++ child = of_get_compatible_child(node, "snps,dwc3");
+ if (!child) {
+ dev_err(&pdev->dev, "failed to find dwc3 core node\n");
+ ret = -ENODEV;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index eca945feeec3e..0ed9826a4c470 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1277,8 +1277,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
+ }
+
+- /* always enable Interrupt on Missed ISOC */
+- trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
++ if (!no_interrupt && !chain)
++ trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
+ break;
+
+ case USB_ENDPOINT_XFER_BULK:
+@@ -1683,6 +1683,16 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
+ cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
+ memset(¶ms, 0, sizeof(params));
+ ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
++ /*
++ * If the End Transfer command was timed out while the device is
++ * not in SETUP phase, it's possible that an incoming Setup packet
++ * may prevent the command's completion. Let's retry when the
++ * ep0state returns to EP0_SETUP_PHASE.
++ */
++ if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) {
++ dep->flags |= DWC3_EP_DELAY_STOP;
++ return 0;
++ }
+ WARN_ON_ONCE(ret);
+ dep->resource_index = 0;
+
+@@ -2501,6 +2511,9 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+ if (dwc->ep0state != EP0_SETUP_PHASE) {
+ int ret;
+
++ if (dwc->delayed_status)
++ dwc3_ep0_send_delayed_status(dwc);
++
+ reinit_completion(&dwc->ep0_in_setup);
+
+ spin_unlock_irqrestore(&dwc->lock, flags);
+@@ -3215,6 +3228,10 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
+ if (event->status & DEPEVT_STATUS_SHORT && !chain)
+ return 1;
+
++ if ((trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) &&
++ DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
++ return 1;
++
+ if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
+ (trb->ctrl & DWC3_TRB_CTRL_LST))
+ return 1;
+diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
+index ec500ee499eed..0aa3d7e1f3cc3 100644
+--- a/drivers/usb/gadget/function/uvc_queue.c
++++ b/drivers/usb/gadget/function/uvc_queue.c
+@@ -304,6 +304,7 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
+
+ queue->sequence = 0;
+ queue->buf_used = 0;
++ queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
+ } else {
+ ret = vb2_streamoff(&queue->queue, queue->queue.type);
+ if (ret < 0)
+@@ -329,10 +330,11 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
+ void uvcg_complete_buffer(struct uvc_video_queue *queue,
+ struct uvc_buffer *buf)
+ {
+- if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
+- buf->length != buf->bytesused) {
+- buf->state = UVC_BUF_STATE_QUEUED;
++ if (queue->flags & UVC_QUEUE_DROP_INCOMPLETE) {
++ queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
++ buf->state = UVC_BUF_STATE_ERROR;
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
++ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index bb037fcc90e69..dd1c6b2ca7c6f 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -88,6 +88,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
+ struct uvc_buffer *buf)
+ {
+ void *mem = req->buf;
++ struct uvc_request *ureq = req->context;
+ int len = video->req_size;
+ int ret;
+
+@@ -113,13 +114,14 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+ list_del(&buf->queue);
+- uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
++ ureq->last_buf = buf;
+
+ video->payload_size = 0;
+ }
+
+ if (video->payload_size == video->max_payload_size ||
++ video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE ||
+ buf->bytesused == video->queue.buf_used)
+ video->payload_size = 0;
+ }
+@@ -155,10 +157,10 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
+ sg = sg_next(sg);
+
+ for_each_sg(sg, iter, ureq->sgt.nents - 1, i) {
+- if (!len || !buf->sg || !sg_dma_len(buf->sg))
++ if (!len || !buf->sg || !buf->sg->length)
+ break;
+
+- sg_left = sg_dma_len(buf->sg) - buf->offset;
++ sg_left = buf->sg->length - buf->offset;
+ part = min_t(unsigned int, len, sg_left);
+
+ sg_set_page(iter, sg_page(buf->sg), part, buf->offset);
+@@ -180,7 +182,8 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
+ req->length -= len;
+ video->queue.buf_used += req->length - header_len;
+
+- if (buf->bytesused == video->queue.buf_used || !buf->sg) {
++ if (buf->bytesused == video->queue.buf_used || !buf->sg ||
++ video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+ buf->offset = 0;
+@@ -195,6 +198,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
+ struct uvc_buffer *buf)
+ {
+ void *mem = req->buf;
++ struct uvc_request *ureq = req->context;
+ int len = video->req_size;
+ int ret;
+
+@@ -209,12 +213,13 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
+
+ req->length = video->req_size - len;
+
+- if (buf->bytesused == video->queue.buf_used) {
++ if (buf->bytesused == video->queue.buf_used ||
++ video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+ list_del(&buf->queue);
+- uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
++ ureq->last_buf = buf;
+ }
+ }
+
+@@ -255,6 +260,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
+ case 0:
+ break;
+
++ case -EXDEV:
++ uvcg_dbg(&video->uvc->func, "VS request missed xfer.\n");
++ queue->flags |= UVC_QUEUE_DROP_INCOMPLETE;
++ break;
++
+ case -ESHUTDOWN: /* disconnect from host. */
+ uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
+ uvcg_queue_cancel(queue, 1);
+@@ -431,7 +441,8 @@ static void uvcg_video_pump(struct work_struct *work)
+
+ /* Endpoint now owns the request */
+ req = NULL;
+- video->req_int_count++;
++ if (buf->state != UVC_BUF_STATE_DONE)
++ video->req_int_count++;
+ }
+
+ if (!req)
+diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+index b0dfca43fbdce..4f3bc27c1c628 100644
+--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
++++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+@@ -591,6 +591,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
+ d->gadget.max_speed = USB_SPEED_HIGH;
+ d->gadget.speed = USB_SPEED_UNKNOWN;
+ d->gadget.dev.of_node = vhub->pdev->dev.of_node;
++ d->gadget.dev.of_node_reused = true;
+
+ rc = usb_add_gadget_udc(d->port_dev, &d->gadget);
+ if (rc != 0)
+diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c
+index 5ac0ef88334eb..53ffaf4e2e376 100644
+--- a/drivers/usb/gadget/udc/bdc/bdc_udc.c
++++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c
+@@ -151,6 +151,7 @@ static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit)
+ bdc->delayed_status = false;
+ bdc->reinit = reinit;
+ bdc->test_mode = false;
++ usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED);
+ }
+
+ /* TNotify wkaeup timer */
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 9e56aa28efcd4..81ca2bc1f0bef 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -889,15 +889,19 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
+ if (dev->eps[i].stream_info)
+ xhci_free_stream_info(xhci,
+ dev->eps[i].stream_info);
+- /* Endpoints on the TT/root port lists should have been removed
+- * when usb_disable_device() was called for the device.
+- * We can't drop them anyway, because the udev might have gone
+- * away by this point, and we can't tell what speed it was.
++ /*
++ * Endpoints are normally deleted from the bandwidth list when
++ * endpoints are dropped, before device is freed.
++ * If host is dying or being removed then endpoints aren't
++ * dropped cleanly, so delete the endpoint from list here.
++ * Only applicable for hosts with software bandwidth checking.
+ */
+- if (!list_empty(&dev->eps[i].bw_endpoint_list))
+- xhci_warn(xhci, "Slot %u endpoint %u "
+- "not removed from BW list!\n",
+- slot_id, i);
++
++ if (!list_empty(&dev->eps[i].bw_endpoint_list)) {
++ list_del_init(&dev->eps[i].bw_endpoint_list);
++ xhci_dbg(xhci, "Slot %u endpoint %u not removed from BW list!\n",
++ slot_id, i);
++ }
+ }
+ /* If this is a hub, free the TT(s) from the TT list */
+ xhci_free_tt_info(xhci, dev, slot_id);
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index dce6c0ec8d340..0a8d37c5af030 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -58,25 +58,13 @@
+ #define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af
+ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
+ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
+-#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI 0xa71e
+-#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI 0x7ec0
++#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
+
+ #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 0x161a
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 0x161b
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 0x161d
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 0x161e
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 0x15d6
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 0x15d7
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 0x161c
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8 0x161f
+
+ #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042
+ #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
+@@ -257,6 +245,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
+ xhci->quirks |= XHCI_MISSING_CAS;
+
++ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
++ pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)
++ xhci->quirks |= XHCI_RESET_TO_DEFAULT;
++
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+ (pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI ||
+@@ -268,12 +260,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI ||
+- pdev->device == PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI))
++ pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI))
+ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+
+ if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+@@ -306,8 +293,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ }
+
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+- pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
++ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
++ /*
++ * try to tame the ASMedia 1042 controller which reports 0.96
++ * but appears to behave more like 1.0
++ */
++ xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+ xhci->quirks |= XHCI_BROKEN_STREAMS;
++ }
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
+ xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+@@ -336,15 +329,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
+ xhci->quirks |= XHCI_NO_SOFT_RETRY;
+
+- if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+- (pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 ||
+- pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8))
++ /* xHC spec requires PCI devices to support D3hot and D3cold */
++ if (xhci->hci_version >= 0x120)
+ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index a7ef675f00fdd..44078a05a0fed 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -810,9 +810,15 @@ void xhci_shutdown(struct usb_hcd *hcd)
+
+ spin_lock_irq(&xhci->lock);
+ xhci_halt(xhci);
+- /* Workaround for spurious wakeups at shutdown with HSW */
+- if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
++
++ /*
++ * Workaround for spurious wakeps at shutdown with HSW, and for boot
++ * firmware delay in ADL-P PCH if port are left in U3 at shutdown
++ */
++ if (xhci->quirks & XHCI_SPURIOUS_WAKEUP ||
++ xhci->quirks & XHCI_RESET_TO_DEFAULT)
+ xhci_reset(xhci, XHCI_RESET_SHORT_USEC);
++
+ spin_unlock_irq(&xhci->lock);
+
+ xhci_cleanup_msix(xhci);
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 6dfbf73ee840d..a6daf37ff4bf7 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1900,6 +1900,7 @@ struct xhci_hcd {
+ #define XHCI_BROKEN_D3COLD BIT_ULL(41)
+ #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
+ #define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43)
++#define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
+
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 74fb5a4c6f21b..a7987fc764cc6 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -183,16 +183,6 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(ucsi_send_command);
+
+-int ucsi_resume(struct ucsi *ucsi)
+-{
+- u64 command;
+-
+- /* Restore UCSI notification enable mask after system resume */
+- command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+-
+- return ucsi_send_command(ucsi, command, NULL, 0);
+-}
+-EXPORT_SYMBOL_GPL(ucsi_resume);
+ /* -------------------------------------------------------------------------- */
+
+ struct ucsi_work {
+@@ -744,6 +734,7 @@ static void ucsi_partner_change(struct ucsi_connector *con)
+
+ static int ucsi_check_connection(struct ucsi_connector *con)
+ {
++ u8 prev_flags = con->status.flags;
+ u64 command;
+ int ret;
+
+@@ -754,10 +745,13 @@ static int ucsi_check_connection(struct ucsi_connector *con)
+ return ret;
+ }
+
++ if (con->status.flags == prev_flags)
++ return 0;
++
+ if (con->status.flags & UCSI_CONSTAT_CONNECTED) {
+- if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
+- UCSI_CONSTAT_PWR_OPMODE_PD)
+- ucsi_partner_task(con, ucsi_check_altmodes, 30, 0);
++ ucsi_register_partner(con);
++ ucsi_pwr_opmode_change(con);
++ ucsi_partner_change(con);
+ } else {
+ ucsi_partner_change(con);
+ ucsi_port_psy_changed(con);
+@@ -1276,6 +1270,28 @@ err:
+ return ret;
+ }
+
++int ucsi_resume(struct ucsi *ucsi)
++{
++ struct ucsi_connector *con;
++ u64 command;
++ int ret;
++
++ /* Restore UCSI notification enable mask after system resume */
++ command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
++ ret = ucsi_send_command(ucsi, command, NULL, 0);
++ if (ret < 0)
++ return ret;
++
++ for (con = ucsi->connector; con->port; con++) {
++ mutex_lock(&con->lock);
++ ucsi_check_connection(con);
++ mutex_unlock(&con->lock);
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(ucsi_resume);
++
+ static void ucsi_init_work(struct work_struct *work)
+ {
+ struct ucsi *ucsi = container_of(work, struct ucsi, work.work);
+diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
+index 8873c1644a295..ce0c8ef80c043 100644
+--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
+@@ -185,6 +185,15 @@ static int ucsi_acpi_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++static int ucsi_acpi_resume(struct device *dev)
++{
++ struct ucsi_acpi *ua = dev_get_drvdata(dev);
++
++ return ucsi_resume(ua->ucsi);
++}
++
++static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume);
++
+ static const struct acpi_device_id ucsi_acpi_match[] = {
+ { "PNP0CA0", 0 },
+ { },
+@@ -194,6 +203,7 @@ MODULE_DEVICE_TABLE(acpi, ucsi_acpi_match);
+ static struct platform_driver ucsi_acpi_platform_driver = {
+ .driver = {
+ .name = "ucsi_acpi",
++ .pm = pm_ptr(&ucsi_acpi_pm_ops),
+ .acpi_match_table = ACPI_PTR(ucsi_acpi_match),
+ },
+ .probe = ucsi_acpi_probe,
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 9223d3d4089f1..013a382bf5f48 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -351,12 +351,9 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
+ size = pci_resource_len(pdev, bar);
+ ret = aperture_remove_conflicting_devices(base, size, primary, name);
+ if (ret)
+- break;
++ return ret;
+ }
+
+- if (ret)
+- return ret;
+-
+ /*
+ * If a driver asked to unregister a platform device registered by
+ * sysfb, then can be assumed that this is a driver for a display
+diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
+index e65bdc499c236..9343b7a4ac899 100644
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -97,7 +97,6 @@ struct ufx_data {
+ struct kref kref;
+ int fb_count;
+ bool virtualized; /* true when physical usb device not present */
+- struct delayed_work free_framebuffer_work;
+ atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
+ atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
+ u8 *edid; /* null until we read edid from hw or get from sysfs */
+@@ -1117,15 +1116,24 @@ static void ufx_free(struct kref *kref)
+ {
+ struct ufx_data *dev = container_of(kref, struct ufx_data, kref);
+
+- /* this function will wait for all in-flight urbs to complete */
+- if (dev->urbs.count > 0)
+- ufx_free_urb_list(dev);
++ kfree(dev);
++}
+
+- pr_debug("freeing ufx_data %p", dev);
++static void ufx_ops_destory(struct fb_info *info)
++{
++ struct ufx_data *dev = info->par;
++ int node = info->node;
+
+- kfree(dev);
++ /* Assume info structure is freed after this point */
++ framebuffer_release(info);
++
++ pr_debug("fb_info for /dev/fb%d has been freed", node);
++
++ /* release reference taken by kref_init in probe() */
++ kref_put(&dev->kref, ufx_free);
+ }
+
++
+ static void ufx_release_urb_work(struct work_struct *work)
+ {
+ struct urb_node *unode = container_of(work, struct urb_node,
+@@ -1134,14 +1142,9 @@ static void ufx_release_urb_work(struct work_struct *work)
+ up(&unode->dev->urbs.limit_sem);
+ }
+
+-static void ufx_free_framebuffer_work(struct work_struct *work)
++static void ufx_free_framebuffer(struct ufx_data *dev)
+ {
+- struct ufx_data *dev = container_of(work, struct ufx_data,
+- free_framebuffer_work.work);
+ struct fb_info *info = dev->info;
+- int node = info->node;
+-
+- unregister_framebuffer(info);
+
+ if (info->cmap.len != 0)
+ fb_dealloc_cmap(&info->cmap);
+@@ -1153,11 +1156,6 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
+
+ dev->info = NULL;
+
+- /* Assume info structure is freed after this point */
+- framebuffer_release(info);
+-
+- pr_debug("fb_info for /dev/fb%d has been freed", node);
+-
+ /* ref taken in probe() as part of registering framebfufer */
+ kref_put(&dev->kref, ufx_free);
+ }
+@@ -1169,11 +1167,13 @@ static int ufx_ops_release(struct fb_info *info, int user)
+ {
+ struct ufx_data *dev = info->par;
+
++ mutex_lock(&disconnect_mutex);
++
+ dev->fb_count--;
+
+ /* We can't free fb_info here - fbmem will touch it when we return */
+ if (dev->virtualized && (dev->fb_count == 0))
+- schedule_delayed_work(&dev->free_framebuffer_work, HZ);
++ ufx_free_framebuffer(dev);
+
+ if ((dev->fb_count == 0) && (info->fbdefio)) {
+ fb_deferred_io_cleanup(info);
+@@ -1186,6 +1186,8 @@ static int ufx_ops_release(struct fb_info *info, int user)
+
+ kref_put(&dev->kref, ufx_free);
+
++ mutex_unlock(&disconnect_mutex);
++
+ return 0;
+ }
+
+@@ -1292,6 +1294,7 @@ static const struct fb_ops ufx_ops = {
+ .fb_blank = ufx_ops_blank,
+ .fb_check_var = ufx_ops_check_var,
+ .fb_set_par = ufx_ops_set_par,
++ .fb_destroy = ufx_ops_destory,
+ };
+
+ /* Assumes &info->lock held by caller
+@@ -1673,9 +1676,6 @@ static int ufx_usb_probe(struct usb_interface *interface,
+ goto destroy_modedb;
+ }
+
+- INIT_DELAYED_WORK(&dev->free_framebuffer_work,
+- ufx_free_framebuffer_work);
+-
+ retval = ufx_reg_read(dev, 0x3000, &id_rev);
+ check_warn_goto_error(retval, "error %d reading 0x3000 register from device", retval);
+ dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev);
+@@ -1748,10 +1748,12 @@ e_nomem:
+ static void ufx_usb_disconnect(struct usb_interface *interface)
+ {
+ struct ufx_data *dev;
++ struct fb_info *info;
+
+ mutex_lock(&disconnect_mutex);
+
+ dev = usb_get_intfdata(interface);
++ info = dev->info;
+
+ pr_debug("USB disconnect starting\n");
+
+@@ -1765,12 +1767,15 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+
+ /* if clients still have us open, will be freed on last close */
+ if (dev->fb_count == 0)
+- schedule_delayed_work(&dev->free_framebuffer_work, 0);
++ ufx_free_framebuffer(dev);
+
+- /* release reference taken by kref_init in probe() */
+- kref_put(&dev->kref, ufx_free);
++ /* this function will wait for all in-flight urbs to complete */
++ if (dev->urbs.count > 0)
++ ufx_free_urb_list(dev);
+
+- /* consider ufx_data freed */
++ pr_debug("freeing ufx_data %p", dev);
++
++ unregister_framebuffer(info);
+
+ mutex_unlock(&disconnect_mutex);
+ }
+diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
+index 7753e586e65a0..3feb6e40d56d8 100644
+--- a/drivers/video/fbdev/stifb.c
++++ b/drivers/video/fbdev/stifb.c
+@@ -1055,7 +1055,8 @@ stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+ {
+ struct stifb_info *fb = container_of(info, struct stifb_info, info);
+
+- if (rect->rop != ROP_COPY)
++ if (rect->rop != ROP_COPY ||
++ (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32))
+ return cfb_fillrect(info, rect);
+
+ SETUP_HW(fb);
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+index 63c7ebb0da898..6a11025e58502 100644
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -911,7 +911,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
+ interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
+ if (!interp_elf_ex) {
+ retval = -ENOMEM;
+- goto out_free_ph;
++ goto out_free_file;
+ }
+
+ /* Get the exec headers */
+@@ -1354,6 +1354,7 @@ out:
+ out_free_dentry:
+ kfree(interp_elf_ex);
+ kfree(interp_elf_phdata);
++out_free_file:
+ allow_write_access(interpreter);
+ if (interpreter)
+ fput(interpreter);
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index 6e663275aeb13..c7511b4317763 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -765,13 +765,13 @@ retry:
+ if (fe->pcl->pageofs_out != (map->m_la & ~PAGE_MASK))
+ fe->pcl->multibases = true;
+
+- if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
+- fe->pcl->length == map->m_llen)
+- fe->pcl->partial = false;
+ if (fe->pcl->length < offset + end - map->m_la) {
+ fe->pcl->length = offset + end - map->m_la;
+ fe->pcl->pageofs_out = map->m_la & ~PAGE_MASK;
+ }
++ if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
++ fe->pcl->length == map->m_llen)
++ fe->pcl->partial = false;
+ next_part:
+ /* shorten the remaining extent to update progress */
+ map->m_llen = offset + cur - map->m_la;
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index d58549ca1df9b..63fd2f1460265 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -61,8 +61,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+
+ pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
+ vi->xattr_isize, 8);
+- kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos),
+- EROFS_KMAP_ATOMIC);
++ kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
+ if (IS_ERR(kaddr)) {
+ err = PTR_ERR(kaddr);
+ goto out_unlock;
+@@ -79,7 +78,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
+ headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
+ err = -EOPNOTSUPP;
+- goto unmap_done;
++ goto out_put_metabuf;
+ }
+
+ vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
+@@ -89,7 +88,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
+ vi->nid);
+ err = -EFSCORRUPTED;
+- goto unmap_done;
++ goto out_put_metabuf;
+ }
+ if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
+ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
+@@ -97,12 +96,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
+ vi->nid);
+ err = -EFSCORRUPTED;
+- goto unmap_done;
++ goto out_put_metabuf;
+ }
+-unmap_done:
+- erofs_put_metabuf(&buf);
+- if (err)
+- goto out_unlock;
+
+ if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
+ struct erofs_map_blocks map = {
+@@ -121,11 +116,13 @@ unmap_done:
+ err = -EFSCORRUPTED;
+ }
+ if (err < 0)
+- goto out_unlock;
++ goto out_put_metabuf;
+ }
+ /* paired with smp_mb() at the beginning of the function */
+ smp_mb();
+ set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
++out_put_metabuf:
++ erofs_put_metabuf(&buf);
+ out_unlock:
+ clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
+ return err;
+diff --git a/fs/exec.c b/fs/exec.c
+index d046dbb9cbd08..6f3d6fce178f2 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1196,11 +1196,11 @@ static int unshare_sighand(struct task_struct *me)
+ return -ENOMEM;
+
+ refcount_set(&newsighand->count, 1);
+- memcpy(newsighand->action, oldsighand->action,
+- sizeof(newsighand->action));
+
+ write_lock_irq(&tasklist_lock);
+ spin_lock(&oldsighand->siglock);
++ memcpy(newsighand->action, oldsighand->action,
++ sizeof(newsighand->action));
+ rcu_assign_pointer(me->sighand, newsighand);
+ spin_unlock(&oldsighand->siglock);
+ write_unlock_irq(&tasklist_lock);
+diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
+index 1cc88ba6de907..2e9313988871b 100644
+--- a/fs/kernfs/dir.c
++++ b/fs/kernfs/dir.c
+@@ -1585,8 +1585,11 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
+ down_write(&root->kernfs_rwsem);
+
+ kn = kernfs_find_ns(parent, name, ns);
+- if (kn)
++ if (kn) {
++ kernfs_get(kn);
+ __kernfs_remove(kn);
++ kernfs_put(kn);
++ }
+
+ up_write(&root->kernfs_rwsem);
+
+diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
+index e56510964b229..8ba8c4c507707 100644
+--- a/fs/squashfs/file.c
++++ b/fs/squashfs/file.c
+@@ -506,8 +506,9 @@ static int squashfs_readahead_fragment(struct page **page,
+ squashfs_i(inode)->fragment_size);
+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
+ unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
++ int error = buffer->error;
+
+- if (buffer->error)
++ if (error)
+ goto out;
+
+ expected += squashfs_i(inode)->fragment_offset;
+@@ -529,7 +530,7 @@ static int squashfs_readahead_fragment(struct page **page,
+
+ out:
+ squashfs_cache_put(buffer);
+- return buffer->error;
++ return error;
+ }
+
+ static void squashfs_readahead(struct readahead_control *ractl)
+@@ -557,6 +558,13 @@ static void squashfs_readahead(struct readahead_control *ractl)
+ int res, bsize;
+ u64 block = 0;
+ unsigned int expected;
++ struct page *last_page;
++
++ expected = start >> msblk->block_log == file_end ?
++ (i_size_read(inode) & (msblk->block_size - 1)) :
++ msblk->block_size;
++
++ max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ nr_pages = __readahead_batch(ractl, pages, max_pages);
+ if (!nr_pages)
+@@ -566,13 +574,10 @@ static void squashfs_readahead(struct readahead_control *ractl)
+ goto skip_pages;
+
+ index = pages[0]->index >> shift;
++
+ if ((pages[nr_pages - 1]->index >> shift) != index)
+ goto skip_pages;
+
+- expected = index == file_end ?
+- (i_size_read(inode) & (msblk->block_size - 1)) :
+- msblk->block_size;
+-
+ if (index == file_end && squashfs_i(inode)->fragment_block !=
+ SQUASHFS_INVALID_BLK) {
+ res = squashfs_readahead_fragment(pages, nr_pages,
+@@ -593,15 +598,15 @@ static void squashfs_readahead(struct readahead_control *ractl)
+
+ res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor);
+
+- squashfs_page_actor_free(actor);
++ last_page = squashfs_page_actor_free(actor);
+
+ if (res == expected) {
+ int bytes;
+
+ /* Last page (if present) may have trailing bytes not filled */
+ bytes = res % PAGE_SIZE;
+- if (pages[nr_pages - 1]->index == file_end && bytes)
+- memzero_page(pages[nr_pages - 1], bytes,
++ if (index == file_end && bytes && last_page)
++ memzero_page(last_page, bytes,
+ PAGE_SIZE - bytes);
+
+ for (i = 0; i < nr_pages; i++) {
+diff --git a/fs/squashfs/page_actor.c b/fs/squashfs/page_actor.c
+index 54b93bf4a25c1..81af6c4ca1157 100644
+--- a/fs/squashfs/page_actor.c
++++ b/fs/squashfs/page_actor.c
+@@ -71,11 +71,13 @@ static void *handle_next_page(struct squashfs_page_actor *actor)
+ (actor->next_index != actor->page[actor->next_page]->index)) {
+ actor->next_index++;
+ actor->returned_pages++;
++ actor->last_page = NULL;
+ return actor->alloc_buffer ? actor->tmp_buffer : ERR_PTR(-ENOMEM);
+ }
+
+ actor->next_index++;
+ actor->returned_pages++;
++ actor->last_page = actor->page[actor->next_page];
+ return actor->pageaddr = kmap_local_page(actor->page[actor->next_page++]);
+ }
+
+@@ -125,6 +127,7 @@ struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_
+ actor->returned_pages = 0;
+ actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1);
+ actor->pageaddr = NULL;
++ actor->last_page = NULL;
+ actor->alloc_buffer = msblk->decompressor->alloc_buffer;
+ actor->squashfs_first_page = direct_first_page;
+ actor->squashfs_next_page = direct_next_page;
+diff --git a/fs/squashfs/page_actor.h b/fs/squashfs/page_actor.h
+index 95ffbb543d913..97d4983559b19 100644
+--- a/fs/squashfs/page_actor.h
++++ b/fs/squashfs/page_actor.h
+@@ -16,6 +16,7 @@ struct squashfs_page_actor {
+ void *(*squashfs_first_page)(struct squashfs_page_actor *);
+ void *(*squashfs_next_page)(struct squashfs_page_actor *);
+ void (*squashfs_finish_page)(struct squashfs_page_actor *);
++ struct page *last_page;
+ int pages;
+ int length;
+ int next_page;
+@@ -29,10 +30,13 @@ extern struct squashfs_page_actor *squashfs_page_actor_init(void **buffer,
+ extern struct squashfs_page_actor *squashfs_page_actor_init_special(
+ struct squashfs_sb_info *msblk,
+ struct page **page, int pages, int length);
+-static inline void squashfs_page_actor_free(struct squashfs_page_actor *actor)
++static inline struct page *squashfs_page_actor_free(struct squashfs_page_actor *actor)
+ {
++ struct page *last_page = actor->last_page;
++
+ kfree(actor->tmp_buffer);
+ kfree(actor);
++ return last_page;
+ }
+ static inline void *squashfs_first_page(struct squashfs_page_actor *actor)
+ {
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index c32de987fa71c..454dab40baf69 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -973,7 +973,7 @@ void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
+ struct mlx5_async_ctx {
+ struct mlx5_core_dev *dev;
+ atomic_t num_inflight;
+- struct wait_queue_head wait;
++ struct completion inflight_done;
+ };
+
+ struct mlx5_async_work;
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index ee8b9ecdc03b7..00df832584471 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -736,11 +736,14 @@ struct perf_event {
+ struct fasync_struct *fasync;
+
+ /* delayed work for NMIs and such */
+- int pending_wakeup;
+- int pending_kill;
+- int pending_disable;
++ unsigned int pending_wakeup;
++ unsigned int pending_kill;
++ unsigned int pending_disable;
++ unsigned int pending_sigtrap;
+ unsigned long pending_addr; /* SIGTRAP */
+- struct irq_work pending;
++ struct irq_work pending_irq;
++ struct callback_head pending_task;
++ unsigned int pending_work;
+
+ atomic_t event_limit;
+
+@@ -857,6 +860,14 @@ struct perf_event_context {
+ #endif
+ void *task_ctx_data; /* pmu specific data */
+ struct rcu_head rcu_head;
++
++ /*
++ * Sum (event->pending_sigtrap + event->pending_work)
++ *
++ * The SIGTRAP is targeted at ctx->task, as such it won't do changing
++ * that until the signal is delivered.
++ */
++ local_t nr_pending;
+ };
+
+ /*
+diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
+index e1b8a915e9e9f..31d86b8c0634f 100644
+--- a/include/linux/userfaultfd_k.h
++++ b/include/linux/userfaultfd_k.h
+@@ -146,9 +146,9 @@ static inline bool userfaultfd_armed(struct vm_area_struct *vma)
+ static inline bool vma_can_userfault(struct vm_area_struct *vma,
+ unsigned long vm_flags)
+ {
+- if (vm_flags & VM_UFFD_MINOR)
+- return is_vm_hugetlb_page(vma) || vma_is_shmem(vma);
+-
++ if ((vm_flags & VM_UFFD_MINOR) &&
++ (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma)))
++ return false;
+ #ifndef CONFIG_PTE_MARKER_UFFD_WP
+ /*
+ * If user requested uffd-wp but not enabled pte markers for
+diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
+index b708d63995f45..2ae2be4c87e5a 100644
+--- a/include/media/v4l2-common.h
++++ b/include/media/v4l2-common.h
+@@ -175,7 +175,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @client: pointer to struct i2c_client
+- * @devname: the name of the device; if NULL, the I²C device's name will be used
++ * @devname: the name of the device; if NULL, the I²C device drivers's name
++ * will be used
+ * @postfix: sub-device specific string to put right after the I²C device name;
+ * may be NULL
+ */
+diff --git a/include/net/sock.h b/include/net/sock.h
+index d08cfe190a78b..8a98ea9360fb7 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2567,7 +2567,7 @@ static inline gfp_t gfp_any(void)
+
+ static inline gfp_t gfp_memcg_charge(void)
+ {
+- return in_softirq() ? GFP_NOWAIT : GFP_KERNEL;
++ return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
+ }
+
+ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)
+diff --git a/include/sound/control.h b/include/sound/control.h
+index eae443ba79ba5..cc3dcc6cfb0f2 100644
+--- a/include/sound/control.h
++++ b/include/sound/control.h
+@@ -138,6 +138,7 @@ int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
+ int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+ int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
++void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
+ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
+ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
+ struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
+index bc7fd46ec2bc8..ac750afa7bc6c 100644
+--- a/include/sound/soc-acpi-intel-match.h
++++ b/include/sound/soc-acpi-intel-match.h
+@@ -30,6 +30,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[];
++extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[];
+
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[];
+@@ -38,6 +39,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[];
++extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[];
+
+ /*
+diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
+index 01e630f2ec786..fbe40307934d0 100644
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -1602,7 +1602,8 @@ struct v4l2_bt_timings {
+ ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
+ #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \
+ ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \
+- (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch)
++ ((bt)->interlaced ? \
++ ((bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) : 0))
+ #define V4L2_DV_BT_FRAME_HEIGHT(bt) \
+ ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt))
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 36fd4b509294a..0d23d4bcd81cc 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -4436,6 +4436,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
+ return -EINVAL;
+ }
+
++ if (btf_type_is_resolve_source_only(ret_type)) {
++ btf_verifier_log_type(env, t, "Invalid return type");
++ return -EINVAL;
++ }
++
+ if (btf_type_needs_resolve(ret_type) &&
+ !env_type_is_resolved(env, ret_type_id)) {
+ err = btf_resolve(env, ret_type, ret_type_id);
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index ff4bffc502c67..072ab26269c0b 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -54,6 +54,7 @@
+ #include <linux/highmem.h>
+ #include <linux/pgtable.h>
+ #include <linux/buildid.h>
++#include <linux/task_work.h>
+
+ #include "internal.h"
+
+@@ -2268,11 +2269,26 @@ event_sched_out(struct perf_event *event,
+ event->pmu->del(event, 0);
+ event->oncpu = -1;
+
+- if (READ_ONCE(event->pending_disable) >= 0) {
+- WRITE_ONCE(event->pending_disable, -1);
++ if (event->pending_disable) {
++ event->pending_disable = 0;
+ perf_cgroup_event_disable(event, ctx);
+ state = PERF_EVENT_STATE_OFF;
+ }
++
++ if (event->pending_sigtrap) {
++ bool dec = true;
++
++ event->pending_sigtrap = 0;
++ if (state != PERF_EVENT_STATE_OFF &&
++ !event->pending_work) {
++ event->pending_work = 1;
++ dec = false;
++ task_work_add(current, &event->pending_task, TWA_RESUME);
++ }
++ if (dec)
++ local_dec(&event->ctx->nr_pending);
++ }
++
+ perf_event_set_state(event, state);
+
+ if (!is_software_event(event))
+@@ -2424,7 +2440,7 @@ static void __perf_event_disable(struct perf_event *event,
+ * hold the top-level event's child_mutex, so any descendant that
+ * goes to exit will block in perf_event_exit_event().
+ *
+- * When called from perf_pending_event it's OK because event->ctx
++ * When called from perf_pending_irq it's OK because event->ctx
+ * is the current context on this CPU and preemption is disabled,
+ * hence we can't get into perf_event_task_sched_out for this context.
+ */
+@@ -2463,9 +2479,8 @@ EXPORT_SYMBOL_GPL(perf_event_disable);
+
+ void perf_event_disable_inatomic(struct perf_event *event)
+ {
+- WRITE_ONCE(event->pending_disable, smp_processor_id());
+- /* can fail, see perf_pending_event_disable() */
+- irq_work_queue(&event->pending);
++ event->pending_disable = 1;
++ irq_work_queue(&event->pending_irq);
+ }
+
+ #define MAX_INTERRUPTS (~0ULL)
+@@ -3420,11 +3435,23 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
+ raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING);
+ if (context_equiv(ctx, next_ctx)) {
+
++ perf_pmu_disable(pmu);
++
++ /* PMIs are disabled; ctx->nr_pending is stable. */
++ if (local_read(&ctx->nr_pending) ||
++ local_read(&next_ctx->nr_pending)) {
++ /*
++ * Must not swap out ctx when there's pending
++ * events that rely on the ctx->task relation.
++ */
++ raw_spin_unlock(&next_ctx->lock);
++ rcu_read_unlock();
++ goto inside_switch;
++ }
++
+ WRITE_ONCE(ctx->task, next);
+ WRITE_ONCE(next_ctx->task, task);
+
+- perf_pmu_disable(pmu);
+-
+ if (cpuctx->sched_cb_usage && pmu->sched_task)
+ pmu->sched_task(ctx, false);
+
+@@ -3465,6 +3492,7 @@ unlock:
+ raw_spin_lock(&ctx->lock);
+ perf_pmu_disable(pmu);
+
++inside_switch:
+ if (cpuctx->sched_cb_usage && pmu->sched_task)
+ pmu->sched_task(ctx, false);
+ task_ctx_sched_out(cpuctx, ctx, EVENT_ALL);
+@@ -4931,7 +4959,7 @@ static void perf_addr_filters_splice(struct perf_event *event,
+
+ static void _free_event(struct perf_event *event)
+ {
+- irq_work_sync(&event->pending);
++ irq_work_sync(&event->pending_irq);
+
+ unaccount_event(event);
+
+@@ -6431,7 +6459,8 @@ static void perf_sigtrap(struct perf_event *event)
+ return;
+
+ /*
+- * perf_pending_event() can race with the task exiting.
++ * Both perf_pending_task() and perf_pending_irq() can race with the
++ * task exiting.
+ */
+ if (current->flags & PF_EXITING)
+ return;
+@@ -6440,23 +6469,33 @@ static void perf_sigtrap(struct perf_event *event)
+ event->attr.type, event->attr.sig_data);
+ }
+
+-static void perf_pending_event_disable(struct perf_event *event)
++/*
++ * Deliver the pending work in-event-context or follow the context.
++ */
++static void __perf_pending_irq(struct perf_event *event)
+ {
+- int cpu = READ_ONCE(event->pending_disable);
++ int cpu = READ_ONCE(event->oncpu);
+
++ /*
++ * If the event isn't running; we done. event_sched_out() will have
++ * taken care of things.
++ */
+ if (cpu < 0)
+ return;
+
++ /*
++ * Yay, we hit home and are in the context of the event.
++ */
+ if (cpu == smp_processor_id()) {
+- WRITE_ONCE(event->pending_disable, -1);
+-
+- if (event->attr.sigtrap) {
++ if (event->pending_sigtrap) {
++ event->pending_sigtrap = 0;
+ perf_sigtrap(event);
+- atomic_set_release(&event->event_limit, 1); /* rearm event */
+- return;
++ local_dec(&event->ctx->nr_pending);
++ }
++ if (event->pending_disable) {
++ event->pending_disable = 0;
++ perf_event_disable_local(event);
+ }
+-
+- perf_event_disable_local(event);
+ return;
+ }
+
+@@ -6476,35 +6515,62 @@ static void perf_pending_event_disable(struct perf_event *event)
+ * irq_work_queue(); // FAILS
+ *
+ * irq_work_run()
+- * perf_pending_event()
++ * perf_pending_irq()
+ *
+ * But the event runs on CPU-B and wants disabling there.
+ */
+- irq_work_queue_on(&event->pending, cpu);
++ irq_work_queue_on(&event->pending_irq, cpu);
+ }
+
+-static void perf_pending_event(struct irq_work *entry)
++static void perf_pending_irq(struct irq_work *entry)
+ {
+- struct perf_event *event = container_of(entry, struct perf_event, pending);
++ struct perf_event *event = container_of(entry, struct perf_event, pending_irq);
+ int rctx;
+
+- rctx = perf_swevent_get_recursion_context();
+ /*
+ * If we 'fail' here, that's OK, it means recursion is already disabled
+ * and we won't recurse 'further'.
+ */
++ rctx = perf_swevent_get_recursion_context();
+
+- perf_pending_event_disable(event);
+-
++ /*
++ * The wakeup isn't bound to the context of the event -- it can happen
++ * irrespective of where the event is.
++ */
+ if (event->pending_wakeup) {
+ event->pending_wakeup = 0;
+ perf_event_wakeup(event);
+ }
+
++ __perf_pending_irq(event);
++
+ if (rctx >= 0)
+ perf_swevent_put_recursion_context(rctx);
+ }
+
++static void perf_pending_task(struct callback_head *head)
++{
++ struct perf_event *event = container_of(head, struct perf_event, pending_task);
++ int rctx;
++
++ /*
++ * If we 'fail' here, that's OK, it means recursion is already disabled
++ * and we won't recurse 'further'.
++ */
++ preempt_disable_notrace();
++ rctx = perf_swevent_get_recursion_context();
++
++ if (event->pending_work) {
++ event->pending_work = 0;
++ perf_sigtrap(event);
++ local_dec(&event->ctx->nr_pending);
++ }
++
++ if (rctx >= 0)
++ perf_swevent_put_recursion_context(rctx);
++ preempt_enable_notrace();
++}
++
+ #ifdef CONFIG_GUEST_PERF_EVENTS
+ struct perf_guest_info_callbacks __rcu *perf_guest_cbs;
+
+@@ -9188,8 +9254,8 @@ int perf_event_account_interrupt(struct perf_event *event)
+ */
+
+ static int __perf_event_overflow(struct perf_event *event,
+- int throttle, struct perf_sample_data *data,
+- struct pt_regs *regs)
++ int throttle, struct perf_sample_data *data,
++ struct pt_regs *regs)
+ {
+ int events = atomic_read(&event->event_limit);
+ int ret = 0;
+@@ -9212,24 +9278,36 @@ static int __perf_event_overflow(struct perf_event *event,
+ if (events && atomic_dec_and_test(&event->event_limit)) {
+ ret = 1;
+ event->pending_kill = POLL_HUP;
+- event->pending_addr = data->addr;
+-
+ perf_event_disable_inatomic(event);
+ }
+
++ if (event->attr.sigtrap) {
++ /*
++ * Should not be able to return to user space without processing
++ * pending_sigtrap (kernel events can overflow multiple times).
++ */
++ WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel);
++ if (!event->pending_sigtrap) {
++ event->pending_sigtrap = 1;
++ local_inc(&event->ctx->nr_pending);
++ }
++ event->pending_addr = data->addr;
++ irq_work_queue(&event->pending_irq);
++ }
++
+ READ_ONCE(event->overflow_handler)(event, data, regs);
+
+ if (*perf_event_fasync(event) && event->pending_kill) {
+ event->pending_wakeup = 1;
+- irq_work_queue(&event->pending);
++ irq_work_queue(&event->pending_irq);
+ }
+
+ return ret;
+ }
+
+ int perf_event_overflow(struct perf_event *event,
+- struct perf_sample_data *data,
+- struct pt_regs *regs)
++ struct perf_sample_data *data,
++ struct pt_regs *regs)
+ {
+ return __perf_event_overflow(event, 1, data, regs);
+ }
+@@ -11537,8 +11615,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+
+
+ init_waitqueue_head(&event->waitq);
+- event->pending_disable = -1;
+- init_irq_work(&event->pending, perf_pending_event);
++ init_irq_work(&event->pending_irq, perf_pending_irq);
++ init_task_work(&event->pending_task, perf_pending_task);
+
+ mutex_init(&event->mmap_mutex);
+ raw_spin_lock_init(&event->addr_filters.lock);
+@@ -11560,9 +11638,6 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+ if (parent_event)
+ event->event_caps = parent_event->event_caps;
+
+- if (event->attr.sigtrap)
+- atomic_set(&event->event_limit, 1);
+-
+ if (task) {
+ event->attach_state = PERF_ATTACH_TASK;
+ /*
+diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
+index 726132039c388..273a0fe7910a5 100644
+--- a/kernel/events/ring_buffer.c
++++ b/kernel/events/ring_buffer.c
+@@ -22,7 +22,7 @@ static void perf_output_wakeup(struct perf_output_handle *handle)
+ atomic_set(&handle->rb->poll, EPOLLIN);
+
+ handle->event->pending_wakeup = 1;
+- irq_work_queue(&handle->event->pending);
++ irq_work_queue(&handle->event->pending_irq);
+ }
+
+ /*
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index 89c71fce225dd..537dd3beafc16 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -641,7 +641,7 @@ static void power_down(void)
+ int error;
+
+ if (hibernation_mode == HIBERNATION_SUSPEND) {
+- error = suspend_devices_and_enter(PM_SUSPEND_MEM);
++ error = suspend_devices_and_enter(mem_sleep_current);
+ if (error) {
+ hibernation_mode = hibernation_ops ?
+ HIBERNATION_PLATFORM :
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index eb435941e92fd..5b52727dcc1c4 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -1402,30 +1402,32 @@ static void rcu_poll_gp_seq_end(unsigned long *snap)
+ // where caller does not hold the root rcu_node structure's lock.
+ static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap)
+ {
++ unsigned long flags;
+ struct rcu_node *rnp = rcu_get_root();
+
+ if (rcu_init_invoked()) {
+ lockdep_assert_irqs_enabled();
+- raw_spin_lock_irq_rcu_node(rnp);
++ raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ }
+ rcu_poll_gp_seq_start(snap);
+ if (rcu_init_invoked())
+- raw_spin_unlock_irq_rcu_node(rnp);
++ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ }
+
+ // Make the polled API aware of the end of a grace period, but where
+ // caller does not hold the root rcu_node structure's lock.
+ static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap)
+ {
++ unsigned long flags;
+ struct rcu_node *rnp = rcu_get_root();
+
+ if (rcu_init_invoked()) {
+ lockdep_assert_irqs_enabled();
+- raw_spin_lock_irq_rcu_node(rnp);
++ raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ }
+ rcu_poll_gp_seq_end(snap);
+ if (rcu_init_invoked())
+- raw_spin_unlock_irq_rcu_node(rnp);
++ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ }
+
+ /*
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index e26688d387aeb..f34b489636ffb 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -1197,6 +1197,14 @@ static inline bool is_migration_disabled(struct task_struct *p)
+ #endif
+ }
+
++DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++
++#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
++#define this_rq() this_cpu_ptr(&runqueues)
++#define task_rq(p) cpu_rq(task_cpu(p))
++#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
++#define raw_rq() raw_cpu_ptr(&runqueues)
++
+ struct sched_group;
+ #ifdef CONFIG_SCHED_CORE
+ static inline struct cpumask *sched_group_span(struct sched_group *sg);
+@@ -1284,7 +1292,7 @@ static inline bool sched_group_cookie_match(struct rq *rq,
+ return true;
+
+ for_each_cpu_and(cpu, sched_group_span(group), p->cpus_ptr) {
+- if (sched_core_cookie_match(rq, p))
++ if (sched_core_cookie_match(cpu_rq(cpu), p))
+ return true;
+ }
+ return false;
+@@ -1399,14 +1407,6 @@ static inline void update_idle_core(struct rq *rq)
+ static inline void update_idle_core(struct rq *rq) { }
+ #endif
+
+-DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
+-
+-#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
+-#define this_rq() this_cpu_ptr(&runqueues)
+-#define task_rq(p) cpu_rq(task_cpu(p))
+-#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
+-#define raw_rq() raw_cpu_ptr(&runqueues)
+-
+ #ifdef CONFIG_FAIR_GROUP_SCHED
+ static inline struct task_struct *task_of(struct sched_entity *se)
+ {
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index f42bb51e023a0..9558dbf3954ce 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2445,7 +2445,16 @@ static void __split_huge_page_tail(struct page *head, int tail,
+ page_tail);
+ page_tail->mapping = head->mapping;
+ page_tail->index = head->index + tail;
+- page_tail->private = 0;
++
++ /*
++ * page->private should not be set in tail pages with the exception
++ * of swap cache pages that store the swp_entry_t in tail pages.
++ * Fix up and warn once if private is unexpectedly set.
++ */
++ if (!folio_test_swapcache(page_folio(head))) {
++ VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail);
++ page_tail->private = 0;
++ }
+
+ /* Page flags must be visible before we make the page non-compound. */
+ smp_wmb();
+diff --git a/mm/kmemleak.c b/mm/kmemleak.c
+index 1eddc0132f7f5..613d34b57c5d9 100644
+--- a/mm/kmemleak.c
++++ b/mm/kmemleak.c
+@@ -1463,6 +1463,27 @@ static void scan_gray_list(void)
+ WARN_ON(!list_empty(&gray_list));
+ }
+
++/*
++ * Conditionally call resched() in a object iteration loop while making sure
++ * that the given object won't go away without RCU read lock by performing a
++ * get_object() if !pinned.
++ *
++ * Return: false if can't do a cond_resched() due to get_object() failure
++ * true otherwise
++ */
++static bool kmemleak_cond_resched(struct kmemleak_object *object, bool pinned)
++{
++ if (!pinned && !get_object(object))
++ return false;
++
++ rcu_read_unlock();
++ cond_resched();
++ rcu_read_lock();
++ if (!pinned)
++ put_object(object);
++ return true;
++}
++
+ /*
+ * Scan data sections and all the referenced memory blocks allocated via the
+ * kernel's standard allocators. This function must be called with the
+@@ -1474,7 +1495,7 @@ static void kmemleak_scan(void)
+ struct zone *zone;
+ int __maybe_unused i;
+ int new_leaks = 0;
+- int loop1_cnt = 0;
++ int loop_cnt = 0;
+
+ jiffies_last_scan = jiffies;
+
+@@ -1483,7 +1504,6 @@ static void kmemleak_scan(void)
+ list_for_each_entry_rcu(object, &object_list, object_list) {
+ bool obj_pinned = false;
+
+- loop1_cnt++;
+ raw_spin_lock_irq(&object->lock);
+ #ifdef DEBUG
+ /*
+@@ -1517,24 +1537,11 @@ static void kmemleak_scan(void)
+ raw_spin_unlock_irq(&object->lock);
+
+ /*
+- * Do a cond_resched() to avoid soft lockup every 64k objects.
+- * Make sure a reference has been taken so that the object
+- * won't go away without RCU read lock.
++ * Do a cond_resched() every 64k objects to avoid soft lockup.
+ */
+- if (!(loop1_cnt & 0xffff)) {
+- if (!obj_pinned && !get_object(object)) {
+- /* Try the next object instead */
+- loop1_cnt--;
+- continue;
+- }
+-
+- rcu_read_unlock();
+- cond_resched();
+- rcu_read_lock();
+-
+- if (!obj_pinned)
+- put_object(object);
+- }
++ if (!(++loop_cnt & 0xffff) &&
++ !kmemleak_cond_resched(object, obj_pinned))
++ loop_cnt--; /* Try again on next object */
+ }
+ rcu_read_unlock();
+
+@@ -1601,7 +1608,15 @@ static void kmemleak_scan(void)
+ * scan and color them gray until the next scan.
+ */
+ rcu_read_lock();
++ loop_cnt = 0;
+ list_for_each_entry_rcu(object, &object_list, object_list) {
++ /*
++ * Do a cond_resched() every 64k objects to avoid soft lockup.
++ */
++ if (!(++loop_cnt & 0xffff) &&
++ !kmemleak_cond_resched(object, false))
++ loop_cnt--; /* Try again on next object */
++
+ /*
+ * This is racy but we can save the overhead of lock/unlock
+ * calls. The missed objects, if any, should be caught in
+@@ -1635,7 +1650,15 @@ static void kmemleak_scan(void)
+ * Scanning result reporting.
+ */
+ rcu_read_lock();
++ loop_cnt = 0;
+ list_for_each_entry_rcu(object, &object_list, object_list) {
++ /*
++ * Do a cond_resched() every 64k objects to avoid soft lockup.
++ */
++ if (!(++loop_cnt & 0xffff) &&
++ !kmemleak_cond_resched(object, false))
++ loop_cnt--; /* Try again on next object */
++
+ /*
+ * This is racy but we can save the overhead of lock/unlock
+ * calls. The missed objects, if any, should be caught in
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 9ff51650f4f07..98ed17a4471a0 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -811,7 +811,14 @@ static bool madvise_dontneed_free_valid_vma(struct vm_area_struct *vma,
+ if (start & ~huge_page_mask(hstate_vma(vma)))
+ return false;
+
+- *end = ALIGN(*end, huge_page_size(hstate_vma(vma)));
++ /*
++ * Madvise callers expect the length to be rounded up to PAGE_SIZE
++ * boundaries, and may be unaware that this VMA uses huge pages.
++ * Avoid unexpected data loss by rounding down the number of
++ * huge pages freed.
++ */
++ *end = ALIGN_DOWN(*end, huge_page_size(hstate_vma(vma)));
++
+ return true;
+ }
+
+@@ -826,6 +833,9 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
+ if (!madvise_dontneed_free_valid_vma(vma, start, &end, behavior))
+ return -EINVAL;
+
++ if (start == end)
++ return 0;
++
+ if (!userfaultfd_remove(vma, start, end)) {
+ *prev = NULL; /* mmap_lock has been dropped, prev is stale */
+
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 6a1597c92261d..524248466bb82 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -1558,6 +1558,13 @@ out:
+ */
+ list_splice(&ret_pages, from);
+
++ /*
++ * Return 0 in case all subpages of fail-to-migrate THPs are
++ * migrated successfully.
++ */
++ if (list_empty(from))
++ rc = 0;
++
+ count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded);
+ count_vm_events(PGMIGRATE_FAIL, nr_failed_pages);
+ count_vm_events(THP_MIGRATION_SUCCESS, nr_thp_succeeded);
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index d04211f0ef0b1..19749f5409e72 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -804,6 +804,7 @@ static void prep_compound_tail(struct page *head, int tail_idx)
+
+ p->mapping = TAIL_MAPPING;
+ set_compound_head(p, head);
++ set_page_private(p, 0);
+ }
+
+ void prep_compound_page(struct page *page, unsigned int order)
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index d7d86c944d76d..55f29c9f9e08e 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -342,10 +342,12 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ __skb_unlink(do_skb, &session->skb_queue);
+ /* drop ref taken in j1939_session_skb_queue() */
+ skb_unref(do_skb);
++ spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+
+ kfree_skb(do_skb);
++ } else {
++ spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+ }
+- spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+ }
+
+ void j1939_session_skb_queue(struct j1939_session *session,
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 0ec2f5906a27c..f64654df71a29 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -117,6 +117,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
+
+ static int ops_init(const struct pernet_operations *ops, struct net *net)
+ {
++ struct net_generic *ng;
+ int err = -ENOMEM;
+ void *data = NULL;
+
+@@ -135,7 +136,13 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
+ if (!err)
+ return 0;
+
++ if (ops->id && ops->size) {
+ cleanup:
++ ng = rcu_dereference_protected(net->gen,
++ lockdep_is_held(&pernet_ops_rwsem));
++ ng->ptr[*ops->id] = NULL;
++ }
++
+ kfree(data);
+
+ out:
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 417463da4fac7..5e1a8eeb5e322 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3868,7 +3868,7 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
+ } else if (i < MAX_SKB_FRAGS) {
+ skb_zcopy_downgrade_managed(skb);
+ get_page(page);
+- skb_fill_page_desc(skb, i, page, offset, size);
++ skb_fill_page_desc_noacc(skb, i, page, offset, size);
+ } else {
+ return -EMSGSIZE;
+ }
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 1c94bb8ea03f2..49c0a2a77f02d 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -124,7 +124,7 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+ if (ret)
+ goto err_free;
+
+- ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
++ ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL);
+ if (ret < 0)
+ goto err_ops;
+
+diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
+index 6e55fae4c6860..1fa2fe041ec03 100644
+--- a/net/ieee802154/socket.c
++++ b/net/ieee802154/socket.c
+@@ -502,8 +502,10 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
+ if (err < 0)
+ goto out;
+
+- if (addr->family != AF_IEEE802154)
++ if (addr->family != AF_IEEE802154) {
++ err = -EINVAL;
+ goto out;
++ }
+
+ ieee802154_addr_from_sa(&haddr, &addr->addr);
+ dev = ieee802154_get_dev(sock_net(sk), &haddr);
+diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
+index 853a75a8fbafc..d8ef05347fd98 100644
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -2534,7 +2534,7 @@ static int nh_create_ipv4(struct net *net, struct nexthop *nh,
+ if (!err) {
+ nh->nh_flags = fib_nh->fib_nh_flags;
+ fib_info_update_nhc_saddr(net, &fib_nh->nh_common,
+- fib_nh->fib_nh_scope);
++ !fib_nh->fib_nh_scope ? 0 : fib_nh->fib_nh_scope - 1);
+ } else {
+ fib_nh_release(net, fib_nh);
+ }
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index bc2ea12221f95..0640453fce54b 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2192,7 +2192,8 @@ void tcp_enter_loss(struct sock *sk)
+ */
+ static bool tcp_check_sack_reneging(struct sock *sk, int flag)
+ {
+- if (flag & FLAG_SACK_RENEGING) {
++ if (flag & FLAG_SACK_RENEGING &&
++ flag & FLAG_SND_UNA_ADVANCED) {
+ struct tcp_sock *tp = tcp_sk(sk);
+ unsigned long delay = max(usecs_to_jiffies(tp->srtt_us >> 4),
+ msecs_to_jiffies(10));
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 5b019ba2b9d21..fe9a6022db66d 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1853,11 +1853,13 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
+ __skb_push(skb, hdrlen);
+
+ no_coalesce:
++ limit = (u32)READ_ONCE(sk->sk_rcvbuf) + (u32)(READ_ONCE(sk->sk_sndbuf) >> 1);
++
+ /* Only socket owner can try to collapse/prune rx queues
+ * to reduce memory overhead, so add a little headroom here.
+ * Few sockets backlog are possibly concurrently non empty.
+ */
+- limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf) + 64*1024;
++ limit += 64 * 1024;
+
+ if (unlikely(sk_add_backlog(sk, skb, limit))) {
+ bh_unlock_sock(sk);
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
+index 80cb50d459e4c..409e8dded7c65 100644
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -1175,14 +1175,16 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
+ dev->needed_headroom = dst_len;
+
+ if (set_mtu) {
+- dev->mtu = rt->dst.dev->mtu - t_hlen;
++ int mtu = rt->dst.dev->mtu - t_hlen;
++
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+- dev->mtu -= 8;
++ mtu -= 8;
+ if (dev->type == ARPHRD_ETHER)
+- dev->mtu -= ETH_HLEN;
++ mtu -= ETH_HLEN;
+
+- if (dev->mtu < IPV6_MIN_MTU)
+- dev->mtu = IPV6_MIN_MTU;
++ if (mtu < IPV6_MIN_MTU)
++ mtu = IPV6_MIN_MTU;
++ WRITE_ONCE(dev->mtu, mtu);
+ }
+ }
+ ip6_rt_put(rt);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 79c6a827dea9f..616487b146982 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1450,8 +1450,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
+ struct net_device *tdev = NULL;
+ struct __ip6_tnl_parm *p = &t->parms;
+ struct flowi6 *fl6 = &t->fl.u.ip6;
+- unsigned int mtu;
+ int t_hlen;
++ int mtu;
+
+ __dev_addr_set(dev, &p->laddr, sizeof(struct in6_addr));
+ memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
+@@ -1498,12 +1498,13 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
+ dev->hard_header_len = tdev->hard_header_len + t_hlen;
+ mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU);
+
+- dev->mtu = mtu - t_hlen;
++ mtu = mtu - t_hlen;
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+- dev->mtu -= 8;
++ mtu -= 8;
+
+- if (dev->mtu < IPV6_MIN_MTU)
+- dev->mtu = IPV6_MIN_MTU;
++ if (mtu < IPV6_MIN_MTU)
++ mtu = IPV6_MIN_MTU;
++ WRITE_ONCE(dev->mtu, mtu);
+ }
+ }
+ }
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
+index e0dcc7a193df2..b61066ac8648e 100644
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -419,6 +419,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
+ rtnl_lock();
+ lock_sock(sk);
+
++ /* Another thread has converted the socket into IPv4 with
++ * IPV6_ADDRFORM concurrently.
++ */
++ if (unlikely(sk->sk_family != AF_INET6))
++ goto unlock;
++
+ switch (optname) {
+
+ case IPV6_ADDRFORM:
+@@ -994,6 +1000,7 @@ done:
+ break;
+ }
+
++unlock:
+ release_sock(sk);
+ if (needs_rtnl)
+ rtnl_unlock();
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 6b73b7a5f1755..59b2d9a6210c8 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -1124,10 +1124,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
+
+ if (tdev && !netif_is_l3_master(tdev)) {
+ int t_hlen = tunnel->hlen + sizeof(struct iphdr);
++ int mtu;
+
+- dev->mtu = tdev->mtu - t_hlen;
+- if (dev->mtu < IPV6_MIN_MTU)
+- dev->mtu = IPV6_MIN_MTU;
++ mtu = tdev->mtu - t_hlen;
++ if (mtu < IPV6_MIN_MTU)
++ mtu = IPV6_MIN_MTU;
++ WRITE_ONCE(dev->mtu, mtu);
+ }
+ }
+
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 1215c863e1c41..befc62606cdf0 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -162,7 +162,8 @@ static void kcm_rcv_ready(struct kcm_sock *kcm)
+ /* Buffer limit is okay now, add to ready list */
+ list_add_tail(&kcm->wait_rx_list,
+ &kcm->mux->kcm_rx_waiters);
+- kcm->rx_wait = true;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_wait, true);
+ }
+
+ static void kcm_rfree(struct sk_buff *skb)
+@@ -178,7 +179,7 @@ static void kcm_rfree(struct sk_buff *skb)
+ /* For reading rx_wait and rx_psock without holding lock */
+ smp_mb__after_atomic();
+
+- if (!kcm->rx_wait && !kcm->rx_psock &&
++ if (!READ_ONCE(kcm->rx_wait) && !READ_ONCE(kcm->rx_psock) &&
+ sk_rmem_alloc_get(sk) < sk->sk_rcvlowat) {
+ spin_lock_bh(&mux->rx_lock);
+ kcm_rcv_ready(kcm);
+@@ -237,7 +238,8 @@ try_again:
+ if (kcm_queue_rcv_skb(&kcm->sk, skb)) {
+ /* Should mean socket buffer full */
+ list_del(&kcm->wait_rx_list);
+- kcm->rx_wait = false;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_wait, false);
+
+ /* Commit rx_wait to read in kcm_free */
+ smp_wmb();
+@@ -280,10 +282,12 @@ static struct kcm_sock *reserve_rx_kcm(struct kcm_psock *psock,
+ kcm = list_first_entry(&mux->kcm_rx_waiters,
+ struct kcm_sock, wait_rx_list);
+ list_del(&kcm->wait_rx_list);
+- kcm->rx_wait = false;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_wait, false);
+
+ psock->rx_kcm = kcm;
+- kcm->rx_psock = psock;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_psock, psock);
+
+ spin_unlock_bh(&mux->rx_lock);
+
+@@ -310,7 +314,8 @@ static void unreserve_rx_kcm(struct kcm_psock *psock,
+ spin_lock_bh(&mux->rx_lock);
+
+ psock->rx_kcm = NULL;
+- kcm->rx_psock = NULL;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_psock, NULL);
+
+ /* Commit kcm->rx_psock before sk_rmem_alloc_get to sync with
+ * kcm_rfree
+@@ -834,7 +839,7 @@ static ssize_t kcm_sendpage(struct socket *sock, struct page *page,
+ }
+
+ get_page(page);
+- skb_fill_page_desc(skb, i, page, offset, size);
++ skb_fill_page_desc_noacc(skb, i, page, offset, size);
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
+
+ coalesced:
+@@ -1240,7 +1245,8 @@ static void kcm_recv_disable(struct kcm_sock *kcm)
+ if (!kcm->rx_psock) {
+ if (kcm->rx_wait) {
+ list_del(&kcm->wait_rx_list);
+- kcm->rx_wait = false;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_wait, false);
+ }
+
+ requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue);
+@@ -1793,7 +1799,8 @@ static void kcm_done(struct kcm_sock *kcm)
+
+ if (kcm->rx_wait) {
+ list_del(&kcm->wait_rx_list);
+- kcm->rx_wait = false;
++ /* paired with lockless reads in kcm_rfree() */
++ WRITE_ONCE(kcm->rx_wait, false);
+ }
+ /* Move any pending receive messages to other kcm sockets */
+ requeue_rx_msgs(mux, &sk->sk_receive_queue);
+diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
+index c439125ef2b91..726b47a4611b5 100644
+--- a/net/mac802154/rx.c
++++ b/net/mac802154/rx.c
+@@ -132,7 +132,7 @@ static int
+ ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr)
+ {
+ int hlen;
+- struct ieee802154_mac_cb *cb = mac_cb_init(skb);
++ struct ieee802154_mac_cb *cb = mac_cb(skb);
+
+ skb_reset_mac_header(skb);
+
+@@ -294,8 +294,9 @@ void
+ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)
+ {
+ struct ieee802154_local *local = hw_to_local(hw);
++ struct ieee802154_mac_cb *cb = mac_cb_init(skb);
+
+- mac_cb(skb)->lqi = lqi;
++ cb->lqi = lqi;
+ skb->pkt_type = IEEE802154_RX_MSG;
+ skb_queue_tail(&local->skb_queue, skb);
+ tasklet_schedule(&local->tasklet);
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index f8897a70c11d4..b568f55998f3c 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2867,7 +2867,7 @@ static void mptcp_close(struct sock *sk, long timeout)
+ sock_put(sk);
+ }
+
+-static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
++void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
+ {
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+ const struct ipv6_pinfo *ssk6 = inet6_sk(ssk);
+@@ -3613,7 +3613,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
+ if (mptcp_is_fully_established(newsk))
+ mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
+
+- mptcp_copy_inaddrs(newsk, msk->first);
+ mptcp_rcv_space_init(msk, msk->first);
+ mptcp_propagate_sndbuf(newsk, msk->first);
+
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 8f372b8f059c6..c1eaa16855921 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -597,6 +597,7 @@ int mptcp_is_checksum_enabled(const struct net *net);
+ int mptcp_allow_join_id0(const struct net *net);
+ unsigned int mptcp_stale_loss_cnt(const struct net *net);
+ int mptcp_get_pm_type(const struct net *net);
++void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk);
+ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
+ struct mptcp_options_received *mp_opt);
+ bool __mptcp_retransmit_pending_data(struct sock *sk);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 07dd23d0fe04a..02a54d59697b5 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -723,6 +723,8 @@ create_child:
+ goto dispose_child;
+ }
+
++ if (new_msk)
++ mptcp_copy_inaddrs(new_msk, child);
+ subflow_drop_ctx(child);
+ goto out;
+ }
+@@ -750,6 +752,11 @@ create_child:
+ ctx->conn = new_msk;
+ new_msk = NULL;
+
++ /* set msk addresses early to ensure mptcp_pm_get_local_id()
++ * uses the correct data
++ */
++ mptcp_copy_inaddrs(ctx->conn, child);
++
+ /* with OoO packets we can reach here without ingress
+ * mpc option
+ */
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 93c596e3b22b9..8a22574ed7ad6 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1606,7 +1606,8 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb,
+ if (IS_ERR(dp))
+ return;
+
+- WARN(dp->user_features, "Dropping previously announced user features\n");
++ pr_warn("%s: Dropping previously announced user features\n",
++ ovs_dp_name(dp));
+ dp->user_features = 0;
+ }
+
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index 14fd05fd6107d..d92ec92f0b71d 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -450,12 +450,19 @@ static void tipc_conn_data_ready(struct sock *sk)
+ static void tipc_topsrv_accept(struct work_struct *work)
+ {
+ struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
+- struct socket *lsock = srv->listener;
+- struct socket *newsock;
++ struct socket *newsock, *lsock;
+ struct tipc_conn *con;
+ struct sock *newsk;
+ int ret;
+
++ spin_lock_bh(&srv->idr_lock);
++ if (!srv->listener) {
++ spin_unlock_bh(&srv->idr_lock);
++ return;
++ }
++ lsock = srv->listener;
++ spin_unlock_bh(&srv->idr_lock);
++
+ while (1) {
+ ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+ if (ret < 0)
+@@ -489,7 +496,7 @@ static void tipc_topsrv_listener_data_ready(struct sock *sk)
+
+ read_lock_bh(&sk->sk_callback_lock);
+ srv = sk->sk_user_data;
+- if (srv->listener)
++ if (srv)
+ queue_work(srv->rcv_wq, &srv->awork);
+ read_unlock_bh(&sk->sk_callback_lock);
+ }
+@@ -699,8 +706,9 @@ static void tipc_topsrv_stop(struct net *net)
+ __module_get(lsock->sk->sk_prot_creator->owner);
+ srv->listener = NULL;
+ spin_unlock_bh(&srv->idr_lock);
+- sock_release(lsock);
++
+ tipc_topsrv_work_stop(srv);
++ sock_release(lsock);
+ idr_destroy(&srv->conn_idr);
+ kfree(srv);
+ }
+diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
+index faf6b03131ee4..51ed2f34b276d 100644
+--- a/sound/aoa/soundbus/i2sbus/core.c
++++ b/sound/aoa/soundbus/i2sbus/core.c
+@@ -147,6 +147,7 @@ static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
+ return rc;
+ }
+
++/* Returns 1 if added, 0 for otherwise; don't return a negative value! */
+ /* FIXME: look at device node refcounting */
+ static int i2sbus_add_dev(struct macio_dev *macio,
+ struct i2sbus_control *control,
+@@ -213,7 +214,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
+ * either as the second one in that case is just a modem. */
+ if (!ok) {
+ kfree(dev);
+- return -ENODEV;
++ return 0;
+ }
+
+ mutex_init(&dev->lock);
+@@ -302,6 +303,10 @@ static int i2sbus_add_dev(struct macio_dev *macio,
+
+ if (soundbus_add_one(&dev->sound)) {
+ printk(KERN_DEBUG "i2sbus: device registration error!\n");
++ if (dev->sound.ofdev.dev.kobj.state_initialized) {
++ soundbus_dev_put(&dev->sound);
++ return 0;
++ }
+ goto err;
+ }
+
+diff --git a/sound/core/control.c b/sound/core/control.c
+index a7271927d875f..50e7ba66f1876 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -753,6 +753,29 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
+ }
+ EXPORT_SYMBOL(snd_ctl_rename_id);
+
++/**
++ * snd_ctl_rename - rename the control on the card
++ * @card: the card instance
++ * @kctl: the control to rename
++ * @name: the new name
++ *
++ * Renames the specified control on the card to the new name.
++ *
++ * Make sure to take the control write lock - down_write(&card->controls_rwsem).
++ */
++void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,
++ const char *name)
++{
++ remove_hash_entries(card, kctl);
++
++ if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)
++ pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n",
++ name, kctl->id.name);
++
++ add_hash_entries(card, kctl);
++}
++EXPORT_SYMBOL(snd_ctl_rename);
++
+ #ifndef CONFIG_SND_CTL_FAST_LOOKUP
+ static struct snd_kcontrol *
+ snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid)
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
+index cb60a07d39a8e..ff685321f1a11 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -2009,6 +2009,7 @@ static int snd_ac97_dev_register(struct snd_device *device)
+ err = device_register(&ac97->dev);
+ if (err < 0) {
+ ac97_err(ac97, "Can't register ac97 bus\n");
++ put_device(&ac97->dev);
+ ac97->dev.bus = NULL;
+ return err;
+ }
+@@ -2655,11 +2656,18 @@ EXPORT_SYMBOL(snd_ac97_resume);
+ */
+ static void set_ctl_name(char *dst, const char *src, const char *suffix)
+ {
+- if (suffix)
+- sprintf(dst, "%s %s", src, suffix);
+- else
+- strcpy(dst, src);
+-}
++ const size_t msize = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
++
++ if (suffix) {
++ if (snprintf(dst, msize, "%s %s", src, suffix) >= msize)
++ pr_warn("ALSA: AC97 control name '%s %s' truncated to '%s'\n",
++ src, suffix, dst);
++ } else {
++ if (strscpy(dst, src, msize) < 0)
++ pr_warn("ALSA: AC97 control name '%s' truncated to '%s'\n",
++ src, dst);
++ }
++}
+
+ /* remove the control with the given name and optional suffix */
+ static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+@@ -2686,8 +2694,11 @@ static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+ const char *dst, const char *suffix)
+ {
+ struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
++ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
++
+ if (kctl) {
+- set_ctl_name(kctl->id.name, dst, suffix);
++ set_ctl_name(name, dst, suffix);
++ snd_ctl_rename(ac97->bus->card, kctl, name);
+ return 0;
+ }
+ return -ENOENT;
+@@ -2706,11 +2717,17 @@ static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+ const char *s2, const char *suffix)
+ {
+ struct snd_kcontrol *kctl1, *kctl2;
++ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
++
+ kctl1 = ctl_find(ac97, s1, suffix);
+ kctl2 = ctl_find(ac97, s2, suffix);
+ if (kctl1 && kctl2) {
+- set_ctl_name(kctl1->id.name, s2, suffix);
+- set_ctl_name(kctl2->id.name, s1, suffix);
++ set_ctl_name(name, s2, suffix);
++ snd_ctl_rename(ac97->bus->card, kctl1, name);
++
++ set_ctl_name(name, s1, suffix);
++ snd_ctl_rename(ac97->bus->card, kctl2, name);
++
+ return 0;
+ }
+ return -ENOENT;
+diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
+index 0aa7af049b1b9..6cbb2bc4a0483 100644
+--- a/sound/pci/au88x0/au88x0.h
++++ b/sound/pci/au88x0/au88x0.h
+@@ -141,7 +141,7 @@ struct snd_vortex {
+ #ifndef CHIP_AU8810
+ stream_t dma_wt[NR_WT];
+ wt_voice_t wt_voice[NR_WT]; /* WT register cache. */
+- char mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */
++ s8 mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */
+ #endif
+
+ /* Global resources */
+@@ -235,8 +235,8 @@ static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
+ static void vortex_connect_default(vortex_t * vortex, int en);
+ static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
+ int dir, int type, int subdev);
+-static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
+- int restype);
++static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
++ int restype);
+ #ifndef CHIP_AU8810
+ static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
+ static void vortex_wt_connect(vortex_t * vortex, int en);
+diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
+index 2ed5100b8caea..f217c02dfdfa4 100644
+--- a/sound/pci/au88x0/au88x0_core.c
++++ b/sound/pci/au88x0/au88x0_core.c
+@@ -1998,7 +1998,7 @@ static const int resnum[VORTEX_RESOURCE_LAST] =
+ out: Mean checkout if != 0. Else mean Checkin resource.
+ restype: Indicates type of resource to be checked in or out.
+ */
+-static char
++static int
+ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
+ {
+ int i, qty = resnum[restype], resinuse = 0;
+diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
+index 05f56015ddd87..f6381c098d4f6 100644
+--- a/sound/pci/ca0106/ca0106_mixer.c
++++ b/sound/pci/ca0106/ca0106_mixer.c
+@@ -720,7 +720,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
+ {
+ struct snd_kcontrol *kctl = ctl_find(card, src);
+ if (kctl) {
+- strcpy(kctl->id.name, dst);
++ snd_ctl_rename(card, kctl, dst);
+ return 0;
+ }
+ return -ENOENT;
+diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
+index e9c0fe3b84461..3c115f8ab96c0 100644
+--- a/sound/pci/emu10k1/emumixer.c
++++ b/sound/pci/emu10k1/emumixer.c
+@@ -1767,7 +1767,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
+ {
+ struct snd_kcontrol *kctl = ctl_find(card, src);
+ if (kctl) {
+- strcpy(kctl->id.name, dst);
++ snd_ctl_rename(card, kctl, dst);
+ return 0;
+ }
+ return -ENOENT;
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 8f7905e0b376b..6e25a0f89f6b4 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2141,7 +2141,7 @@ static void rename_ctl(struct hda_codec *codec, const char *oldname,
+
+ kctl = snd_hda_find_mixer_ctl(codec, oldname);
+ if (kctl)
+- strcpy(kctl->id.name, newname);
++ snd_ctl_rename(codec->card, kctl, newname);
+ }
+
+ static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
+@@ -9333,6 +9333,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
++ SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+@@ -9351,6 +9352,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x89c0, "HP ZBook Power 15.6 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+@@ -9405,6 +9407,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
++ SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
+ SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
+ SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
+ SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
+diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
+index dcc43a81ae0e8..65add92c88aa6 100644
+--- a/sound/pci/rme9652/hdsp.c
++++ b/sound/pci/rme9652/hdsp.c
+@@ -433,7 +433,7 @@ struct hdsp_midi {
+ struct snd_rawmidi *rmidi;
+ struct snd_rawmidi_substream *input;
+ struct snd_rawmidi_substream *output;
+- char istimer; /* timer in use */
++ signed char istimer; /* timer in use */
+ struct timer_list timer;
+ spinlock_t lock;
+ int pending;
+@@ -480,7 +480,7 @@ struct hdsp {
+ pid_t playback_pid;
+ int running;
+ int system_sample_rate;
+- const char *channel_map;
++ const signed char *channel_map;
+ int dev;
+ int irq;
+ unsigned long port;
+@@ -502,7 +502,7 @@ struct hdsp {
+ where the data for that channel can be read/written from/to.
+ */
+
+-static const char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25
+ };
+@@ -517,7 +517,7 @@ static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
+ -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+-static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = {
+ /* ADAT channels are remapped */
+ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
+ /* channels 12 and 13 are S/PDIF */
+@@ -526,7 +526,7 @@ static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+-static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
+ /* ADAT channels */
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ /* SPDIF */
+@@ -540,7 +540,7 @@ static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
+ -1, -1
+ };
+
+-static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
+ /* ADAT */
+ 1, 3, 5, 7,
+ /* SPDIF */
+@@ -554,7 +554,7 @@ static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
+ -1, -1, -1, -1, -1, -1
+ };
+
+-static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
+ /* ADAT is disabled in this mode */
+ /* SPDIF */
+ 8, 9,
+@@ -3939,7 +3939,7 @@ static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream
+ return hdsp_hw_pointer(hdsp);
+ }
+
+-static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
++static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp,
+ int stream,
+ int channel)
+
+@@ -3964,7 +3964,7 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
+ void __user *src, unsigned long count)
+ {
+ struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
+ return -EINVAL;
+@@ -3982,7 +3982,7 @@ static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream,
+ void *src, unsigned long count)
+ {
+ struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
+ if (snd_BUG_ON(!channel_buf))
+@@ -3996,7 +3996,7 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
+ void __user *dst, unsigned long count)
+ {
+ struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
+ return -EINVAL;
+@@ -4014,7 +4014,7 @@ static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream,
+ void *dst, unsigned long count)
+ {
+ struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
+ if (snd_BUG_ON(!channel_buf))
+@@ -4028,7 +4028,7 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,
+ unsigned long count)
+ {
+ struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
+ if (snd_BUG_ON(!channel_buf))
+diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
+index 1d614fe89a6ae..e7c320afefe86 100644
+--- a/sound/pci/rme9652/rme9652.c
++++ b/sound/pci/rme9652/rme9652.c
+@@ -230,7 +230,7 @@ struct snd_rme9652 {
+ int last_spdif_sample_rate; /* so that we can catch externally ... */
+ int last_adat_sample_rate; /* ... induced rate changes */
+
+- const char *channel_map;
++ const signed char *channel_map;
+
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+@@ -247,12 +247,12 @@ struct snd_rme9652 {
+ where the data for that channel can be read/written from/to.
+ */
+
+-static const char channel_map_9652_ss[26] = {
++static const signed char channel_map_9652_ss[26] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25
+ };
+
+-static const char channel_map_9636_ss[26] = {
++static const signed char channel_map_9636_ss[26] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ /* channels 16 and 17 are S/PDIF */
+ 24, 25,
+@@ -260,7 +260,7 @@ static const char channel_map_9636_ss[26] = {
+ -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+-static const char channel_map_9652_ds[26] = {
++static const signed char channel_map_9652_ds[26] = {
+ /* ADAT channels are remapped */
+ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
+ /* channels 12 and 13 are S/PDIF */
+@@ -269,7 +269,7 @@ static const char channel_map_9652_ds[26] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+-static const char channel_map_9636_ds[26] = {
++static const signed char channel_map_9636_ds[26] = {
+ /* ADAT channels are remapped */
+ 1, 3, 5, 7, 9, 11, 13, 15,
+ /* channels 8 and 9 are S/PDIF */
+@@ -1819,7 +1819,7 @@ static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substr
+ return rme9652_hw_pointer(rme9652);
+ }
+
+-static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
++static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
+ int stream,
+ int channel)
+
+@@ -1847,7 +1847,7 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
+ void __user *src, unsigned long count)
+ {
+ struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
+ return -EINVAL;
+@@ -1867,7 +1867,7 @@ static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
+ void *src, unsigned long count)
+ {
+ struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = rme9652_channel_buffer_location(rme9652,
+ substream->pstr->stream,
+@@ -1883,7 +1883,7 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
+ void __user *dst, unsigned long count)
+ {
+ struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
+ return -EINVAL;
+@@ -1903,7 +1903,7 @@ static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
+ void *dst, unsigned long count)
+ {
+ struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = rme9652_channel_buffer_location(rme9652,
+ substream->pstr->stream,
+@@ -1919,7 +1919,7 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
+ unsigned long count)
+ {
+ struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+- char *channel_buf;
++ signed char *channel_buf;
+
+ channel_buf = rme9652_channel_buffer_location (rme9652,
+ substream->pstr->stream,
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index d16b4efb88a77..932f08549788a 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -1599,6 +1599,7 @@ config SND_SOC_TFA989X
+ config SND_SOC_TLV320ADC3XXX
+ tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
+ depends on I2C
++ depends on GPIOLIB
+ help
+ Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
+ ADCs.
+diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c
+index 748998e48af97..8a0965cd3e667 100644
+--- a/sound/soc/codecs/tlv320adc3xxx.c
++++ b/sound/soc/codecs/tlv320adc3xxx.c
+@@ -1450,7 +1450,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
+ .of_match_table = tlv320adc3xxx_of_match,
+ },
+ .probe_new = adc3xxx_i2c_probe,
+- .remove = adc3xxx_i2c_remove,
++ .remove = __exit_p(adc3xxx_i2c_remove),
+ .id_table = adc3xxx_i2c_id,
+ };
+
+diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
+index 8ca8f872ec80c..41054cf09ec9d 100644
+--- a/sound/soc/intel/common/Makefile
++++ b/sound/soc/intel/common/Makefile
+@@ -9,7 +9,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
+ soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \
+ soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \
+ soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \
+- soc-acpi-intel-mtl-match.o \
++ soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \
+ soc-acpi-intel-hda-match.o \
+ soc-acpi-intel-sdw-mockup-match.o
+
+diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+new file mode 100644
+index 0000000000000..0b77401e4e6f9
+--- /dev/null
++++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+@@ -0,0 +1,51 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * soc-apci-intel-rpl-match.c - tables and support for RPL ACPI enumeration.
++ *
++ * Copyright (c) 2022 Intel Corporation.
++ */
++
++#include <sound/soc-acpi.h>
++#include <sound/soc-acpi-intel-match.h>
++
++static const struct snd_soc_acpi_endpoint single_endpoint = {
++ .num = 0,
++ .aggregated = 0,
++ .group_position = 0,
++ .group_id = 0,
++};
++
++static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
++ {
++ .adr = 0x000020025D071100ull,
++ .num_endpoints = 1,
++ .endpoints = &single_endpoint,
++ .name_prefix = "rt711"
++ }
++};
++
++static const struct snd_soc_acpi_link_adr rpl_rvp[] = {
++ {
++ .mask = BIT(0),
++ .num_adr = ARRAY_SIZE(rt711_0_adr),
++ .adr_d = rt711_0_adr,
++ },
++ {}
++};
++
++struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = {
++ {},
++};
++EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines);
++
++/* this table is used when there is no I2S codec present */
++struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
++ {
++ .link_mask = 0x1, /* link0 required */
++ .links = rpl_rvp,
++ .drv_name = "sof_sdw",
++ .sof_tplg_filename = "sof-rpl-rt711.tplg",
++ },
++ {},
++};
++EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_sdw_machines);
+diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
+index 8a56f38dc7e86..54353842dc07f 100644
+--- a/sound/soc/qcom/lpass-cpu.c
++++ b/sound/soc/qcom/lpass-cpu.c
+@@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
+ return true;
+ if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
+ return true;
++ if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
++ return true;
++ if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
++ return true;
+
+ for (i = 0; i < v->hdmi_rdma_channels; ++i) {
+ if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
+ return true;
++ if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
++ return true;
++ if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
++ return true;
++ if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
++ return true;
+ }
+ return false;
+ }
+diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c
+index 899b00d53d64f..9f39da984e9fa 100644
+--- a/sound/soc/sof/intel/pci-mtl.c
++++ b/sound/soc/sof/intel/pci-mtl.c
+@@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
+ [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
+ },
+ .default_fw_filename = {
+- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
++ [SOF_INTEL_IPC4] = "sof-mtl.ri",
+ },
+ .nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
+ .ops = &sof_mtl_ops,
+diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c
+index ccc44ba3ad94d..4644a78bc95d2 100644
+--- a/sound/soc/sof/intel/pci-tgl.c
++++ b/sound/soc/sof/intel/pci-tgl.c
+@@ -159,6 +159,90 @@ static const struct sof_dev_desc adl_desc = {
+ .ops_init = sof_tgl_ops_init,
+ };
+
++static const struct sof_dev_desc adl_n_desc = {
++ .machines = snd_soc_acpi_intel_adl_machines,
++ .alt_machines = snd_soc_acpi_intel_adl_sdw_machines,
++ .use_acpi_target_states = true,
++ .resindex_lpe_base = 0,
++ .resindex_pcicfg_base = -1,
++ .resindex_imr_base = -1,
++ .irqindex_host_ipc = -1,
++ .chip_info = &tgl_chip_info,
++ .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++ .ipc_default = SOF_IPC,
++ .default_fw_path = {
++ [SOF_IPC] = "intel/sof",
++ [SOF_INTEL_IPC4] = "intel/avs/adl-n",
++ },
++ .default_tplg_path = {
++ [SOF_IPC] = "intel/sof-tplg",
++ [SOF_INTEL_IPC4] = "intel/avs-tplg",
++ },
++ .default_fw_filename = {
++ [SOF_IPC] = "sof-adl-n.ri",
++ [SOF_INTEL_IPC4] = "dsp_basefw.bin",
++ },
++ .nocodec_tplg_filename = "sof-adl-nocodec.tplg",
++ .ops = &sof_tgl_ops,
++ .ops_init = sof_tgl_ops_init,
++};
++
++static const struct sof_dev_desc rpls_desc = {
++ .machines = snd_soc_acpi_intel_rpl_machines,
++ .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines,
++ .use_acpi_target_states = true,
++ .resindex_lpe_base = 0,
++ .resindex_pcicfg_base = -1,
++ .resindex_imr_base = -1,
++ .irqindex_host_ipc = -1,
++ .chip_info = &adls_chip_info,
++ .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++ .ipc_default = SOF_IPC,
++ .default_fw_path = {
++ [SOF_IPC] = "intel/sof",
++ [SOF_INTEL_IPC4] = "intel/avs/rpl-s",
++ },
++ .default_tplg_path = {
++ [SOF_IPC] = "intel/sof-tplg",
++ [SOF_INTEL_IPC4] = "intel/avs-tplg",
++ },
++ .default_fw_filename = {
++ [SOF_IPC] = "sof-rpl-s.ri",
++ [SOF_INTEL_IPC4] = "dsp_basefw.bin",
++ },
++ .nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
++ .ops = &sof_tgl_ops,
++ .ops_init = sof_tgl_ops_init,
++};
++
++static const struct sof_dev_desc rpl_desc = {
++ .machines = snd_soc_acpi_intel_rpl_machines,
++ .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines,
++ .use_acpi_target_states = true,
++ .resindex_lpe_base = 0,
++ .resindex_pcicfg_base = -1,
++ .resindex_imr_base = -1,
++ .irqindex_host_ipc = -1,
++ .chip_info = &tgl_chip_info,
++ .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++ .ipc_default = SOF_IPC,
++ .default_fw_path = {
++ [SOF_IPC] = "intel/sof",
++ [SOF_INTEL_IPC4] = "intel/avs/rpl",
++ },
++ .default_tplg_path = {
++ [SOF_IPC] = "intel/sof-tplg",
++ [SOF_INTEL_IPC4] = "intel/avs-tplg",
++ },
++ .default_fw_filename = {
++ [SOF_IPC] = "sof-rpl.ri",
++ [SOF_INTEL_IPC4] = "dsp_basefw.bin",
++ },
++ .nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
++ .ops = &sof_tgl_ops,
++ .ops_init = sof_tgl_ops_init,
++};
++
+ /* PCI IDs */
+ static const struct pci_device_id sof_pci_ids[] = {
+ { PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */
+@@ -172,7 +256,7 @@ static const struct pci_device_id sof_pci_ids[] = {
+ { PCI_DEVICE(0x8086, 0x7ad0), /* ADL-S */
+ .driver_data = (unsigned long)&adls_desc},
+ { PCI_DEVICE(0x8086, 0x7a50), /* RPL-S */
+- .driver_data = (unsigned long)&adls_desc},
++ .driver_data = (unsigned long)&rpls_desc},
+ { PCI_DEVICE(0x8086, 0x51c8), /* ADL-P */
+ .driver_data = (unsigned long)&adl_desc},
+ { PCI_DEVICE(0x8086, 0x51cd), /* ADL-P */
+@@ -180,13 +264,13 @@ static const struct pci_device_id sof_pci_ids[] = {
+ { PCI_DEVICE(0x8086, 0x51c9), /* ADL-PS */
+ .driver_data = (unsigned long)&adl_desc},
+ { PCI_DEVICE(0x8086, 0x51ca), /* RPL-P */
+- .driver_data = (unsigned long)&adl_desc},
++ .driver_data = (unsigned long)&rpl_desc},
+ { PCI_DEVICE(0x8086, 0x51cb), /* RPL-P */
+- .driver_data = (unsigned long)&adl_desc},
++ .driver_data = (unsigned long)&rpl_desc},
+ { PCI_DEVICE(0x8086, 0x51cc), /* ADL-M */
+ .driver_data = (unsigned long)&adl_desc},
+ { PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
+- .driver_data = (unsigned long)&adl_desc},
++ .driver_data = (unsigned long)&adl_n_desc},
+ { 0, }
+ };
+ MODULE_DEVICE_TABLE(pci, sof_pci_ids);
+diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
+index 5ed8e36d2e043..a870759d179ed 100644
+--- a/sound/synth/emux/emux.c
++++ b/sound/synth/emux/emux.c
+@@ -126,15 +126,10 @@ EXPORT_SYMBOL(snd_emux_register);
+ */
+ int snd_emux_free(struct snd_emux *emu)
+ {
+- unsigned long flags;
+-
+ if (! emu)
+ return -EINVAL;
+
+- spin_lock_irqsave(&emu->voice_lock, flags);
+- if (emu->timer_active)
+- del_timer(&emu->tlist);
+- spin_unlock_irqrestore(&emu->voice_lock, flags);
++ del_timer_sync(&emu->tlist);
+
+ snd_emux_proc_free(emu);
+ snd_emux_delete_virmidi(emu);
+diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c
+index e1bf1b5da423c..f3e8484b3d9cb 100644
+--- a/sound/usb/implicit.c
++++ b/sound/usb/implicit.c
+@@ -47,6 +47,8 @@ struct snd_usb_implicit_fb_match {
+ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
+ /* Fixed EP */
+ /* FIXME: check the availability of generic matching */
++ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */
++ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */
+ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */
+ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */
+ IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index a5641956ef102..9105ec623120a 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -1631,7 +1631,7 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
+ if (!found)
+ return;
+
+- strscpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
++ snd_ctl_rename(card, kctl, "Headphone");
+ }
+
+ static const struct usb_feature_control_info *get_feature_control_info(int control)
+diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c
+index aadee6d34c74c..8d35893b2fa85 100644
+--- a/tools/iio/iio_utils.c
++++ b/tools/iio/iio_utils.c
+@@ -547,6 +547,10 @@ static int calc_digits(int num)
+ {
+ int count = 0;
+
++ /* It takes a digit to represent zero */
++ if (!num)
++ return 1;
++
+ while (num != 0) {
+ num /= 10;
+ count++;
+diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
+index 6970203cb2470..6443a061e22a1 100644
+--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
++++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
+@@ -112,21 +112,21 @@
+ "MetricName": "indirect_branch"
+ },
+ {
+- "MetricExpr": "(armv8_pmuv3_0@event\\=0x1014@ + armv8_pmuv3_0@event\\=0x1018@) / BR_MIS_PRED",
++ "MetricExpr": "(armv8_pmuv3_0@event\\=0x1013@ + armv8_pmuv3_0@event\\=0x1016@) / BR_MIS_PRED",
+ "PublicDescription": "Push branch L3 topdown metric",
+ "BriefDescription": "Push branch L3 topdown metric",
+ "MetricGroup": "TopDownL3",
+ "MetricName": "push_branch"
+ },
+ {
+- "MetricExpr": "armv8_pmuv3_0@event\\=0x100c@ / BR_MIS_PRED",
++ "MetricExpr": "armv8_pmuv3_0@event\\=0x100d@ / BR_MIS_PRED",
+ "PublicDescription": "Pop branch L3 topdown metric",
+ "BriefDescription": "Pop branch L3 topdown metric",
+ "MetricGroup": "TopDownL3",
+ "MetricName": "pop_branch"
+ },
+ {
+- "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1014@ - armv8_pmuv3_0@event\\=0x1018@ - armv8_pmuv3_0@event\\=0x100c@) / BR_MIS_PRED",
++ "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1013@ - armv8_pmuv3_0@event\\=0x1016@ - armv8_pmuv3_0@event\\=0x100d@) / BR_MIS_PRED",
+ "PublicDescription": "Other branch L3 topdown metric",
+ "BriefDescription": "Other branch L3 topdown metric",
+ "MetricGroup": "TopDownL3",
+diff --git a/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
+index 8ba3e81c9808b..fe050d44374ba 100644
+--- a/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
++++ b/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
+@@ -1,13 +1,13 @@
+ [
+ {
+ "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P01",
+- "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@) * 100",
++ "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P23",
+- "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@) * 100",
++ "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+@@ -61,13 +61,13 @@
+ },
+ {
+ "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P01",
+- "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@) * 100",
++ "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P23",
+- "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@) * 100",
++ "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+@@ -151,193 +151,193 @@
+ },
+ {
+ "MetricName": "XLINK0_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK1_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK2_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK3_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK4_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK5_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK6_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK7_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK0_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK1_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK2_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK3_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK4_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK5_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK6_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "XLINK7_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK0_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK1_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK2_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK3_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK4_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK5_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK6_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK7_OUT_TOTAL_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK0_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK1_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK2_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK3_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK4_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK5_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK6_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+ {
+ "MetricName": "ALINK7_OUT_DATA_UTILIZATION",
+- "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++ "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+ "ScaleUnit": "1.063%",
+ "AggregationMode": "PerChip"
+ },
+diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/pai.json b/tools/perf/pmu-events/arch/s390/cf_z16/pai.json
+deleted file mode 100644
+index cf8563d059b9e..0000000000000
+--- a/tools/perf/pmu-events/arch/s390/cf_z16/pai.json
++++ /dev/null
+@@ -1,1101 +0,0 @@
+-[
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4096",
+- "EventName": "CRYPTO_ALL",
+- "BriefDescription": "CRYPTO ALL",
+- "PublicDescription": "Sums of all non zero cryptography counters"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4097",
+- "EventName": "KM_DEA",
+- "BriefDescription": "KM DEA",
+- "PublicDescription": "KM-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4098",
+- "EventName": "KM_TDEA_128",
+- "BriefDescription": "KM TDEA 128",
+- "PublicDescription": "KM-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4099",
+- "EventName": "KM_TDEA_192",
+- "BriefDescription": "KM TDEA 192",
+- "PublicDescription": "KM-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4100",
+- "EventName": "KM_ENCRYPTED_DEA",
+- "BriefDescription": "KM ENCRYPTED DEA",
+- "PublicDescription": "KM-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4101",
+- "EventName": "KM_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KM ENCRYPTED TDEA 128",
+- "PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4102",
+- "EventName": "KM_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KM ENCRYPTED TDEA 192",
+- "PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4103",
+- "EventName": "KM_AES_128",
+- "BriefDescription": "KM AES 128",
+- "PublicDescription": "KM-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4104",
+- "EventName": "KM_AES_192",
+- "BriefDescription": "KM AES 192",
+- "PublicDescription": "KM-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4105",
+- "EventName": "KM_AES_256",
+- "BriefDescription": "KM AES 256",
+- "PublicDescription": "KM-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4106",
+- "EventName": "KM_ENCRYPTED_AES_128",
+- "BriefDescription": "KM ENCRYPTED AES 128",
+- "PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4107",
+- "EventName": "KM_ENCRYPTED_AES_192",
+- "BriefDescription": "KM ENCRYPTED AES 192",
+- "PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4108",
+- "EventName": "KM_ENCRYPTED_AES_256",
+- "BriefDescription": "KM ENCRYPTED AES 256",
+- "PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4109",
+- "EventName": "KM_XTS_AES_128",
+- "BriefDescription": "KM XTS AES 128",
+- "PublicDescription": "KM-XTS-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4110",
+- "EventName": "KM_XTS_AES_256",
+- "BriefDescription": "KM XTS AES 256",
+- "PublicDescription": "KM-XTS-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4111",
+- "EventName": "KM_XTS_ENCRYPTED_AES_128",
+- "BriefDescription": "KM XTS ENCRYPTED AES 128",
+- "PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4112",
+- "EventName": "KM_XTS_ENCRYPTED_AES_256",
+- "BriefDescription": "KM XTS ENCRYPTED AES 256",
+- "PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4113",
+- "EventName": "KMC_DEA",
+- "BriefDescription": "KMC DEA",
+- "PublicDescription": "KMC-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4114",
+- "EventName": "KMC_TDEA_128",
+- "BriefDescription": "KMC TDEA 128",
+- "PublicDescription": "KMC-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4115",
+- "EventName": "KMC_TDEA_192",
+- "BriefDescription": "KMC TDEA 192",
+- "PublicDescription": "KMC-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4116",
+- "EventName": "KMC_ENCRYPTED_DEA",
+- "BriefDescription": "KMC ENCRYPTED DEA",
+- "PublicDescription": "KMC-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4117",
+- "EventName": "KMC_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KMC ENCRYPTED TDEA 128",
+- "PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4118",
+- "EventName": "KMC_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KMC ENCRYPTED TDEA 192",
+- "PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4119",
+- "EventName": "KMC_AES_128",
+- "BriefDescription": "KMC AES 128",
+- "PublicDescription": "KMC-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4120",
+- "EventName": "KMC_AES_192",
+- "BriefDescription": "KMC AES 192",
+- "PublicDescription": "KMC-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4121",
+- "EventName": "KMC_AES_256",
+- "BriefDescription": "KMC AES 256",
+- "PublicDescription": "KMC-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4122",
+- "EventName": "KMC_ENCRYPTED_AES_128",
+- "BriefDescription": "KMC ENCRYPTED AES 128",
+- "PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4123",
+- "EventName": "KMC_ENCRYPTED_AES_192",
+- "BriefDescription": "KMC ENCRYPTED AES 192",
+- "PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4124",
+- "EventName": "KMC_ENCRYPTED_AES_256",
+- "BriefDescription": "KMC ENCRYPTED AES 256",
+- "PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4125",
+- "EventName": "KMC_PRNG",
+- "BriefDescription": "KMC PRNG",
+- "PublicDescription": "KMC-PRNG function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4126",
+- "EventName": "KMA_GCM_AES_128",
+- "BriefDescription": "KMA GCM AES 128",
+- "PublicDescription": "KMA-GCM-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4127",
+- "EventName": "KMA_GCM_AES_192",
+- "BriefDescription": "KMA GCM AES 192",
+- "PublicDescription": "KMA-GCM-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4128",
+- "EventName": "KMA_GCM_AES_256",
+- "BriefDescription": "KMA GCM AES 256",
+- "PublicDescription": "KMA-GCM-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4129",
+- "EventName": "KMA_GCM_ENCRYPTED_AES_128",
+- "BriefDescription": "KMA GCM ENCRYPTED AES 128",
+- "PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4130",
+- "EventName": "KMA_GCM_ENCRYPTED_AES_192",
+- "BriefDescription": "KMA GCM ENCRYPTED AES 192",
+- "PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4131",
+- "EventName": "KMA_GCM_ENCRYPTED_AES_256",
+- "BriefDescription": "KMA GCM ENCRYPTED AES 256",
+- "PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4132",
+- "EventName": "KMF_DEA",
+- "BriefDescription": "KMF DEA",
+- "PublicDescription": "KMF-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4133",
+- "EventName": "KMF_TDEA_128",
+- "BriefDescription": "KMF TDEA 128",
+- "PublicDescription": "KMF-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4134",
+- "EventName": "KMF_TDEA_192",
+- "BriefDescription": "KMF TDEA 192",
+- "PublicDescription": "KMF-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4135",
+- "EventName": "KMF_ENCRYPTED_DEA",
+- "BriefDescription": "KMF ENCRYPTED DEA",
+- "PublicDescription": "KMF-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4136",
+- "EventName": "KMF_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KMF ENCRYPTED TDEA 128",
+- "PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4137",
+- "EventName": "KMF_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KMF ENCRYPTED TDEA 192",
+- "PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4138",
+- "EventName": "KMF_AES_128",
+- "BriefDescription": "KMF AES 128",
+- "PublicDescription": "KMF-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4139",
+- "EventName": "KMF_AES_192",
+- "BriefDescription": "KMF AES 192",
+- "PublicDescription": "KMF-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4140",
+- "EventName": "KMF_AES_256",
+- "BriefDescription": "KMF AES 256",
+- "PublicDescription": "KMF-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4141",
+- "EventName": "KMF_ENCRYPTED_AES_128",
+- "BriefDescription": "KMF ENCRYPTED AES 128",
+- "PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4142",
+- "EventName": "KMF_ENCRYPTED_AES_192",
+- "BriefDescription": "KMF ENCRYPTED AES 192",
+- "PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4143",
+- "EventName": "KMF_ENCRYPTED_AES_256",
+- "BriefDescription": "KMF ENCRYPTED AES 256",
+- "PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4144",
+- "EventName": "KMCTR_DEA",
+- "BriefDescription": "KMCTR DEA",
+- "PublicDescription": "KMCTR-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4145",
+- "EventName": "KMCTR_TDEA_128",
+- "BriefDescription": "KMCTR TDEA 128",
+- "PublicDescription": "KMCTR-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4146",
+- "EventName": "KMCTR_TDEA_192",
+- "BriefDescription": "KMCTR TDEA 192",
+- "PublicDescription": "KMCTR-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4147",
+- "EventName": "KMCTR_ENCRYPTED_DEA",
+- "BriefDescription": "KMCTR ENCRYPTED DEA",
+- "PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4148",
+- "EventName": "KMCTR_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KMCTR ENCRYPTED TDEA 128",
+- "PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4149",
+- "EventName": "KMCTR_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KMCTR ENCRYPTED TDEA 192",
+- "PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4150",
+- "EventName": "KMCTR_AES_128",
+- "BriefDescription": "KMCTR AES 128",
+- "PublicDescription": "KMCTR-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4151",
+- "EventName": "KMCTR_AES_192",
+- "BriefDescription": "KMCTR AES 192",
+- "PublicDescription": "KMCTR-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4152",
+- "EventName": "KMCTR_AES_256",
+- "BriefDescription": "KMCTR AES 256",
+- "PublicDescription": "KMCTR-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4153",
+- "EventName": "KMCTR_ENCRYPTED_AES_128",
+- "BriefDescription": "KMCTR ENCRYPTED AES 128",
+- "PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4154",
+- "EventName": "KMCTR_ENCRYPTED_AES_192",
+- "BriefDescription": "KMCTR ENCRYPTED AES 192",
+- "PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4155",
+- "EventName": "KMCTR_ENCRYPTED_AES_256",
+- "BriefDescription": "KMCTR ENCRYPTED AES 256",
+- "PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4156",
+- "EventName": "KMO_DEA",
+- "BriefDescription": "KMO DEA",
+- "PublicDescription": "KMO-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4157",
+- "EventName": "KMO_TDEA_128",
+- "BriefDescription": "KMO TDEA 128",
+- "PublicDescription": "KMO-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4158",
+- "EventName": "KMO_TDEA_192",
+- "BriefDescription": "KMO TDEA 192",
+- "PublicDescription": "KMO-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4159",
+- "EventName": "KMO_ENCRYPTED_DEA",
+- "BriefDescription": "KMO ENCRYPTED DEA",
+- "PublicDescription": "KMO-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4160",
+- "EventName": "KMO_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KMO ENCRYPTED TDEA 128",
+- "PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4161",
+- "EventName": "KMO_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KMO ENCRYPTED TDEA 192",
+- "PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4162",
+- "EventName": "KMO_AES_128",
+- "BriefDescription": "KMO AES 128",
+- "PublicDescription": "KMO-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4163",
+- "EventName": "KMO_AES_192",
+- "BriefDescription": "KMO AES 192",
+- "PublicDescription": "KMO-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4164",
+- "EventName": "KMO_AES_256",
+- "BriefDescription": "KMO AES 256",
+- "PublicDescription": "KMO-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4165",
+- "EventName": "KMO_ENCRYPTED_AES_128",
+- "BriefDescription": "KMO ENCRYPTED AES 128",
+- "PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4166",
+- "EventName": "KMO_ENCRYPTED_AES_192",
+- "BriefDescription": "KMO ENCRYPTED AES 192",
+- "PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4167",
+- "EventName": "KMO_ENCRYPTED_AES_256",
+- "BriefDescription": "KMO ENCRYPTED AES 256",
+- "PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4168",
+- "EventName": "KIMD_SHA_1",
+- "BriefDescription": "KIMD SHA 1",
+- "PublicDescription": "KIMD-SHA-1 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4169",
+- "EventName": "KIMD_SHA_256",
+- "BriefDescription": "KIMD SHA 256",
+- "PublicDescription": "KIMD-SHA-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4170",
+- "EventName": "KIMD_SHA_512",
+- "BriefDescription": "KIMD SHA 512",
+- "PublicDescription": "KIMD-SHA-512 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4171",
+- "EventName": "KIMD_SHA3_224",
+- "BriefDescription": "KIMD SHA3 224",
+- "PublicDescription": "KIMD-SHA3-224 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4172",
+- "EventName": "KIMD_SHA3_256",
+- "BriefDescription": "KIMD SHA3 256",
+- "PublicDescription": "KIMD-SHA3-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4173",
+- "EventName": "KIMD_SHA3_384",
+- "BriefDescription": "KIMD SHA3 384",
+- "PublicDescription": "KIMD-SHA3-384 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4174",
+- "EventName": "KIMD_SHA3_512",
+- "BriefDescription": "KIMD SHA3 512",
+- "PublicDescription": "KIMD-SHA3-512 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4175",
+- "EventName": "KIMD_SHAKE_128",
+- "BriefDescription": "KIMD SHAKE 128",
+- "PublicDescription": "KIMD-SHAKE-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4176",
+- "EventName": "KIMD_SHAKE_256",
+- "BriefDescription": "KIMD SHAKE 256",
+- "PublicDescription": "KIMD-SHAKE-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4177",
+- "EventName": "KIMD_GHASH",
+- "BriefDescription": "KIMD GHASH",
+- "PublicDescription": "KIMD-GHASH function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4178",
+- "EventName": "KLMD_SHA_1",
+- "BriefDescription": "KLMD SHA 1",
+- "PublicDescription": "KLMD-SHA-1 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4179",
+- "EventName": "KLMD_SHA_256",
+- "BriefDescription": "KLMD SHA 256",
+- "PublicDescription": "KLMD-SHA-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4180",
+- "EventName": "KLMD_SHA_512",
+- "BriefDescription": "KLMD SHA 512",
+- "PublicDescription": "KLMD-SHA-512 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4181",
+- "EventName": "KLMD_SHA3_224",
+- "BriefDescription": "KLMD SHA3 224",
+- "PublicDescription": "KLMD-SHA3-224 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4182",
+- "EventName": "KLMD_SHA3_256",
+- "BriefDescription": "KLMD SHA3 256",
+- "PublicDescription": "KLMD-SHA3-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4183",
+- "EventName": "KLMD_SHA3_384",
+- "BriefDescription": "KLMD SHA3 384",
+- "PublicDescription": "KLMD-SHA3-384 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4184",
+- "EventName": "KLMD_SHA3_512",
+- "BriefDescription": "KLMD SHA3 512",
+- "PublicDescription": "KLMD-SHA3-512 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4185",
+- "EventName": "KLMD_SHAKE_128",
+- "BriefDescription": "KLMD SHAKE 128",
+- "PublicDescription": "KLMD-SHAKE-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4186",
+- "EventName": "KLMD_SHAKE_256",
+- "BriefDescription": "KLMD SHAKE 256",
+- "PublicDescription": "KLMD-SHAKE-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4187",
+- "EventName": "KMAC_DEA",
+- "BriefDescription": "KMAC DEA",
+- "PublicDescription": "KMAC-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4188",
+- "EventName": "KMAC_TDEA_128",
+- "BriefDescription": "KMAC TDEA 128",
+- "PublicDescription": "KMAC-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4189",
+- "EventName": "KMAC_TDEA_192",
+- "BriefDescription": "KMAC TDEA 192",
+- "PublicDescription": "KMAC-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4190",
+- "EventName": "KMAC_ENCRYPTED_DEA",
+- "BriefDescription": "KMAC ENCRYPTED DEA",
+- "PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4191",
+- "EventName": "KMAC_ENCRYPTED_TDEA_128",
+- "BriefDescription": "KMAC ENCRYPTED TDEA 128",
+- "PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4192",
+- "EventName": "KMAC_ENCRYPTED_TDEA_192",
+- "BriefDescription": "KMAC ENCRYPTED TDEA 192",
+- "PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4193",
+- "EventName": "KMAC_AES_128",
+- "BriefDescription": "KMAC AES 128",
+- "PublicDescription": "KMAC-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4194",
+- "EventName": "KMAC_AES_192",
+- "BriefDescription": "KMAC AES 192",
+- "PublicDescription": "KMAC-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4195",
+- "EventName": "KMAC_AES_256",
+- "BriefDescription": "KMAC AES 256",
+- "PublicDescription": "KMAC-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4196",
+- "EventName": "KMAC_ENCRYPTED_AES_128",
+- "BriefDescription": "KMAC ENCRYPTED AES 128",
+- "PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4197",
+- "EventName": "KMAC_ENCRYPTED_AES_192",
+- "BriefDescription": "KMAC ENCRYPTED AES 192",
+- "PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4198",
+- "EventName": "KMAC_ENCRYPTED_AES_256",
+- "BriefDescription": "KMAC ENCRYPTED AES 256",
+- "PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4199",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4200",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4201",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4202",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4203",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4204",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4205",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4206",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4207",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4208",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4209",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4210",
+- "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A",
+- "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A",
+- "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4211",
+- "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128",
+- "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128",
+- "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4212",
+- "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256",
+- "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256",
+- "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4213",
+- "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128",
+- "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128",
+- "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4214",
+- "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256",
+- "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256",
+- "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4215",
+- "EventName": "PCC_SCALAR_MULTIPLY_P256",
+- "BriefDescription": "PCC SCALAR MULTIPLY P256",
+- "PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4216",
+- "EventName": "PCC_SCALAR_MULTIPLY_P384",
+- "BriefDescription": "PCC SCALAR MULTIPLY P384",
+- "PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4217",
+- "EventName": "PCC_SCALAR_MULTIPLY_P521",
+- "BriefDescription": "PCC SCALAR MULTIPLY P521",
+- "PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4218",
+- "EventName": "PCC_SCALAR_MULTIPLY_ED25519",
+- "BriefDescription": "PCC SCALAR MULTIPLY ED25519",
+- "PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4219",
+- "EventName": "PCC_SCALAR_MULTIPLY_ED448",
+- "BriefDescription": "PCC SCALAR MULTIPLY ED448",
+- "PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4220",
+- "EventName": "PCC_SCALAR_MULTIPLY_X25519",
+- "BriefDescription": "PCC SCALAR MULTIPLY X25519",
+- "PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4221",
+- "EventName": "PCC_SCALAR_MULTIPLY_X448",
+- "BriefDescription": "PCC SCALAR MULTIPLY X448",
+- "PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4222",
+- "EventName": "PRNO_SHA_512_DRNG",
+- "BriefDescription": "PRNO SHA 512 DRNG",
+- "PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4223",
+- "EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO",
+- "BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO",
+- "PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4224",
+- "EventName": "PRNO_TRNG",
+- "BriefDescription": "PRNO TRNG",
+- "PublicDescription": "PRNO-TRNG function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4225",
+- "EventName": "KDSA_ECDSA_VERIFY_P256",
+- "BriefDescription": "KDSA ECDSA VERIFY P256",
+- "PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4226",
+- "EventName": "KDSA_ECDSA_VERIFY_P384",
+- "BriefDescription": "KDSA ECDSA VERIFY P384",
+- "PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4227",
+- "EventName": "KDSA_ECDSA_VERIFY_P521",
+- "BriefDescription": "KDSA ECDSA VERIFY P521",
+- "PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4228",
+- "EventName": "KDSA_ECDSA_SIGN_P256",
+- "BriefDescription": "KDSA ECDSA SIGN P256",
+- "PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4229",
+- "EventName": "KDSA_ECDSA_SIGN_P384",
+- "BriefDescription": "KDSA ECDSA SIGN P384",
+- "PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4230",
+- "EventName": "KDSA_ECDSA_SIGN_P521",
+- "BriefDescription": "KDSA ECDSA SIGN P521",
+- "PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4231",
+- "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256",
+- "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256",
+- "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4232",
+- "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384",
+- "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384",
+- "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4233",
+- "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521",
+- "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521",
+- "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4234",
+- "EventName": "KDSA_EDDSA_VERIFY_ED25519",
+- "BriefDescription": "KDSA EDDSA VERIFY ED25519",
+- "PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4235",
+- "EventName": "KDSA_EDDSA_VERIFY_ED448",
+- "BriefDescription": "KDSA EDDSA VERIFY ED448",
+- "PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4236",
+- "EventName": "KDSA_EDDSA_SIGN_ED25519",
+- "BriefDescription": "KDSA EDDSA SIGN ED25519",
+- "PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4237",
+- "EventName": "KDSA_EDDSA_SIGN_ED448",
+- "BriefDescription": "KDSA EDDSA SIGN ED448",
+- "PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4238",
+- "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519",
+- "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519",
+- "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4239",
+- "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448",
+- "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448",
+- "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4240",
+- "EventName": "PCKMO_ENCRYPT_DEA_KEY",
+- "BriefDescription": "PCKMO ENCRYPT DEA KEY",
+- "PublicDescription": "PCKMO-Encrypt-DEA-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4241",
+- "EventName": "PCKMO_ENCRYPT_TDEA_128_KEY",
+- "BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY",
+- "PublicDescription": "PCKMO-Encrypt-TDEA-128-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4242",
+- "EventName": "PCKMO_ENCRYPT_TDEA_192_KEY",
+- "BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY",
+- "PublicDescription": "PCKMO-Encrypt-TDEA-192-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4243",
+- "EventName": "PCKMO_ENCRYPT_AES_128_KEY",
+- "BriefDescription": "PCKMO ENCRYPT AES 128 KEY",
+- "PublicDescription": "PCKMO-Encrypt-AES-128-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4244",
+- "EventName": "PCKMO_ENCRYPT_AES_192_KEY",
+- "BriefDescription": "PCKMO ENCRYPT AES 192 KEY",
+- "PublicDescription": "PCKMO-Encrypt-AES-192-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4245",
+- "EventName": "PCKMO_ENCRYPT_AES_256_KEY",
+- "BriefDescription": "PCKMO ENCRYPT AES 256 KEY",
+- "PublicDescription": "PCKMO-Encrypt-AES-256-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4246",
+- "EventName": "PCKMO_ENCRYPT_ECC_P256_KEY",
+- "BriefDescription": "PCKMO ENCRYPT ECC P256 KEY",
+- "PublicDescription": "PCKMO-Encrypt-ECC-P256-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4247",
+- "EventName": "PCKMO_ENCRYPT_ECC_P384_KEY",
+- "BriefDescription": "PCKMO ENCRYPT ECC P384 KEY",
+- "PublicDescription": "PCKMO-Encrypt-ECC-P384-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4248",
+- "EventName": "PCKMO_ENCRYPT_ECC_P521_KEY",
+- "BriefDescription": "PCKMO ENCRYPT ECC P521 KEY",
+- "PublicDescription": "PCKMO-Encrypt-ECC-P521-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4249",
+- "EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY",
+- "BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY",
+- "PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4250",
+- "EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY",
+- "BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY",
+- "PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4251",
+- "EventName": "IBM_RESERVED_155",
+- "BriefDescription": "IBM RESERVED_155",
+- "PublicDescription": "Reserved for IBM use"
+- },
+- {
+- "Unit": "PAI-CRYPTO",
+- "EventCode": "4252",
+- "EventName": "IBM_RESERVED_156",
+- "BriefDescription": "IBM RESERVED_156",
+- "PublicDescription": "Reserved for IBM use"
+- }
+-]
+diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json b/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json
+new file mode 100644
+index 0000000000000..cf8563d059b9e
+--- /dev/null
++++ b/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json
+@@ -0,0 +1,1101 @@
++[
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4096",
++ "EventName": "CRYPTO_ALL",
++ "BriefDescription": "CRYPTO ALL",
++ "PublicDescription": "Sums of all non zero cryptography counters"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4097",
++ "EventName": "KM_DEA",
++ "BriefDescription": "KM DEA",
++ "PublicDescription": "KM-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4098",
++ "EventName": "KM_TDEA_128",
++ "BriefDescription": "KM TDEA 128",
++ "PublicDescription": "KM-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4099",
++ "EventName": "KM_TDEA_192",
++ "BriefDescription": "KM TDEA 192",
++ "PublicDescription": "KM-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4100",
++ "EventName": "KM_ENCRYPTED_DEA",
++ "BriefDescription": "KM ENCRYPTED DEA",
++ "PublicDescription": "KM-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4101",
++ "EventName": "KM_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KM ENCRYPTED TDEA 128",
++ "PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4102",
++ "EventName": "KM_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KM ENCRYPTED TDEA 192",
++ "PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4103",
++ "EventName": "KM_AES_128",
++ "BriefDescription": "KM AES 128",
++ "PublicDescription": "KM-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4104",
++ "EventName": "KM_AES_192",
++ "BriefDescription": "KM AES 192",
++ "PublicDescription": "KM-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4105",
++ "EventName": "KM_AES_256",
++ "BriefDescription": "KM AES 256",
++ "PublicDescription": "KM-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4106",
++ "EventName": "KM_ENCRYPTED_AES_128",
++ "BriefDescription": "KM ENCRYPTED AES 128",
++ "PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4107",
++ "EventName": "KM_ENCRYPTED_AES_192",
++ "BriefDescription": "KM ENCRYPTED AES 192",
++ "PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4108",
++ "EventName": "KM_ENCRYPTED_AES_256",
++ "BriefDescription": "KM ENCRYPTED AES 256",
++ "PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4109",
++ "EventName": "KM_XTS_AES_128",
++ "BriefDescription": "KM XTS AES 128",
++ "PublicDescription": "KM-XTS-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4110",
++ "EventName": "KM_XTS_AES_256",
++ "BriefDescription": "KM XTS AES 256",
++ "PublicDescription": "KM-XTS-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4111",
++ "EventName": "KM_XTS_ENCRYPTED_AES_128",
++ "BriefDescription": "KM XTS ENCRYPTED AES 128",
++ "PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4112",
++ "EventName": "KM_XTS_ENCRYPTED_AES_256",
++ "BriefDescription": "KM XTS ENCRYPTED AES 256",
++ "PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4113",
++ "EventName": "KMC_DEA",
++ "BriefDescription": "KMC DEA",
++ "PublicDescription": "KMC-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4114",
++ "EventName": "KMC_TDEA_128",
++ "BriefDescription": "KMC TDEA 128",
++ "PublicDescription": "KMC-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4115",
++ "EventName": "KMC_TDEA_192",
++ "BriefDescription": "KMC TDEA 192",
++ "PublicDescription": "KMC-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4116",
++ "EventName": "KMC_ENCRYPTED_DEA",
++ "BriefDescription": "KMC ENCRYPTED DEA",
++ "PublicDescription": "KMC-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4117",
++ "EventName": "KMC_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KMC ENCRYPTED TDEA 128",
++ "PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4118",
++ "EventName": "KMC_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KMC ENCRYPTED TDEA 192",
++ "PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4119",
++ "EventName": "KMC_AES_128",
++ "BriefDescription": "KMC AES 128",
++ "PublicDescription": "KMC-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4120",
++ "EventName": "KMC_AES_192",
++ "BriefDescription": "KMC AES 192",
++ "PublicDescription": "KMC-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4121",
++ "EventName": "KMC_AES_256",
++ "BriefDescription": "KMC AES 256",
++ "PublicDescription": "KMC-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4122",
++ "EventName": "KMC_ENCRYPTED_AES_128",
++ "BriefDescription": "KMC ENCRYPTED AES 128",
++ "PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4123",
++ "EventName": "KMC_ENCRYPTED_AES_192",
++ "BriefDescription": "KMC ENCRYPTED AES 192",
++ "PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4124",
++ "EventName": "KMC_ENCRYPTED_AES_256",
++ "BriefDescription": "KMC ENCRYPTED AES 256",
++ "PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4125",
++ "EventName": "KMC_PRNG",
++ "BriefDescription": "KMC PRNG",
++ "PublicDescription": "KMC-PRNG function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4126",
++ "EventName": "KMA_GCM_AES_128",
++ "BriefDescription": "KMA GCM AES 128",
++ "PublicDescription": "KMA-GCM-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4127",
++ "EventName": "KMA_GCM_AES_192",
++ "BriefDescription": "KMA GCM AES 192",
++ "PublicDescription": "KMA-GCM-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4128",
++ "EventName": "KMA_GCM_AES_256",
++ "BriefDescription": "KMA GCM AES 256",
++ "PublicDescription": "KMA-GCM-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4129",
++ "EventName": "KMA_GCM_ENCRYPTED_AES_128",
++ "BriefDescription": "KMA GCM ENCRYPTED AES 128",
++ "PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4130",
++ "EventName": "KMA_GCM_ENCRYPTED_AES_192",
++ "BriefDescription": "KMA GCM ENCRYPTED AES 192",
++ "PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4131",
++ "EventName": "KMA_GCM_ENCRYPTED_AES_256",
++ "BriefDescription": "KMA GCM ENCRYPTED AES 256",
++ "PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4132",
++ "EventName": "KMF_DEA",
++ "BriefDescription": "KMF DEA",
++ "PublicDescription": "KMF-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4133",
++ "EventName": "KMF_TDEA_128",
++ "BriefDescription": "KMF TDEA 128",
++ "PublicDescription": "KMF-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4134",
++ "EventName": "KMF_TDEA_192",
++ "BriefDescription": "KMF TDEA 192",
++ "PublicDescription": "KMF-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4135",
++ "EventName": "KMF_ENCRYPTED_DEA",
++ "BriefDescription": "KMF ENCRYPTED DEA",
++ "PublicDescription": "KMF-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4136",
++ "EventName": "KMF_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KMF ENCRYPTED TDEA 128",
++ "PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4137",
++ "EventName": "KMF_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KMF ENCRYPTED TDEA 192",
++ "PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4138",
++ "EventName": "KMF_AES_128",
++ "BriefDescription": "KMF AES 128",
++ "PublicDescription": "KMF-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4139",
++ "EventName": "KMF_AES_192",
++ "BriefDescription": "KMF AES 192",
++ "PublicDescription": "KMF-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4140",
++ "EventName": "KMF_AES_256",
++ "BriefDescription": "KMF AES 256",
++ "PublicDescription": "KMF-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4141",
++ "EventName": "KMF_ENCRYPTED_AES_128",
++ "BriefDescription": "KMF ENCRYPTED AES 128",
++ "PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4142",
++ "EventName": "KMF_ENCRYPTED_AES_192",
++ "BriefDescription": "KMF ENCRYPTED AES 192",
++ "PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4143",
++ "EventName": "KMF_ENCRYPTED_AES_256",
++ "BriefDescription": "KMF ENCRYPTED AES 256",
++ "PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4144",
++ "EventName": "KMCTR_DEA",
++ "BriefDescription": "KMCTR DEA",
++ "PublicDescription": "KMCTR-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4145",
++ "EventName": "KMCTR_TDEA_128",
++ "BriefDescription": "KMCTR TDEA 128",
++ "PublicDescription": "KMCTR-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4146",
++ "EventName": "KMCTR_TDEA_192",
++ "BriefDescription": "KMCTR TDEA 192",
++ "PublicDescription": "KMCTR-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4147",
++ "EventName": "KMCTR_ENCRYPTED_DEA",
++ "BriefDescription": "KMCTR ENCRYPTED DEA",
++ "PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4148",
++ "EventName": "KMCTR_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KMCTR ENCRYPTED TDEA 128",
++ "PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4149",
++ "EventName": "KMCTR_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KMCTR ENCRYPTED TDEA 192",
++ "PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4150",
++ "EventName": "KMCTR_AES_128",
++ "BriefDescription": "KMCTR AES 128",
++ "PublicDescription": "KMCTR-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4151",
++ "EventName": "KMCTR_AES_192",
++ "BriefDescription": "KMCTR AES 192",
++ "PublicDescription": "KMCTR-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4152",
++ "EventName": "KMCTR_AES_256",
++ "BriefDescription": "KMCTR AES 256",
++ "PublicDescription": "KMCTR-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4153",
++ "EventName": "KMCTR_ENCRYPTED_AES_128",
++ "BriefDescription": "KMCTR ENCRYPTED AES 128",
++ "PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4154",
++ "EventName": "KMCTR_ENCRYPTED_AES_192",
++ "BriefDescription": "KMCTR ENCRYPTED AES 192",
++ "PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4155",
++ "EventName": "KMCTR_ENCRYPTED_AES_256",
++ "BriefDescription": "KMCTR ENCRYPTED AES 256",
++ "PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4156",
++ "EventName": "KMO_DEA",
++ "BriefDescription": "KMO DEA",
++ "PublicDescription": "KMO-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4157",
++ "EventName": "KMO_TDEA_128",
++ "BriefDescription": "KMO TDEA 128",
++ "PublicDescription": "KMO-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4158",
++ "EventName": "KMO_TDEA_192",
++ "BriefDescription": "KMO TDEA 192",
++ "PublicDescription": "KMO-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4159",
++ "EventName": "KMO_ENCRYPTED_DEA",
++ "BriefDescription": "KMO ENCRYPTED DEA",
++ "PublicDescription": "KMO-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4160",
++ "EventName": "KMO_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KMO ENCRYPTED TDEA 128",
++ "PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4161",
++ "EventName": "KMO_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KMO ENCRYPTED TDEA 192",
++ "PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4162",
++ "EventName": "KMO_AES_128",
++ "BriefDescription": "KMO AES 128",
++ "PublicDescription": "KMO-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4163",
++ "EventName": "KMO_AES_192",
++ "BriefDescription": "KMO AES 192",
++ "PublicDescription": "KMO-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4164",
++ "EventName": "KMO_AES_256",
++ "BriefDescription": "KMO AES 256",
++ "PublicDescription": "KMO-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4165",
++ "EventName": "KMO_ENCRYPTED_AES_128",
++ "BriefDescription": "KMO ENCRYPTED AES 128",
++ "PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4166",
++ "EventName": "KMO_ENCRYPTED_AES_192",
++ "BriefDescription": "KMO ENCRYPTED AES 192",
++ "PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4167",
++ "EventName": "KMO_ENCRYPTED_AES_256",
++ "BriefDescription": "KMO ENCRYPTED AES 256",
++ "PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4168",
++ "EventName": "KIMD_SHA_1",
++ "BriefDescription": "KIMD SHA 1",
++ "PublicDescription": "KIMD-SHA-1 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4169",
++ "EventName": "KIMD_SHA_256",
++ "BriefDescription": "KIMD SHA 256",
++ "PublicDescription": "KIMD-SHA-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4170",
++ "EventName": "KIMD_SHA_512",
++ "BriefDescription": "KIMD SHA 512",
++ "PublicDescription": "KIMD-SHA-512 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4171",
++ "EventName": "KIMD_SHA3_224",
++ "BriefDescription": "KIMD SHA3 224",
++ "PublicDescription": "KIMD-SHA3-224 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4172",
++ "EventName": "KIMD_SHA3_256",
++ "BriefDescription": "KIMD SHA3 256",
++ "PublicDescription": "KIMD-SHA3-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4173",
++ "EventName": "KIMD_SHA3_384",
++ "BriefDescription": "KIMD SHA3 384",
++ "PublicDescription": "KIMD-SHA3-384 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4174",
++ "EventName": "KIMD_SHA3_512",
++ "BriefDescription": "KIMD SHA3 512",
++ "PublicDescription": "KIMD-SHA3-512 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4175",
++ "EventName": "KIMD_SHAKE_128",
++ "BriefDescription": "KIMD SHAKE 128",
++ "PublicDescription": "KIMD-SHAKE-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4176",
++ "EventName": "KIMD_SHAKE_256",
++ "BriefDescription": "KIMD SHAKE 256",
++ "PublicDescription": "KIMD-SHAKE-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4177",
++ "EventName": "KIMD_GHASH",
++ "BriefDescription": "KIMD GHASH",
++ "PublicDescription": "KIMD-GHASH function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4178",
++ "EventName": "KLMD_SHA_1",
++ "BriefDescription": "KLMD SHA 1",
++ "PublicDescription": "KLMD-SHA-1 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4179",
++ "EventName": "KLMD_SHA_256",
++ "BriefDescription": "KLMD SHA 256",
++ "PublicDescription": "KLMD-SHA-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4180",
++ "EventName": "KLMD_SHA_512",
++ "BriefDescription": "KLMD SHA 512",
++ "PublicDescription": "KLMD-SHA-512 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4181",
++ "EventName": "KLMD_SHA3_224",
++ "BriefDescription": "KLMD SHA3 224",
++ "PublicDescription": "KLMD-SHA3-224 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4182",
++ "EventName": "KLMD_SHA3_256",
++ "BriefDescription": "KLMD SHA3 256",
++ "PublicDescription": "KLMD-SHA3-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4183",
++ "EventName": "KLMD_SHA3_384",
++ "BriefDescription": "KLMD SHA3 384",
++ "PublicDescription": "KLMD-SHA3-384 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4184",
++ "EventName": "KLMD_SHA3_512",
++ "BriefDescription": "KLMD SHA3 512",
++ "PublicDescription": "KLMD-SHA3-512 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4185",
++ "EventName": "KLMD_SHAKE_128",
++ "BriefDescription": "KLMD SHAKE 128",
++ "PublicDescription": "KLMD-SHAKE-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4186",
++ "EventName": "KLMD_SHAKE_256",
++ "BriefDescription": "KLMD SHAKE 256",
++ "PublicDescription": "KLMD-SHAKE-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4187",
++ "EventName": "KMAC_DEA",
++ "BriefDescription": "KMAC DEA",
++ "PublicDescription": "KMAC-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4188",
++ "EventName": "KMAC_TDEA_128",
++ "BriefDescription": "KMAC TDEA 128",
++ "PublicDescription": "KMAC-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4189",
++ "EventName": "KMAC_TDEA_192",
++ "BriefDescription": "KMAC TDEA 192",
++ "PublicDescription": "KMAC-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4190",
++ "EventName": "KMAC_ENCRYPTED_DEA",
++ "BriefDescription": "KMAC ENCRYPTED DEA",
++ "PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4191",
++ "EventName": "KMAC_ENCRYPTED_TDEA_128",
++ "BriefDescription": "KMAC ENCRYPTED TDEA 128",
++ "PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4192",
++ "EventName": "KMAC_ENCRYPTED_TDEA_192",
++ "BriefDescription": "KMAC ENCRYPTED TDEA 192",
++ "PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4193",
++ "EventName": "KMAC_AES_128",
++ "BriefDescription": "KMAC AES 128",
++ "PublicDescription": "KMAC-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4194",
++ "EventName": "KMAC_AES_192",
++ "BriefDescription": "KMAC AES 192",
++ "PublicDescription": "KMAC-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4195",
++ "EventName": "KMAC_AES_256",
++ "BriefDescription": "KMAC AES 256",
++ "PublicDescription": "KMAC-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4196",
++ "EventName": "KMAC_ENCRYPTED_AES_128",
++ "BriefDescription": "KMAC ENCRYPTED AES 128",
++ "PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4197",
++ "EventName": "KMAC_ENCRYPTED_AES_192",
++ "BriefDescription": "KMAC ENCRYPTED AES 192",
++ "PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4198",
++ "EventName": "KMAC_ENCRYPTED_AES_256",
++ "BriefDescription": "KMAC ENCRYPTED AES 256",
++ "PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4199",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4200",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4201",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4202",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4203",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4204",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4205",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4206",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4207",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4208",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4209",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4210",
++ "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A",
++ "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A",
++ "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4211",
++ "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128",
++ "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128",
++ "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4212",
++ "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256",
++ "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256",
++ "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4213",
++ "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128",
++ "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128",
++ "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4214",
++ "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256",
++ "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256",
++ "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4215",
++ "EventName": "PCC_SCALAR_MULTIPLY_P256",
++ "BriefDescription": "PCC SCALAR MULTIPLY P256",
++ "PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4216",
++ "EventName": "PCC_SCALAR_MULTIPLY_P384",
++ "BriefDescription": "PCC SCALAR MULTIPLY P384",
++ "PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4217",
++ "EventName": "PCC_SCALAR_MULTIPLY_P521",
++ "BriefDescription": "PCC SCALAR MULTIPLY P521",
++ "PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4218",
++ "EventName": "PCC_SCALAR_MULTIPLY_ED25519",
++ "BriefDescription": "PCC SCALAR MULTIPLY ED25519",
++ "PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4219",
++ "EventName": "PCC_SCALAR_MULTIPLY_ED448",
++ "BriefDescription": "PCC SCALAR MULTIPLY ED448",
++ "PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4220",
++ "EventName": "PCC_SCALAR_MULTIPLY_X25519",
++ "BriefDescription": "PCC SCALAR MULTIPLY X25519",
++ "PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4221",
++ "EventName": "PCC_SCALAR_MULTIPLY_X448",
++ "BriefDescription": "PCC SCALAR MULTIPLY X448",
++ "PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4222",
++ "EventName": "PRNO_SHA_512_DRNG",
++ "BriefDescription": "PRNO SHA 512 DRNG",
++ "PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4223",
++ "EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO",
++ "BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO",
++ "PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4224",
++ "EventName": "PRNO_TRNG",
++ "BriefDescription": "PRNO TRNG",
++ "PublicDescription": "PRNO-TRNG function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4225",
++ "EventName": "KDSA_ECDSA_VERIFY_P256",
++ "BriefDescription": "KDSA ECDSA VERIFY P256",
++ "PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4226",
++ "EventName": "KDSA_ECDSA_VERIFY_P384",
++ "BriefDescription": "KDSA ECDSA VERIFY P384",
++ "PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4227",
++ "EventName": "KDSA_ECDSA_VERIFY_P521",
++ "BriefDescription": "KDSA ECDSA VERIFY P521",
++ "PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4228",
++ "EventName": "KDSA_ECDSA_SIGN_P256",
++ "BriefDescription": "KDSA ECDSA SIGN P256",
++ "PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4229",
++ "EventName": "KDSA_ECDSA_SIGN_P384",
++ "BriefDescription": "KDSA ECDSA SIGN P384",
++ "PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4230",
++ "EventName": "KDSA_ECDSA_SIGN_P521",
++ "BriefDescription": "KDSA ECDSA SIGN P521",
++ "PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4231",
++ "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256",
++ "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256",
++ "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4232",
++ "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384",
++ "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384",
++ "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4233",
++ "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521",
++ "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521",
++ "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4234",
++ "EventName": "KDSA_EDDSA_VERIFY_ED25519",
++ "BriefDescription": "KDSA EDDSA VERIFY ED25519",
++ "PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4235",
++ "EventName": "KDSA_EDDSA_VERIFY_ED448",
++ "BriefDescription": "KDSA EDDSA VERIFY ED448",
++ "PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4236",
++ "EventName": "KDSA_EDDSA_SIGN_ED25519",
++ "BriefDescription": "KDSA EDDSA SIGN ED25519",
++ "PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4237",
++ "EventName": "KDSA_EDDSA_SIGN_ED448",
++ "BriefDescription": "KDSA EDDSA SIGN ED448",
++ "PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4238",
++ "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519",
++ "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519",
++ "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4239",
++ "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448",
++ "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448",
++ "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4240",
++ "EventName": "PCKMO_ENCRYPT_DEA_KEY",
++ "BriefDescription": "PCKMO ENCRYPT DEA KEY",
++ "PublicDescription": "PCKMO-Encrypt-DEA-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4241",
++ "EventName": "PCKMO_ENCRYPT_TDEA_128_KEY",
++ "BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY",
++ "PublicDescription": "PCKMO-Encrypt-TDEA-128-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4242",
++ "EventName": "PCKMO_ENCRYPT_TDEA_192_KEY",
++ "BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY",
++ "PublicDescription": "PCKMO-Encrypt-TDEA-192-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4243",
++ "EventName": "PCKMO_ENCRYPT_AES_128_KEY",
++ "BriefDescription": "PCKMO ENCRYPT AES 128 KEY",
++ "PublicDescription": "PCKMO-Encrypt-AES-128-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4244",
++ "EventName": "PCKMO_ENCRYPT_AES_192_KEY",
++ "BriefDescription": "PCKMO ENCRYPT AES 192 KEY",
++ "PublicDescription": "PCKMO-Encrypt-AES-192-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4245",
++ "EventName": "PCKMO_ENCRYPT_AES_256_KEY",
++ "BriefDescription": "PCKMO ENCRYPT AES 256 KEY",
++ "PublicDescription": "PCKMO-Encrypt-AES-256-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4246",
++ "EventName": "PCKMO_ENCRYPT_ECC_P256_KEY",
++ "BriefDescription": "PCKMO ENCRYPT ECC P256 KEY",
++ "PublicDescription": "PCKMO-Encrypt-ECC-P256-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4247",
++ "EventName": "PCKMO_ENCRYPT_ECC_P384_KEY",
++ "BriefDescription": "PCKMO ENCRYPT ECC P384 KEY",
++ "PublicDescription": "PCKMO-Encrypt-ECC-P384-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4248",
++ "EventName": "PCKMO_ENCRYPT_ECC_P521_KEY",
++ "BriefDescription": "PCKMO ENCRYPT ECC P521 KEY",
++ "PublicDescription": "PCKMO-Encrypt-ECC-P521-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4249",
++ "EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY",
++ "BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY",
++ "PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4250",
++ "EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY",
++ "BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY",
++ "PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4251",
++ "EventName": "IBM_RESERVED_155",
++ "BriefDescription": "IBM RESERVED_155",
++ "PublicDescription": "Reserved for IBM use"
++ },
++ {
++ "Unit": "PAI-CRYPTO",
++ "EventCode": "4252",
++ "EventName": "IBM_RESERVED_156",
++ "BriefDescription": "IBM RESERVED_156",
++ "PublicDescription": "Reserved for IBM use"
++ }
++]
+diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
+index 6edab8a16de6a..aded2caff3a23 100644
+--- a/tools/perf/util/auxtrace.c
++++ b/tools/perf/util/auxtrace.c
+@@ -2308,11 +2308,19 @@ struct sym_args {
+ bool near;
+ };
+
++static bool kern_sym_name_match(const char *kname, const char *name)
++{
++ size_t n = strlen(name);
++
++ return !strcmp(kname, name) ||
++ (!strncmp(kname, name, n) && kname[n] == '\t');
++}
++
+ static bool kern_sym_match(struct sym_args *args, const char *name, char type)
+ {
+ /* A function with the same name, and global or the n'th found or any */
+ return kallsyms__is_function(type) &&
+- !strcmp(name, args->name) &&
++ kern_sym_name_match(name, args->name) &&
+ ((args->global && isupper(type)) ||
+ (args->selected && ++(args->cnt) == args->idx) ||
+ (!args->global && !args->selected));
+diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile
+index 1d866658e541e..c61299c10e367 100644
+--- a/tools/testing/selftests/drivers/net/bonding/Makefile
++++ b/tools/testing/selftests/drivers/net/bonding/Makefile
+@@ -5,6 +5,8 @@ TEST_PROGS := bond-break-lacpdu-tx.sh \
+ dev_addr_lists.sh \
+ bond-arp-interval-causes-panic.sh
+
+-TEST_FILES := lag_lib.sh
++TEST_FILES := \
++ lag_lib.sh \
++ net_forwarding_lib.sh
+
+ include ../../../lib.mk
+diff --git a/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh b/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
+index e6fa24eded5b8..5cfe7d8ebc256 100755
+--- a/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
++++ b/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
+@@ -14,7 +14,7 @@ ALL_TESTS="
+ REQUIRE_MZ=no
+ NUM_NETIFS=0
+ lib_dir=$(dirname "$0")
+-source "$lib_dir"/../../../net/forwarding/lib.sh
++source "$lib_dir"/net_forwarding_lib.sh
+
+ source "$lib_dir"/lag_lib.sh
+
+diff --git a/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh
+new file mode 120000
+index 0000000000000..39c96828c5eff
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh
+@@ -0,0 +1 @@
++../../../net/forwarding/lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh b/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
+index dca8be6092b92..a1f269ee84dac 100755
+--- a/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
++++ b/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
+@@ -18,8 +18,8 @@ NUM_NETIFS=1
+ REQUIRE_JQ="no"
+ REQUIRE_MZ="no"
+ NETIF_CREATE="no"
+-lib_dir=$(dirname $0)/../../../net/forwarding
+-source $lib_dir/lib.sh
++lib_dir=$(dirname "$0")
++source "$lib_dir"/lib.sh
+
+ cleanup() {
+ echo "Cleaning up"
+diff --git a/tools/testing/selftests/drivers/net/team/Makefile b/tools/testing/selftests/drivers/net/team/Makefile
+index 642d8df1c137b..6a86e61e8bfe5 100644
+--- a/tools/testing/selftests/drivers/net/team/Makefile
++++ b/tools/testing/selftests/drivers/net/team/Makefile
+@@ -3,4 +3,8 @@
+
+ TEST_PROGS := dev_addr_lists.sh
+
++TEST_FILES := \
++ lag_lib.sh \
++ net_forwarding_lib.sh
++
+ include ../../../lib.mk
+diff --git a/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh b/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
+index debda72629564..33913112d5ca0 100755
+--- a/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
++++ b/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
+@@ -11,14 +11,14 @@ ALL_TESTS="
+ REQUIRE_MZ=no
+ NUM_NETIFS=0
+ lib_dir=$(dirname "$0")
+-source "$lib_dir"/../../../net/forwarding/lib.sh
++source "$lib_dir"/net_forwarding_lib.sh
+
+-source "$lib_dir"/../bonding/lag_lib.sh
++source "$lib_dir"/lag_lib.sh
+
+
+ destroy()
+ {
+- local ifnames=(dummy0 dummy1 team0 mv0)
++ local ifnames=(dummy1 dummy2 team0 mv0)
+ local ifname
+
+ for ifname in "${ifnames[@]}"; do
+diff --git a/tools/testing/selftests/drivers/net/team/lag_lib.sh b/tools/testing/selftests/drivers/net/team/lag_lib.sh
+new file mode 120000
+index 0000000000000..e1347a10afde6
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/team/lag_lib.sh
+@@ -0,0 +1 @@
++../bonding/lag_lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh
+new file mode 120000
+index 0000000000000..39c96828c5eff
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh
+@@ -0,0 +1 @@
++../../../net/forwarding/lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
+index db522577ff787..d3a79da215c8b 100644
+--- a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
++++ b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
+ # description: Generic dynamic event - check if duplicate events are caught
+-# requires: dynamic_events "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
++# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+
+ echo 0 > events/enable
+
+diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
+index 914fe2e5d0309..6461c375694f0 100644
+--- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
++++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
+ # description: event trigger - test inter-event histogram trigger eprobe on synthetic event
+-# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
++# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+
+ echo 0 > events/enable
+
+diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c b/tools/testing/selftests/kvm/memslot_modification_stress_test.c
+index 6ee7e1dde4043..bb1d17a1171bc 100644
+--- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c
++++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c
+@@ -67,7 +67,7 @@ struct memslot_antagonist_args {
+ static void add_remove_memslot(struct kvm_vm *vm, useconds_t delay,
+ uint64_t nr_modifications)
+ {
+- const uint64_t pages = 1;
++ uint64_t pages = max_t(int, vm->page_size, getpagesize()) / vm->page_size;
+ uint64_t gpa;
+ int i;
+
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index 9d4cb94cf4374..a3ea3d4a206d0 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -70,7 +70,7 @@ endef
+ run_tests: all
+ ifdef building_out_of_srctree
+ @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
+- rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
++ rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
+ fi
+ @if [ "X$(TEST_PROGS)" != "X" ]; then \
+ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \
+@@ -84,7 +84,7 @@ endif
+
+ define INSTALL_SINGLE_RULE
+ $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH))
+- $(if $(INSTALL_LIST),rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/)
++ $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/)
+ endef
+
+ define INSTALL_RULE
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-09 19:00 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-09 19:00 UTC (permalink / raw
To: gentoo-commits
commit: b5e5b27b8f93dc75bf46515f069c294820553d54
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 9 18:59:50 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Nov 9 18:59:50 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b5e5b27b
bpf: mark get_entry_ip as __maybe_unused
Bug: https://bugs.gentoo.org/878831
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 ++++
2910_bfp-mark-get-entry-ip-as--maybe-unused.patch | 11 +++++++++++
2 files changed, 15 insertions(+)
diff --git a/0000_README b/0000_README
index 9f94b8ae..004afc57 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
From: https://bugs.gentoo.org/710790
Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
+Patch: 2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
+From: https://www.spinics.net/lists/stable/msg604665.html
+Desc: bpf: mark get_entry_ip as __maybe_unused
+
Patch: 2920_sign-file-patch-for-libressl.patch
From: https://bugs.gentoo.org/717166
Desc: sign-file: full functionality with modern LibreSSL
diff --git a/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch b/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
new file mode 100644
index 00000000..a75b90c8
--- /dev/null
+++ b/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
@@ -0,0 +1,11 @@
+--- a/kernel/trace/bpf_trace.c 2022-11-09 13:30:24.192940988 -0500
++++ b/kernel/trace/bpf_trace.c 2022-11-09 13:30:59.029810818 -0500
+@@ -1027,7 +1027,7 @@ static const struct bpf_func_proto bpf_g
+ };
+
+ #ifdef CONFIG_X86_KERNEL_IBT
+-static unsigned long get_entry_ip(unsigned long fentry_ip)
++static unsigned long __maybe_unused get_entry_ip(unsigned long fentry_ip)
+ {
+ u32 instr;
+
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-10 18:10 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-10 18:10 UTC (permalink / raw
To: gentoo-commits
commit: 8b3e419be10860f5c8692b5fb9acaaee189b3279
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 18:09:47 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 18:09:47 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8b3e419b
Linux patch 6.0.8
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1007_linux-6.0.8.patch | 7683 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 7687 insertions(+)
diff --git a/0000_README b/0000_README
index 004afc57..52ac8549 100644
--- a/0000_README
+++ b/0000_README
@@ -71,6 +71,10 @@ Patch: 1006_linux-6.0.7.patch
From: http://www.kernel.org
Desc: Linux 6.0.7
+Patch: 1007_linux-6.0.8.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.8
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1007_linux-6.0.8.patch b/1007_linux-6.0.8.patch
new file mode 100644
index 00000000..c970b363
--- /dev/null
+++ b/1007_linux-6.0.8.patch
@@ -0,0 +1,7683 @@
+diff --git a/Documentation/process/howto.rst b/Documentation/process/howto.rst
+index cd6997a9d2032..8fc5398c732bc 100644
+--- a/Documentation/process/howto.rst
++++ b/Documentation/process/howto.rst
+@@ -36,7 +36,7 @@ experience, the following books are good for, if anything, reference:
+ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
+
+ The kernel is written using GNU C and the GNU toolchain. While it
+-adheres to the ISO C89 standard, it uses a number of extensions that are
++adheres to the ISO C11 standard, it uses a number of extensions that are
+ not featured in the standard. The kernel is a freestanding C
+ environment, with no reliance on the standard C library, so some
+ portions of the C standard are not supported. Arbitrary long long
+diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst
+index 859fd1b76c638..69354e1e7b255 100644
+--- a/Documentation/trace/histogram.rst
++++ b/Documentation/trace/histogram.rst
+@@ -39,7 +39,7 @@ Documentation written by Tom Zanussi
+ will use the event's kernel stacktrace as the key. The keywords
+ 'keys' or 'key' can be used to specify keys, and the keywords
+ 'values', 'vals', or 'val' can be used to specify values. Compound
+- keys consisting of up to two fields can be specified by the 'keys'
++ keys consisting of up to three fields can be specified by the 'keys'
+ keyword. Hashing a compound key produces a unique entry in the
+ table for each unique combination of component keys, and can be
+ useful for providing more fine-grained summaries of event data.
+diff --git a/Documentation/translations/it_IT/process/howto.rst b/Documentation/translations/it_IT/process/howto.rst
+index 16ad5622d5495..67b84f015da8a 100644
+--- a/Documentation/translations/it_IT/process/howto.rst
++++ b/Documentation/translations/it_IT/process/howto.rst
+@@ -44,7 +44,7 @@ altro, utili riferimenti:
+ - "C: A Reference Manual" di Harbison and Steele [Prentice Hall]
+
+ Il kernel è stato scritto usando GNU C e la toolchain GNU.
+-Sebbene si attenga allo standard ISO C89, esso utilizza una serie di
++Sebbene si attenga allo standard ISO C11, esso utilizza una serie di
+ estensioni che non sono previste in questo standard. Il kernel è un
+ ambiente C indipendente, che non ha alcuna dipendenza dalle librerie
+ C standard, così alcune parti del C standard non sono supportate.
+diff --git a/Documentation/translations/ja_JP/howto.rst b/Documentation/translations/ja_JP/howto.rst
+index 649e2ff2a407e..e2e946a4298ad 100644
+--- a/Documentation/translations/ja_JP/howto.rst
++++ b/Documentation/translations/ja_JP/howto.rst
+@@ -65,7 +65,7 @@ Linux カーネル開発のやり方
+ - 『新・詳説 C 言語 H&S リファレンス』 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク]
+
+ カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル
+-は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って
++は ISO C11 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って
+ います。カーネルは標準 C ライブラリに依存しない、C 言語非依存環境です。
+ そのため、C の標準の中で使えないものもあります。特に任意の long long
+ の除算や浮動小数点は使えません。カーネルがツールチェインや C 言語拡張
+diff --git a/Documentation/translations/ko_KR/howto.rst b/Documentation/translations/ko_KR/howto.rst
+index e43970584ca4d..2a7ab4257e44c 100644
+--- a/Documentation/translations/ko_KR/howto.rst
++++ b/Documentation/translations/ko_KR/howto.rst
+@@ -62,7 +62,7 @@ Documentation/process/howto.rst
+ - "Practical C Programming" by Steve Oualline [O'Reilly]
+ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
+
+-커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을
++커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C11 표준을
+ 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C
+ 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는
+ 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다.
+diff --git a/Documentation/translations/zh_CN/process/howto.rst b/Documentation/translations/zh_CN/process/howto.rst
+index 1455190dc087a..e7e4bb000b8a5 100644
+--- a/Documentation/translations/zh_CN/process/howto.rst
++++ b/Documentation/translations/zh_CN/process/howto.rst
+@@ -45,7 +45,7 @@ Linux内核大部分是由C语言写成的,一些体系结构相关的代码
+ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
+ 《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社]
+
+-Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些
++Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C11标准,但也用到了一些
+ 标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以
+ 并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许
+ 使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目
+diff --git a/Documentation/translations/zh_TW/process/howto.rst b/Documentation/translations/zh_TW/process/howto.rst
+index 68ae4411285b8..e335789d7e26c 100644
+--- a/Documentation/translations/zh_TW/process/howto.rst
++++ b/Documentation/translations/zh_TW/process/howto.rst
+@@ -48,7 +48,7 @@ Linux內核大部分是由C語言寫成的,一些體系結構相關的代碼
+ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
+ 《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社]
+
+-Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些
++Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C11標準,但也用到了一些
+ 標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以
+ 並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許
+ 使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目
+diff --git a/Makefile b/Makefile
+index c2144a4bb2efe..bcb76d4fdbc11 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 7
++SUBLEVEL = 8
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/imx6q-yapp4-crux.dts b/arch/arm/boot/dts/imx6q-yapp4-crux.dts
+index 15f4824a5142a..bddf3822ebf73 100644
+--- a/arch/arm/boot/dts/imx6q-yapp4-crux.dts
++++ b/arch/arm/boot/dts/imx6q-yapp4-crux.dts
+@@ -33,6 +33,10 @@
+ status = "okay";
+ };
+
++®_pu {
++ regulator-always-on;
++};
++
+ ®_usb_h1_vbus {
+ status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
+index 68e5ab2e27e22..6bb4855d13ce5 100644
+--- a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
+@@ -29,7 +29,7 @@
+
+ user-pb {
+ label = "user_pb";
+- gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>;
++ gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
+index 8e23cec7149e5..696427b487f01 100644
+--- a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
+@@ -26,7 +26,7 @@
+
+ user-pb {
+ label = "user_pb";
+- gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>;
++ gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+
+diff --git a/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts b/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
+index cea165f2161a3..afaf4a6759d4b 100644
+--- a/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
++++ b/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
+@@ -33,6 +33,10 @@
+ status = "okay";
+ };
+
++®_pu {
++ regulator-always-on;
++};
++
+ ®_usb_h1_vbus {
+ status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
+index fbaa0ce464271..8f1bb78fc1e48 100644
+--- a/arch/arm/boot/dts/ste-href.dtsi
++++ b/arch/arm/boot/dts/ste-href.dtsi
+@@ -24,6 +24,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
+index 1c9094f248939..e2f0cdacba7d1 100644
+--- a/arch/arm/boot/dts/ste-snowball.dts
++++ b/arch/arm/boot/dts/ste-snowball.dts
+@@ -28,6 +28,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
+index d6940e0afa863..27a3ab7e25e13 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
+@@ -44,6 +44,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+index 5f41256d7f4b4..b88f0c07873dd 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+@@ -57,6 +57,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+index 806da3fc33cd7..7231bc7452000 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+@@ -30,6 +30,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
+index b0dce91aff4be..9604695edf530 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
+@@ -35,6 +35,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+index ed5c79c3d04b0..69387e8754a95 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+@@ -30,6 +30,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
+index c57676faf181b..167846df31045 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
+@@ -34,6 +34,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+index 81b341a5ae451..93e5f5ed888d1 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+@@ -30,6 +30,14 @@
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
++
++ trips {
++ battery-crit-hi {
++ temperature = <70000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
+index 2f27619d8abd5..8b4d280b1e7e7 100644
+--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
++++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
+@@ -751,12 +751,26 @@
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&scpi_sensors0 0>;
++ trips {
++ pmic_crit0: trip0 {
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+
+ soc {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&scpi_sensors0 3>;
++ trips {
++ soc_crit0: trip0 {
++ temperature = <80000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
+ };
+
+ big_cluster_thermal_zone: big-cluster {
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+index 421d879013d7f..260d045dbd9a8 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+@@ -779,6 +779,9 @@
+ little-endian;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(1)>;
+ status = "disabled";
+ };
+
+@@ -788,6 +791,9 @@
+ little-endian;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(1)>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+index d76f1c42f3fa5..7bb33933c2cb2 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+@@ -533,6 +533,9 @@
+ little-endian;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(2)>;
+ status = "disabled";
+ };
+
+@@ -542,6 +545,9 @@
+ little-endian;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(2)>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+index 6680fb2a6dc92..8c76d86cb7566 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+@@ -1385,6 +1385,9 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+ little-endian;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(2)>;
+ status = "disabled";
+ };
+
+@@ -1395,6 +1398,9 @@
+ little-endian;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ clock-frequency = <2500000>;
++ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++ QORIQ_CLK_PLL_DIV(2)>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+index 82a1c44883786..10370d1a6c6de 100644
+--- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+@@ -38,9 +38,9 @@ conn_subsys: bus@5b000000 {
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x5b010000 0x10000>;
+ clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
+- <&sdhc0_lpcg IMX_LPCG_CLK_5>,
+- <&sdhc0_lpcg IMX_LPCG_CLK_0>;
+- clock-names = "ipg", "per", "ahb";
++ <&sdhc0_lpcg IMX_LPCG_CLK_0>,
++ <&sdhc0_lpcg IMX_LPCG_CLK_5>;
++ clock-names = "ipg", "ahb", "per";
+ power-domains = <&pd IMX_SC_R_SDHC_0>;
+ status = "disabled";
+ };
+@@ -49,9 +49,9 @@ conn_subsys: bus@5b000000 {
+ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x5b020000 0x10000>;
+ clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>,
+- <&sdhc1_lpcg IMX_LPCG_CLK_5>,
+- <&sdhc1_lpcg IMX_LPCG_CLK_0>;
+- clock-names = "ipg", "per", "ahb";
++ <&sdhc1_lpcg IMX_LPCG_CLK_0>,
++ <&sdhc1_lpcg IMX_LPCG_CLK_5>;
++ clock-names = "ipg", "ahb", "per";
+ power-domains = <&pd IMX_SC_R_SDHC_1>;
+ fsl,tuning-start-tap = <20>;
+ fsl,tuning-step = <2>;
+@@ -62,9 +62,9 @@ conn_subsys: bus@5b000000 {
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x5b030000 0x10000>;
+ clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>,
+- <&sdhc2_lpcg IMX_LPCG_CLK_5>,
+- <&sdhc2_lpcg IMX_LPCG_CLK_0>;
+- clock-names = "ipg", "per", "ahb";
++ <&sdhc2_lpcg IMX_LPCG_CLK_0>,
++ <&sdhc2_lpcg IMX_LPCG_CLK_5>;
++ clock-names = "ipg", "ahb", "per";
+ power-domains = <&pd IMX_SC_R_SDHC_2>;
+ status = "disabled";
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts b/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
+index 32f6f2f50c10c..43e89859c0445 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
+@@ -250,21 +250,21 @@
+ /* SODIMM 96 */
+ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4
+ /* CPLD_D[7] */
+- MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4
++ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x184
+ /* CPLD_D[6] */
+- MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4
++ MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x184
+ /* CPLD_D[5] */
+- MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4
++ MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x184
+ /* CPLD_D[4] */
+- MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4
++ MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x184
+ /* CPLD_D[3] */
+- MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4
++ MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x184
+ /* CPLD_D[2] */
+- MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4
++ MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x184
+ /* CPLD_D[1] */
+- MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4
++ MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x184
+ /* CPLD_D[0] */
+- MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4
++ MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x184
+ /* KBD_intK */
+ MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1c4
+ /* DISP_reset */
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index afb90f59c83c5..dabd94dc30c4b 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -276,6 +276,7 @@
+ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ clock-names = "main_clk";
++ power-domains = <&pgc_otg1>;
+ };
+
+ usbphynop2: usbphynop2 {
+@@ -285,6 +286,7 @@
+ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ clock-names = "main_clk";
++ power-domains = <&pgc_otg2>;
+ };
+
+ soc: soc@0 {
+@@ -674,13 +676,11 @@
+ pgc_otg1: power-domain@2 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MM_POWER_DOMAIN_OTG1>;
+- power-domains = <&pgc_hsiomix>;
+ };
+
+ pgc_otg2: power-domain@3 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MM_POWER_DOMAIN_OTG2>;
+- power-domains = <&pgc_hsiomix>;
+ };
+
+ pgc_gpumix: power-domain@4 {
+@@ -1186,7 +1186,7 @@
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
+ phys = <&usbphynop1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+- power-domains = <&pgc_otg1>;
++ power-domains = <&pgc_hsiomix>;
+ status = "disabled";
+ };
+
+@@ -1206,7 +1206,7 @@
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
+ phys = <&usbphynop2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+- power-domains = <&pgc_otg2>;
++ power-domains = <&pgc_hsiomix>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+index cb2836bfbd95c..ad0b99adf6911 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+@@ -662,7 +662,6 @@
+ pgc_otg1: power-domain@1 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_OTG1>;
+- power-domains = <&pgc_hsiomix>;
+ };
+
+ pgc_gpumix: power-domain@2 {
+@@ -1076,7 +1075,7 @@
+ assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
+ phys = <&usbphynop1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+- power-domains = <&pgc_otg1>;
++ power-domains = <&pgc_hsiomix>;
+ status = "disabled";
+ };
+
+@@ -1175,5 +1174,6 @@
+ assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+ clock-names = "main_clk";
++ power-domains = <&pgc_otg1>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+index 1c74c6a194491..360be51a35274 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+@@ -339,16 +339,6 @@
+ "SODIMM_82",
+ "SODIMM_70",
+ "SODIMM_72";
+-
+- ctrl-sleep-moci-hog {
+- gpio-hog;
+- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+- gpios = <29 GPIO_ACTIVE_HIGH>;
+- line-name = "CTRL_SLEEP_MOCI#";
+- output-high;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+- };
+ };
+
+ &gpio3 {
+@@ -417,6 +407,16 @@
+ "SODIMM_256",
+ "SODIMM_48",
+ "SODIMM_44";
++
++ ctrl-sleep-moci-hog {
++ gpio-hog;
++ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
++ gpios = <29 GPIO_ACTIVE_HIGH>;
++ line-name = "CTRL_SLEEP_MOCI#";
++ output-high;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
++ };
+ };
+
+ /* On-module I2C */
+diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
+index f83a07c7c9b1e..6981d3b0e2740 100644
+--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
+@@ -295,7 +295,10 @@
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- gpio-ranges = <&iomuxc 0 32 32>;
++ clocks = <&clk IMX93_CLK_GPIO2_GATE>,
++ <&clk IMX93_CLK_GPIO2_GATE>;
++ clock-names = "gpio", "port";
++ gpio-ranges = <&iomuxc 0 4 30>;
+ };
+
+ gpio3: gpio@43820080 {
+@@ -306,7 +309,11 @@
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- gpio-ranges = <&iomuxc 0 64 32>;
++ clocks = <&clk IMX93_CLK_GPIO3_GATE>,
++ <&clk IMX93_CLK_GPIO3_GATE>;
++ clock-names = "gpio", "port";
++ gpio-ranges = <&iomuxc 0 84 8>, <&iomuxc 8 66 18>,
++ <&iomuxc 26 34 2>, <&iomuxc 28 0 4>;
+ };
+
+ gpio4: gpio@43830080 {
+@@ -317,7 +324,10 @@
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- gpio-ranges = <&iomuxc 0 96 32>;
++ clocks = <&clk IMX93_CLK_GPIO4_GATE>,
++ <&clk IMX93_CLK_GPIO4_GATE>;
++ clock-names = "gpio", "port";
++ gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>;
+ };
+
+ gpio1: gpio@47400080 {
+@@ -328,7 +338,10 @@
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- gpio-ranges = <&iomuxc 0 0 32>;
++ clocks = <&clk IMX93_CLK_GPIO1_GATE>,
++ <&clk IMX93_CLK_GPIO1_GATE>;
++ clock-names = "gpio", "port";
++ gpio-ranges = <&iomuxc 0 92 16>;
+ };
+ };
+ };
+diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
+index c75ca36b4a491..deb2897f39d63 100644
+--- a/arch/arm64/kernel/entry-common.c
++++ b/arch/arm64/kernel/entry-common.c
+@@ -329,7 +329,8 @@ static void cortex_a76_erratum_1463225_svc_handler(void)
+ __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
+ }
+
+-static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
++static __always_inline bool
++cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
+ {
+ if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
+ return false;
+diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
+index b7557b25ed568..791d3de767713 100644
+--- a/arch/arm64/kvm/hyp/exception.c
++++ b/arch/arm64/kvm/hyp/exception.c
+@@ -13,6 +13,7 @@
+ #include <hyp/adjust_pc.h>
+ #include <linux/kvm_host.h>
+ #include <asm/kvm_emulate.h>
++#include <asm/kvm_mmu.h>
+
+ #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__)
+ #error Hypervisor code only!
+@@ -115,7 +116,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
+ new |= (old & PSR_C_BIT);
+ new |= (old & PSR_V_BIT);
+
+- if (kvm_has_mte(vcpu->kvm))
++ if (kvm_has_mte(kern_hyp_va(vcpu->kvm)))
+ new |= PSR_TCO_BIT;
+
+ new |= (old & PSR_DIT_BIT);
+diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
+index 6cbbb6c02f663..3330d1b76bdd2 100644
+--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
++++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
+@@ -87,6 +87,17 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
+
+ vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
+ write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
++
++ if (cpus_have_final_cap(ARM64_SME)) {
++ sysreg_clear_set_s(SYS_HFGRTR_EL2,
++ HFGxTR_EL2_nSMPRI_EL1_MASK |
++ HFGxTR_EL2_nTPIDR2_EL0_MASK,
++ 0);
++ sysreg_clear_set_s(SYS_HFGWTR_EL2,
++ HFGxTR_EL2_nSMPRI_EL1_MASK |
++ HFGxTR_EL2_nTPIDR2_EL0_MASK,
++ 0);
++ }
+ }
+
+ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
+@@ -96,6 +107,15 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
+ write_sysreg(0, hstr_el2);
+ if (kvm_arm_support_pmu_v3())
+ write_sysreg(0, pmuserenr_el0);
++
++ if (cpus_have_final_cap(ARM64_SME)) {
++ sysreg_clear_set_s(SYS_HFGRTR_EL2, 0,
++ HFGxTR_EL2_nSMPRI_EL1_MASK |
++ HFGxTR_EL2_nTPIDR2_EL0_MASK);
++ sysreg_clear_set_s(SYS_HFGWTR_EL2, 0,
++ HFGxTR_EL2_nSMPRI_EL1_MASK |
++ HFGxTR_EL2_nTPIDR2_EL0_MASK);
++ }
+ }
+
+ static inline void ___activate_traps(struct kvm_vcpu *vcpu)
+diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
+index 9f63857020618..c5f6fd8a94405 100644
+--- a/arch/arm64/kvm/hyp/nvhe/switch.c
++++ b/arch/arm64/kvm/hyp/nvhe/switch.c
+@@ -55,18 +55,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
+ write_sysreg(val, cptr_el2);
+ write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
+
+- if (cpus_have_final_cap(ARM64_SME)) {
+- val = read_sysreg_s(SYS_HFGRTR_EL2);
+- val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+- HFGxTR_EL2_nSMPRI_EL1_MASK);
+- write_sysreg_s(val, SYS_HFGRTR_EL2);
+-
+- val = read_sysreg_s(SYS_HFGWTR_EL2);
+- val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+- HFGxTR_EL2_nSMPRI_EL1_MASK);
+- write_sysreg_s(val, SYS_HFGWTR_EL2);
+- }
+-
+ if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
+ struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+
+@@ -110,20 +98,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
+
+ write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
+
+- if (cpus_have_final_cap(ARM64_SME)) {
+- u64 val;
+-
+- val = read_sysreg_s(SYS_HFGRTR_EL2);
+- val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+- HFGxTR_EL2_nSMPRI_EL1_MASK;
+- write_sysreg_s(val, SYS_HFGRTR_EL2);
+-
+- val = read_sysreg_s(SYS_HFGWTR_EL2);
+- val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+- HFGxTR_EL2_nSMPRI_EL1_MASK;
+- write_sysreg_s(val, SYS_HFGWTR_EL2);
+- }
+-
+ cptr = CPTR_EL2_DEFAULT;
+ if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED))
+ cptr |= CPTR_EL2_TZ;
+diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
+index 7acb87eaa0925..1a97391fedd29 100644
+--- a/arch/arm64/kvm/hyp/vhe/switch.c
++++ b/arch/arm64/kvm/hyp/vhe/switch.c
+@@ -63,10 +63,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
+ __activate_traps_fpsimd32(vcpu);
+ }
+
+- if (cpus_have_final_cap(ARM64_SME))
+- write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
+- sctlr_el2);
+-
+ write_sysreg(val, cpacr_el1);
+
+ write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
+@@ -88,10 +84,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
+ */
+ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
+
+- if (cpus_have_final_cap(ARM64_SME))
+- write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
+- sctlr_el2);
+-
+ write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
+
+ if (!arm64_kernel_unmapped_at_el0())
+diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h
+index 9d3d7737c58b1..a005ebc547793 100644
+--- a/arch/parisc/include/asm/hardware.h
++++ b/arch/parisc/include/asm/hardware.h
+@@ -10,12 +10,12 @@
+ #define SVERSION_ANY_ID PA_SVERSION_ANY_ID
+
+ struct hp_hardware {
+- unsigned short hw_type:5; /* HPHW_xxx */
+- unsigned short hversion;
+- unsigned long sversion:28;
+- unsigned short opt;
+- const char name[80]; /* The hardware description */
+-};
++ unsigned int hw_type:8; /* HPHW_xxx */
++ unsigned int hversion:12;
++ unsigned int sversion:12;
++ unsigned char opt;
++ unsigned char name[59]; /* The hardware description */
++} __packed;
+
+ struct parisc_device;
+
+diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
+index d126e78e101ae..e7ee0c0c91d35 100644
+--- a/arch/parisc/kernel/drivers.c
++++ b/arch/parisc/kernel/drivers.c
+@@ -882,15 +882,13 @@ void __init walk_central_bus(void)
+ &root);
+ }
+
+-static void print_parisc_device(struct parisc_device *dev)
++static __init void print_parisc_device(struct parisc_device *dev)
+ {
+- char hw_path[64];
+- static int count;
++ static int count __initdata;
+
+- print_pa_hwpath(dev, hw_path);
+- pr_info("%d. %s at %pap [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+- ++count, dev->name, &(dev->hpa.start), hw_path, dev->id.hw_type,
+- dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
++ pr_info("%d. %s at %pap { type:%d, hv:%#x, sv:%#x, rev:%#x }",
++ ++count, dev->name, &(dev->hpa.start), dev->id.hw_type,
++ dev->id.hversion, dev->id.sversion, dev->id.hversion_rev);
+
+ if (dev->num_addrs) {
+ int k;
+@@ -1079,7 +1077,7 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data)
+
+
+
+-static int print_one_device(struct device * dev, void * data)
++static __init int print_one_device(struct device * dev, void * data)
+ {
+ struct parisc_device * pdev = to_parisc_device(dev);
+
+diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
+index 928dcf7a20d98..b8998cf0508a6 100644
+--- a/arch/x86/coco/tdx/tdx.c
++++ b/arch/x86/coco/tdx/tdx.c
+@@ -34,6 +34,8 @@
+ #define VE_GET_PORT_NUM(e) ((e) >> 16)
+ #define VE_IS_IO_STRING(e) ((e) & BIT(4))
+
++#define ATTR_SEPT_VE_DISABLE BIT(28)
++
+ /*
+ * Wrapper for standard use of __tdx_hypercall with no output aside from
+ * return code.
+@@ -98,10 +100,11 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+ panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
+ }
+
+-static u64 get_cc_mask(void)
++static void tdx_parse_tdinfo(u64 *cc_mask)
+ {
+ struct tdx_module_output out;
+ unsigned int gpa_width;
++ u64 td_attr;
+
+ /*
+ * TDINFO TDX module call is used to get the TD execution environment
+@@ -109,19 +112,27 @@ static u64 get_cc_mask(void)
+ * information, etc. More details about the ABI can be found in TDX
+ * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL
+ * [TDG.VP.INFO].
++ */
++ tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
++
++ /*
++ * The highest bit of a guest physical address is the "sharing" bit.
++ * Set it for shared pages and clear it for private pages.
+ *
+ * The GPA width that comes out of this call is critical. TDX guests
+ * can not meaningfully run without it.
+ */
+- tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
+-
+ gpa_width = out.rcx & GENMASK(5, 0);
++ *cc_mask = BIT_ULL(gpa_width - 1);
+
+ /*
+- * The highest bit of a guest physical address is the "sharing" bit.
+- * Set it for shared pages and clear it for private pages.
++ * 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.
+ */
+- return BIT_ULL(gpa_width - 1);
++ td_attr = out.rdx;
++ if (!(td_attr & ATTR_SEPT_VE_DISABLE))
++ panic("TD misconfiguration: SEPT_VE_DISABLE attibute must be set.\n");
+ }
+
+ /*
+@@ -758,7 +769,7 @@ void __init tdx_early_init(void)
+ setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
+
+ cc_set_vendor(CC_VENDOR_INTEL);
+- cc_mask = get_cc_mask();
++ tdx_parse_tdinfo(&cc_mask);
+ cc_set_mask(cc_mask);
+
+ /*
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index c20d8cd47c484..3bfd0c5e01593 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -4891,6 +4891,7 @@ static const struct x86_cpu_desc isolation_ucodes[] = {
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000),
++ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e),
+diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
+index ac973c6f82ad6..d1b9d2ad03476 100644
+--- a/arch/x86/events/intel/ds.c
++++ b/arch/x86/events/intel/ds.c
+@@ -982,8 +982,13 @@ struct event_constraint intel_icl_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */
+
+ INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), /* MEM_INST_RETIRED.LOAD */
+- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), /* MEM_INST_RETIRED.STORE */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
+
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */
+
+@@ -1004,8 +1009,13 @@ struct event_constraint intel_spr_pebs_event_constraints[] = {
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe),
+ INTEL_PLD_CONSTRAINT(0x1cd, 0xfe),
+ INTEL_PSD_CONSTRAINT(0x2cd, 0x1),
+- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf),
+- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf),
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
++ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
+
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf),
+
+diff --git a/arch/x86/include/asm/syscall_wrapper.h b/arch/x86/include/asm/syscall_wrapper.h
+index 59358d1bf8800..fd2669b1cb2d9 100644
+--- a/arch/x86/include/asm/syscall_wrapper.h
++++ b/arch/x86/include/asm/syscall_wrapper.h
+@@ -6,7 +6,7 @@
+ #ifndef _ASM_X86_SYSCALL_WRAPPER_H
+ #define _ASM_X86_SYSCALL_WRAPPER_H
+
+-struct pt_regs;
++#include <asm/ptrace.h>
+
+ extern long __x64_sys_ni_syscall(const struct pt_regs *regs);
+ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 2796dde06302a..28ab0b9484d33 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -1117,11 +1117,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ entry->eax = max(entry->eax, 0x80000021);
+ break;
+ case 0x80000001:
++ entry->ebx &= ~GENMASK(27, 16);
+ cpuid_entry_override(entry, CPUID_8000_0001_EDX);
+ cpuid_entry_override(entry, CPUID_8000_0001_ECX);
+ break;
+ case 0x80000006:
+- /* L2 cache and TLB: pass through host info. */
++ /* Drop reserved bits, pass host L2 cache and TLB info. */
++ entry->edx &= ~GENMASK(17, 16);
+ break;
+ case 0x80000007: /* Advanced power management */
+ /* invariant TSC is CPUID.80000007H:EDX[8] */
+@@ -1151,6 +1153,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ g_phys_as = phys_as;
+
+ entry->eax = g_phys_as | (virt_as << 8);
++ entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
+ entry->edx = 0;
+ cpuid_entry_override(entry, CPUID_8000_0008_EBX);
+ break;
+@@ -1170,6 +1173,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ entry->ecx = entry->edx = 0;
+ break;
+ case 0x8000001a:
++ entry->eax &= GENMASK(2, 0);
++ entry->ebx = entry->ecx = entry->edx = 0;
++ break;
+ case 0x8000001e:
+ break;
+ case 0x8000001F:
+@@ -1177,7 +1183,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+ } else {
+ cpuid_entry_override(entry, CPUID_8000_001F_EAX);
+-
++ /* Clear NumVMPL since KVM does not support VMPL. */
++ entry->ebx &= ~GENMASK(31, 12);
+ /*
+ * Enumerate '0' for "PA bits reduction", the adjusted
+ * MAXPHYADDR is enumerated directly (see 0x80000008).
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 883e380e5801d..fdb20b3c38f5f 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -791,8 +791,7 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
+ ctxt->mode, linear);
+ }
+
+-static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+- enum x86emul_mode mode)
++static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+ ulong linear;
+ int rc;
+@@ -802,41 +801,71 @@ static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+
+ if (ctxt->op_bytes != sizeof(unsigned long))
+ addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
+- rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear);
++ rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, &linear);
+ if (rc == X86EMUL_CONTINUE)
+ ctxt->_eip = addr.ea;
+ return rc;
+ }
+
++static inline int emulator_recalc_and_set_mode(struct x86_emulate_ctxt *ctxt)
++{
++ u64 efer;
++ struct desc_struct cs;
++ u16 selector;
++ u32 base3;
++
++ ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
++
++ if (!(ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PE)) {
++ /* Real mode. cpu must not have long mode active */
++ if (efer & EFER_LMA)
++ return X86EMUL_UNHANDLEABLE;
++ ctxt->mode = X86EMUL_MODE_REAL;
++ return X86EMUL_CONTINUE;
++ }
++
++ if (ctxt->eflags & X86_EFLAGS_VM) {
++ /* Protected/VM86 mode. cpu must not have long mode active */
++ if (efer & EFER_LMA)
++ return X86EMUL_UNHANDLEABLE;
++ ctxt->mode = X86EMUL_MODE_VM86;
++ return X86EMUL_CONTINUE;
++ }
++
++ if (!ctxt->ops->get_segment(ctxt, &selector, &cs, &base3, VCPU_SREG_CS))
++ return X86EMUL_UNHANDLEABLE;
++
++ if (efer & EFER_LMA) {
++ if (cs.l) {
++ /* Proper long mode */
++ ctxt->mode = X86EMUL_MODE_PROT64;
++ } else if (cs.d) {
++ /* 32 bit compatibility mode*/
++ ctxt->mode = X86EMUL_MODE_PROT32;
++ } else {
++ ctxt->mode = X86EMUL_MODE_PROT16;
++ }
++ } else {
++ /* Legacy 32 bit / 16 bit mode */
++ ctxt->mode = cs.d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
++ }
++
++ return X86EMUL_CONTINUE;
++}
++
+ static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+- return assign_eip(ctxt, dst, ctxt->mode);
++ return assign_eip(ctxt, dst);
+ }
+
+-static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
+- const struct desc_struct *cs_desc)
++static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+- enum x86emul_mode mode = ctxt->mode;
+- int rc;
++ int rc = emulator_recalc_and_set_mode(ctxt);
+
+-#ifdef CONFIG_X86_64
+- if (ctxt->mode >= X86EMUL_MODE_PROT16) {
+- if (cs_desc->l) {
+- u64 efer = 0;
++ if (rc != X86EMUL_CONTINUE)
++ return rc;
+
+- ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+- if (efer & EFER_LMA)
+- mode = X86EMUL_MODE_PROT64;
+- } else
+- mode = X86EMUL_MODE_PROT32; /* temporary value */
+- }
+-#endif
+- if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32)
+- mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+- rc = assign_eip(ctxt, dst, mode);
+- if (rc == X86EMUL_CONTINUE)
+- ctxt->mode = mode;
+- return rc;
++ return assign_eip(ctxt, dst);
+ }
+
+ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
+@@ -2170,7 +2199,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+- rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++ rc = assign_eip_far(ctxt, ctxt->src.val);
+ /* Error handling is not implemented. */
+ if (rc != X86EMUL_CONTINUE)
+ return X86EMUL_UNHANDLEABLE;
+@@ -2248,7 +2277,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
+ &new_desc);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+- rc = assign_eip_far(ctxt, eip, &new_desc);
++ rc = assign_eip_far(ctxt, eip);
+ /* Error handling is not implemented. */
+ if (rc != X86EMUL_CONTINUE)
+ return X86EMUL_UNHANDLEABLE;
+@@ -2430,7 +2459,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
+ ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED;
+ ctxt->_eip = GET_SMSTATE(u32, smstate, 0x7ff0);
+
+- for (i = 0; i < NR_EMULATOR_GPRS; i++)
++ for (i = 0; i < 8; i++)
+ *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4);
+
+ val = GET_SMSTATE(u32, smstate, 0x7fcc);
+@@ -2487,7 +2516,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
+ u16 selector;
+ int i, r;
+
+- for (i = 0; i < NR_EMULATOR_GPRS; i++)
++ for (i = 0; i < 16; i++)
+ *reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8);
+
+ ctxt->_eip = GET_SMSTATE(u64, smstate, 0x7f78);
+@@ -2631,7 +2660,7 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
+ * those side effects need to be explicitly handled for both success
+ * and shutdown.
+ */
+- return X86EMUL_CONTINUE;
++ return emulator_recalc_and_set_mode(ctxt);
+
+ emulate_shutdown:
+ ctxt->ops->triple_fault(ctxt);
+@@ -2874,6 +2903,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
+ ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
+
+ ctxt->_eip = rdx;
++ ctxt->mode = usermode;
+ *reg_write(ctxt, VCPU_REGS_RSP) = rcx;
+
+ return X86EMUL_CONTINUE;
+@@ -3467,7 +3497,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+- rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++ rc = assign_eip_far(ctxt, ctxt->src.val);
+ if (rc != X86EMUL_CONTINUE)
+ goto fail;
+
+@@ -3609,11 +3639,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
+
+ static int em_cr_write(struct x86_emulate_ctxt *ctxt)
+ {
+- if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
++ int cr_num = ctxt->modrm_reg;
++ int r;
++
++ if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val))
+ return emulate_gp(ctxt, 0);
+
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
++
++ if (cr_num == 0) {
++ /*
++ * CR0 write might have updated CR0.PE and/or CR0.PG
++ * which can affect the cpu's execution mode.
++ */
++ r = emulator_recalc_and_set_mode(ctxt);
++ if (r != X86EMUL_CONTINUE)
++ return r;
++ }
++
+ return X86EMUL_CONTINUE;
+ }
+
+diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
+index c5e5dfef69c7f..2bd599d61b9bf 100644
+--- a/arch/x86/kvm/vmx/capabilities.h
++++ b/arch/x86/kvm/vmx/capabilities.h
+@@ -24,8 +24,6 @@ extern int __read_mostly pt_mode;
+ #define PMU_CAP_FW_WRITES (1ULL << 13)
+ #define PMU_CAP_LBR_FMT 0x3f
+
+-#define DEBUGCTLMSR_LBR_MASK (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI)
+-
+ struct nested_vmx_msrs {
+ /*
+ * We only store the "true" versions of the VMX capability MSRs. We
+@@ -404,6 +402,7 @@ static inline bool vmx_pebs_supported(void)
+ static inline u64 vmx_get_perf_capabilities(void)
+ {
+ u64 perf_cap = PMU_CAP_FW_WRITES;
++ struct x86_pmu_lbr lbr;
+ u64 host_perf_cap = 0;
+
+ if (!enable_pmu)
+@@ -412,7 +411,8 @@ static inline u64 vmx_get_perf_capabilities(void)
+ if (boot_cpu_has(X86_FEATURE_PDCM))
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+
+- perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++ if (x86_perf_get_lbr(&lbr) >= 0 && lbr.nr)
++ perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
+
+ if (vmx_pebs_supported()) {
+ perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+@@ -423,19 +423,6 @@ static inline u64 vmx_get_perf_capabilities(void)
+ return perf_cap;
+ }
+
+-static inline u64 vmx_supported_debugctl(void)
+-{
+- u64 debugctl = 0;
+-
+- if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
+- debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
+-
+- if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT)
+- debugctl |= DEBUGCTLMSR_LBR_MASK;
+-
+- return debugctl;
+-}
+-
+ static inline bool cpu_has_notify_vmexit(void)
+ {
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 7f3581960eb5d..74de8c9e401b1 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -2016,15 +2016,17 @@ static u64 nested_vmx_truncate_sysenter_addr(struct kvm_vcpu *vcpu,
+ return (unsigned long)data;
+ }
+
+-static u64 vcpu_supported_debugctl(struct kvm_vcpu *vcpu)
++static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated)
+ {
+- u64 debugctl = vmx_supported_debugctl();
++ u64 debugctl = 0;
+
+- if (!intel_pmu_lbr_is_enabled(vcpu))
+- debugctl &= ~DEBUGCTLMSR_LBR_MASK;
++ if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) &&
++ (host_initiated || guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)))
++ debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
+
+- if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
+- debugctl &= ~DEBUGCTLMSR_BUS_LOCK_DETECT;
++ if ((vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) &&
++ (host_initiated || intel_pmu_lbr_is_enabled(vcpu)))
++ debugctl |= DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
+
+ return debugctl;
+ }
+@@ -2098,7 +2100,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ vmcs_writel(GUEST_SYSENTER_ESP, data);
+ break;
+ case MSR_IA32_DEBUGCTLMSR: {
+- u64 invalid = data & ~vcpu_supported_debugctl(vcpu);
++ u64 invalid;
++
++ invalid = data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_initiated);
+ if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) {
+ if (report_ignored_msrs)
+ vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n",
+@@ -8277,6 +8281,11 @@ static __init int hardware_setup(void)
+ if (!cpu_has_virtual_nmis())
+ enable_vnmi = 0;
+
++#ifdef CONFIG_X86_SGX_KVM
++ if (!cpu_has_vmx_encls_vmexit())
++ enable_sgx = false;
++#endif
++
+ /*
+ * set_apic_access_page_addr() is used to reload apic access
+ * page upon invalidation. No need to do anything if not
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 86c3b29f1abc0..05f4424eb0c52 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -2304,11 +2304,11 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time,
+
+ /* we verify if the enable bit is set... */
+ if (system_time & 1) {
+- kvm_gfn_to_pfn_cache_init(vcpu->kvm, &vcpu->arch.pv_time, vcpu,
+- KVM_HOST_USES_PFN, system_time & ~1ULL,
+- sizeof(struct pvclock_vcpu_time_info));
++ kvm_gpc_activate(vcpu->kvm, &vcpu->arch.pv_time, vcpu,
++ KVM_HOST_USES_PFN, system_time & ~1ULL,
++ sizeof(struct pvclock_vcpu_time_info));
+ } else {
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time);
+ }
+
+ return;
+@@ -3377,7 +3377,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data)
+
+ static void kvmclock_reset(struct kvm_vcpu *vcpu)
+ {
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time);
+ vcpu->arch.time = 0;
+ }
+
+@@ -11629,6 +11629,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
+ vcpu->arch.regs_avail = ~0;
+ vcpu->arch.regs_dirty = ~0;
+
++ kvm_gpc_init(&vcpu->arch.pv_time);
++
+ if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu))
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+ else
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index 280cb5dc7341a..cecf8299b187b 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -42,13 +42,13 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
+ int idx = srcu_read_lock(&kvm->srcu);
+
+ if (gfn == GPA_INVALID) {
+- kvm_gfn_to_pfn_cache_destroy(kvm, gpc);
++ kvm_gpc_deactivate(kvm, gpc);
+ goto out;
+ }
+
+ do {
+- ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, KVM_HOST_USES_PFN,
+- gpa, PAGE_SIZE);
++ ret = kvm_gpc_activate(kvm, gpc, NULL, KVM_HOST_USES_PFN, gpa,
++ PAGE_SIZE);
+ if (ret)
+ goto out;
+
+@@ -554,15 +554,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+ offsetof(struct compat_vcpu_info, time));
+
+ if (data->u.gpa == GPA_INVALID) {
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
+ r = 0;
+ break;
+ }
+
+- r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+- &vcpu->arch.xen.vcpu_info_cache,
+- NULL, KVM_HOST_USES_PFN, data->u.gpa,
+- sizeof(struct vcpu_info));
++ r = kvm_gpc_activate(vcpu->kvm,
++ &vcpu->arch.xen.vcpu_info_cache, NULL,
++ KVM_HOST_USES_PFN, data->u.gpa,
++ sizeof(struct vcpu_info));
+ if (!r)
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+
+@@ -570,16 +570,16 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+
+ case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:
+ if (data->u.gpa == GPA_INVALID) {
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+- &vcpu->arch.xen.vcpu_time_info_cache);
++ kvm_gpc_deactivate(vcpu->kvm,
++ &vcpu->arch.xen.vcpu_time_info_cache);
+ r = 0;
+ break;
+ }
+
+- r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+- &vcpu->arch.xen.vcpu_time_info_cache,
+- NULL, KVM_HOST_USES_PFN, data->u.gpa,
+- sizeof(struct pvclock_vcpu_time_info));
++ r = kvm_gpc_activate(vcpu->kvm,
++ &vcpu->arch.xen.vcpu_time_info_cache,
++ NULL, KVM_HOST_USES_PFN, data->u.gpa,
++ sizeof(struct pvclock_vcpu_time_info));
+ if (!r)
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+ break;
+@@ -590,16 +590,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+ break;
+ }
+ if (data->u.gpa == GPA_INVALID) {
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+- &vcpu->arch.xen.runstate_cache);
++ kvm_gpc_deactivate(vcpu->kvm,
++ &vcpu->arch.xen.runstate_cache);
+ r = 0;
+ break;
+ }
+
+- r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+- &vcpu->arch.xen.runstate_cache,
+- NULL, KVM_HOST_USES_PFN, data->u.gpa,
+- sizeof(struct vcpu_runstate_info));
++ r = kvm_gpc_activate(vcpu->kvm, &vcpu->arch.xen.runstate_cache,
++ NULL, KVM_HOST_USES_PFN, data->u.gpa,
++ sizeof(struct vcpu_runstate_info));
+ break;
+
+ case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT:
+@@ -1817,7 +1816,12 @@ void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu)
+ {
+ vcpu->arch.xen.vcpu_id = vcpu->vcpu_idx;
+ vcpu->arch.xen.poll_evtchn = 0;
++
+ timer_setup(&vcpu->arch.xen.poll_timer, cancel_evtchn_poll, 0);
++
++ kvm_gpc_init(&vcpu->arch.xen.runstate_cache);
++ kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache);
++ kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache);
+ }
+
+ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
+@@ -1825,18 +1829,17 @@ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
+ if (kvm_xen_timer_enabled(vcpu))
+ kvm_xen_stop_timer(vcpu);
+
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+- &vcpu->arch.xen.runstate_cache);
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+- &vcpu->arch.xen.vcpu_info_cache);
+- kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+- &vcpu->arch.xen.vcpu_time_info_cache);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.runstate_cache);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
++ kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_time_info_cache);
++
+ del_timer_sync(&vcpu->arch.xen.poll_timer);
+ }
+
+ void kvm_xen_init_vm(struct kvm *kvm)
+ {
+ idr_init(&kvm->arch.xen.evtchn_ports);
++ kvm_gpc_init(&kvm->arch.xen.shinfo_cache);
+ }
+
+ void kvm_xen_destroy_vm(struct kvm *kvm)
+@@ -1844,7 +1847,7 @@ void kvm_xen_destroy_vm(struct kvm *kvm)
+ struct evtchnfd *evtchnfd;
+ int i;
+
+- kvm_gfn_to_pfn_cache_destroy(kvm, &kvm->arch.xen.shinfo_cache);
++ kvm_gpc_deactivate(kvm, &kvm->arch.xen.shinfo_cache);
+
+ idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) {
+ if (!evtchnfd->deliver.port.port)
+diff --git a/block/bio.c b/block/bio.c
+index 77e3b764a0784..fc2364cf17750 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -741,7 +741,7 @@ void bio_put(struct bio *bio)
+ return;
+ }
+
+- if (bio->bi_opf & REQ_ALLOC_CACHE) {
++ if ((bio->bi_opf & REQ_ALLOC_CACHE) && !WARN_ON_ONCE(in_interrupt())) {
+ struct bio_alloc_cache *cache;
+
+ bio_uninit(bio);
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index fe840536e6ac4..edf41959a705f 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4104,9 +4104,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
+ return 0;
+
+ err_hctxs:
+- xa_destroy(&q->hctx_table);
+- q->nr_hw_queues = 0;
+- blk_mq_sysfs_deinit(q);
++ blk_mq_release(q);
+ err_poll:
+ blk_stat_free_callback(q->poll_cb);
+ q->poll_cb = NULL;
+diff --git a/block/genhd.c b/block/genhd.c
+index 988ba52fd3316..044ff97381e33 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -519,6 +519,7 @@ out_unregister_bdi:
+ bdi_unregister(disk->bdi);
+ out_unregister_queue:
+ blk_unregister_queue(disk);
++ rq_qos_exit(disk->queue);
+ out_put_slave_dir:
+ kobject_put(disk->slave_dir);
+ out_put_holder_dir:
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 80ad530583c9c..9952f3a792bad 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -163,7 +163,7 @@ static void ghes_unmap(void __iomem *vaddr, enum fixed_addresses fixmap_idx)
+ clear_fixmap(fixmap_idx);
+ }
+
+-int ghes_estatus_pool_init(int num_ghes)
++int ghes_estatus_pool_init(unsigned int num_ghes)
+ {
+ unsigned long addr, len;
+ int rc;
+diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
+index 3b818ab186be8..1f4fc5f8a819d 100644
+--- a/drivers/acpi/numa/srat.c
++++ b/drivers/acpi/numa/srat.c
+@@ -327,6 +327,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
+ pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
+ node, start, end);
+ }
++ node_set(node, numa_nodes_parsed);
+
+ /* Set the next available fake_pxm value */
+ (*fake_pxm)++;
+diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
+index 0a8bf09a5c19e..03c580625c2cc 100644
+--- a/drivers/ata/pata_legacy.c
++++ b/drivers/ata/pata_legacy.c
+@@ -315,9 +315,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ outb(inb(0x1F4) & 0x07, 0x1F4);
+
+ rt = inb(0x1F3);
+- rt &= 0x07 << (3 * adev->devno);
++ rt &= ~(0x07 << (3 * !adev->devno));
+ if (pio)
+- rt |= (1 + 3 * pio) << (3 * adev->devno);
++ rt |= (1 + 3 * pio) << (3 * !adev->devno);
++ outb(rt, 0x1F3);
+
+ udelay(100);
+ outb(inb(0x1F2) | 0x01, 0x1F2);
+diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c
+index 400e65190904f..51caa2a427dd8 100644
+--- a/drivers/ata/pata_palmld.c
++++ b/drivers/ata/pata_palmld.c
+@@ -63,8 +63,8 @@ static int palmld_pata_probe(struct platform_device *pdev)
+
+ /* remap drive's physical memory address */
+ mem = devm_platform_ioremap_resource(pdev, 0);
+- if (!mem)
+- return -ENOMEM;
++ if (IS_ERR(mem))
++ return PTR_ERR(mem);
+
+ /* request and activate power and reset GPIOs */
+ lda->power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index 6a4a94b4cdf42..31a8715d3a4d3 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1507,6 +1507,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
+ */
+ ub->dev_info.flags &= UBLK_F_ALL;
+
++ if (!IS_BUILTIN(CONFIG_BLK_DEV_UBLK))
++ ub->dev_info.flags |= UBLK_F_URING_CMD_COMP_IN_TASK;
++
+ /* We are not ready to support zero copy */
+ ub->dev_info.flags &= ~UBLK_F_SUPPORT_ZERO_COPY;
+
+diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
+index 67c21263f9e0f..fd281d4395055 100644
+--- a/drivers/bluetooth/virtio_bt.c
++++ b/drivers/bluetooth/virtio_bt.c
+@@ -219,7 +219,7 @@ static void virtbt_rx_work(struct work_struct *work)
+ if (!skb)
+ return;
+
+- skb->len = len;
++ skb_put(skb, len);
+ virtbt_rx_handle(vbt, skb);
+
+ if (virtbt_add_inbuf(vbt) < 0)
+diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
+index e7dd457e9b22b..e98fcac578d66 100644
+--- a/drivers/char/hw_random/bcm2835-rng.c
++++ b/drivers/char/hw_random/bcm2835-rng.c
+@@ -71,7 +71,7 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
+ while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) {
+ if (!wait)
+ return 0;
+- cpu_relax();
++ hwrng_msleep(rng, 1000);
+ }
+
+ num_words = rng_readl(priv, RNG_STATUS) >> 24;
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index 4f5df1fc74b46..e6247141d0c05 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -90,13 +90,66 @@ static const struct regmap_access_table rs9_writeable_table = {
+ .n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges),
+ };
+
++static int rs9_regmap_i2c_write(void *context,
++ unsigned int reg, unsigned int val)
++{
++ struct i2c_client *i2c = context;
++ const u8 data[3] = { reg, 1, val };
++ const int count = ARRAY_SIZE(data);
++ int ret;
++
++ ret = i2c_master_send(i2c, data, count);
++ if (ret == count)
++ return 0;
++ else if (ret < 0)
++ return ret;
++ else
++ return -EIO;
++}
++
++static int rs9_regmap_i2c_read(void *context,
++ unsigned int reg, unsigned int *val)
++{
++ struct i2c_client *i2c = context;
++ struct i2c_msg xfer[2];
++ u8 txdata = reg;
++ u8 rxdata[2];
++ int ret;
++
++ xfer[0].addr = i2c->addr;
++ xfer[0].flags = 0;
++ xfer[0].len = 1;
++ xfer[0].buf = (void *)&txdata;
++
++ xfer[1].addr = i2c->addr;
++ xfer[1].flags = I2C_M_RD;
++ xfer[1].len = 2;
++ xfer[1].buf = (void *)rxdata;
++
++ ret = i2c_transfer(i2c->adapter, xfer, 2);
++ if (ret < 0)
++ return ret;
++ if (ret != 2)
++ return -EIO;
++
++ /*
++ * Byte 0 is transfer length, which is always 1 due
++ * to BCP register programming to 1 in rs9_probe(),
++ * ignore it and use data from Byte 1.
++ */
++ *val = rxdata[1];
++ return 0;
++}
++
+ static const struct regmap_config rs9_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+- .cache_type = REGCACHE_FLAT,
+- .max_register = 0x8,
++ .cache_type = REGCACHE_NONE,
++ .max_register = RS9_REG_BCP,
+ .rd_table = &rs9_readable_table,
+ .wr_table = &rs9_writeable_table,
++ .reg_write = rs9_regmap_i2c_write,
++ .reg_read = rs9_regmap_i2c_read,
+ };
+
+ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
+@@ -242,11 +295,17 @@ static int rs9_probe(struct i2c_client *client)
+ return ret;
+ }
+
+- rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config);
++ rs9->regmap = devm_regmap_init(&client->dev, NULL,
++ client, &rs9_regmap_config);
+ if (IS_ERR(rs9->regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap),
+ "Failed to allocate register map\n");
+
++ /* Always read back 1 Byte via I2C */
++ ret = regmap_write(rs9->regmap, RS9_REG_BCP, 1);
++ if (ret < 0)
++ return ret;
++
+ /* Register clock */
+ for (i = 0; i < rs9->chip_info->num_clks; i++) {
+ snprintf(name, 5, "DIF%d", i);
+diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c
+index 7ff64d4d5920d..2360f3f956184 100644
+--- a/drivers/clk/qcom/gcc-sc7280.c
++++ b/drivers/clk/qcom/gcc-sc7280.c
+@@ -3467,6 +3467,7 @@ static int gcc_sc7280_probe(struct platform_device *pdev)
+ regmap_update_bits(regmap, 0x28004, BIT(0), BIT(0));
+ regmap_update_bits(regmap, 0x28014, BIT(0), BIT(0));
+ regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));
++ regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13));
+
+ ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+ ARRAY_SIZE(gcc_dfs_clocks));
+diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c
+index 9a832f2bcf491..1490cd45a654a 100644
+--- a/drivers/clk/qcom/gpucc-sc7280.c
++++ b/drivers/clk/qcom/gpucc-sc7280.c
+@@ -463,6 +463,7 @@ static int gpu_cc_sc7280_probe(struct platform_device *pdev)
+ */
+ regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
+ regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0));
++ regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13));
+
+ return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap);
+ }
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index 3fc4233b1ead8..7beb0e3b18724 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -47,6 +47,7 @@ enum clk_ids {
+ CLK_S0_VIO,
+ CLK_S0_VC,
+ CLK_S0_HSC,
++ CLK_SASYNCPER,
+ CLK_SV_VIP,
+ CLK_SV_IR,
+ CLK_SDSRC,
+@@ -84,6 +85,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ DEF_FIXED(".s0_vio", CLK_S0_VIO, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s0_vc", CLK_S0_VC, CLK_PLL1_DIV2, 2, 1),
+ DEF_FIXED(".s0_hsc", CLK_S0_HSC, CLK_PLL1_DIV2, 2, 1),
++ DEF_FIXED(".sasyncper", CLK_SASYNCPER, CLK_PLL5_DIV4, 3, 1),
+ DEF_FIXED(".sv_vip", CLK_SV_VIP, CLK_PLL1, 5, 1),
+ DEF_FIXED(".sv_ir", CLK_SV_IR, CLK_PLL1, 5, 1),
+ DEF_BASE(".sdsrc", CLK_SDSRC, CLK_TYPE_GEN4_SDSRC, CLK_PLL5),
+@@ -128,6 +130,9 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ DEF_FIXED("s0d4_hsc", R8A779G0_CLK_S0D4_HSC, CLK_S0_HSC, 4, 1),
+ DEF_FIXED("cl16m_hsc", R8A779G0_CLK_CL16M_HSC, CLK_S0_HSC, 48, 1),
+ DEF_FIXED("s0d2_cc", R8A779G0_CLK_S0D2_CC, CLK_S0, 2, 1),
++ DEF_FIXED("sasyncperd1",R8A779G0_CLK_SASYNCPERD1, CLK_SASYNCPER,1, 1),
++ DEF_FIXED("sasyncperd2",R8A779G0_CLK_SASYNCPERD2, CLK_SASYNCPER,2, 1),
++ DEF_FIXED("sasyncperd4",R8A779G0_CLK_SASYNCPERD4, CLK_SASYNCPER,4, 1),
+ DEF_FIXED("svd1_ir", R8A779G0_CLK_SVD1_IR, CLK_SV_IR, 1, 1),
+ DEF_FIXED("svd2_ir", R8A779G0_CLK_SVD2_IR, CLK_SV_IR, 2, 1),
+ DEF_FIXED("svd1_vip", R8A779G0_CLK_SVD1_VIP, CLK_SV_VIP, 1, 1),
+@@ -150,10 +155,10 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ };
+
+ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+- DEF_MOD("hscif0", 514, R8A779G0_CLK_S0D3_PER),
+- DEF_MOD("hscif1", 515, R8A779G0_CLK_S0D3_PER),
+- DEF_MOD("hscif2", 516, R8A779G0_CLK_S0D3_PER),
+- DEF_MOD("hscif3", 517, R8A779G0_CLK_S0D3_PER),
++ DEF_MOD("hscif0", 514, R8A779G0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif1", 515, R8A779G0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif2", 516, R8A779G0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif3", 517, R8A779G0_CLK_SASYNCPERD1),
+ };
+
+ /*
+diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c
+index 1d12a8206444e..36aa5070d9024 100644
+--- a/drivers/cxl/core/pmem.c
++++ b/drivers/cxl/core/pmem.c
+@@ -188,6 +188,7 @@ static void cxl_nvdimm_release(struct device *dev)
+ {
+ struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev);
+
++ xa_destroy(&cxl_nvd->pmem_regions);
+ kfree(cxl_nvd);
+ }
+
+@@ -230,6 +231,7 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd)
+
+ dev = &cxl_nvd->dev;
+ cxl_nvd->cxlmd = cxlmd;
++ xa_init(&cxl_nvd->pmem_regions);
+ device_initialize(dev);
+ lockdep_set_class(&dev->mutex, &cxl_nvdimm_key);
+ device_set_pm_not_required(dev);
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index bffde862de0bf..e7556864ea808 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -811,6 +811,7 @@ static struct cxl_dport *find_dport(struct cxl_port *port, int id)
+ static int add_dport(struct cxl_port *port, struct cxl_dport *new)
+ {
+ struct cxl_dport *dup;
++ int rc;
+
+ device_lock_assert(&port->dev);
+ dup = find_dport(port, new->port_id);
+@@ -821,8 +822,14 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *new)
+ dev_name(dup->dport));
+ return -EBUSY;
+ }
+- return xa_insert(&port->dports, (unsigned long)new->dport, new,
+- GFP_KERNEL);
++
++ rc = xa_insert(&port->dports, (unsigned long)new->dport, new,
++ GFP_KERNEL);
++ if (rc)
++ return rc;
++
++ port->nr_dports++;
++ return 0;
+ }
+
+ /*
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 4011480169784..6b7fb955a05ac 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -657,6 +657,9 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port,
+ xa_for_each(&port->regions, index, iter) {
+ struct cxl_region_params *ip = &iter->region->params;
+
++ if (!ip->res)
++ continue;
++
+ if (ip->res->start > p->res->start) {
+ dev_dbg(&cxlr->dev,
+ "%s: HPA order violation %s:%pr vs %pr\n",
+@@ -686,18 +689,27 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port,
+ return cxl_rr;
+ }
+
+-static void free_region_ref(struct cxl_region_ref *cxl_rr)
++static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr)
+ {
+- struct cxl_port *port = cxl_rr->port;
+ struct cxl_region *cxlr = cxl_rr->region;
+ struct cxl_decoder *cxld = cxl_rr->decoder;
+
++ if (!cxld)
++ return;
++
+ dev_WARN_ONCE(&cxlr->dev, cxld->region != cxlr, "region mismatch\n");
+ if (cxld->region == cxlr) {
+ cxld->region = NULL;
+ put_device(&cxlr->dev);
+ }
++}
++
++static void free_region_ref(struct cxl_region_ref *cxl_rr)
++{
++ struct cxl_port *port = cxl_rr->port;
++ struct cxl_region *cxlr = cxl_rr->region;
+
++ cxl_rr_free_decoder(cxl_rr);
+ xa_erase(&port->regions, (unsigned long)cxlr);
+ xa_destroy(&cxl_rr->endpoints);
+ kfree(cxl_rr);
+@@ -728,6 +740,33 @@ static int cxl_rr_ep_add(struct cxl_region_ref *cxl_rr,
+ return 0;
+ }
+
++static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
++ struct cxl_endpoint_decoder *cxled,
++ struct cxl_region_ref *cxl_rr)
++{
++ struct cxl_decoder *cxld;
++
++ if (port == cxled_to_port(cxled))
++ cxld = &cxled->cxld;
++ else
++ cxld = cxl_region_find_decoder(port, cxlr);
++ if (!cxld) {
++ dev_dbg(&cxlr->dev, "%s: no decoder available\n",
++ dev_name(&port->dev));
++ return -EBUSY;
++ }
++
++ if (cxld->region) {
++ dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
++ dev_name(&port->dev), dev_name(&cxld->dev),
++ dev_name(&cxld->region->dev));
++ return -EBUSY;
++ }
++
++ cxl_rr->decoder = cxld;
++ return 0;
++}
++
+ /**
+ * cxl_port_attach_region() - track a region's interest in a port by endpoint
+ * @port: port to add a new region reference 'struct cxl_region_ref'
+@@ -794,12 +833,6 @@ static int cxl_port_attach_region(struct cxl_port *port,
+ cxl_rr->nr_targets++;
+ nr_targets_inc = true;
+ }
+-
+- /*
+- * The decoder for @cxlr was allocated when the region was first
+- * attached to @port.
+- */
+- cxld = cxl_rr->decoder;
+ } else {
+ cxl_rr = alloc_region_ref(port, cxlr);
+ if (IS_ERR(cxl_rr)) {
+@@ -810,26 +843,11 @@ static int cxl_port_attach_region(struct cxl_port *port,
+ }
+ nr_targets_inc = true;
+
+- if (port == cxled_to_port(cxled))
+- cxld = &cxled->cxld;
+- else
+- cxld = cxl_region_find_decoder(port, cxlr);
+- if (!cxld) {
+- dev_dbg(&cxlr->dev, "%s: no decoder available\n",
+- dev_name(&port->dev));
+- goto out_erase;
+- }
+-
+- if (cxld->region) {
+- dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
+- dev_name(&port->dev), dev_name(&cxld->dev),
+- dev_name(&cxld->region->dev));
+- rc = -EBUSY;
++ rc = cxl_rr_alloc_decoder(port, cxlr, cxled, cxl_rr);
++ if (rc)
+ goto out_erase;
+- }
+-
+- cxl_rr->decoder = cxld;
+ }
++ cxld = cxl_rr->decoder;
+
+ rc = cxl_rr_ep_add(cxl_rr, cxled);
+ if (rc) {
+@@ -971,7 +989,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
+ if (cxl_rr->nr_targets_set) {
+ int i, distance;
+
+- distance = p->nr_targets / cxl_rr->nr_targets;
++ /*
++ * Passthrough ports impose no distance requirements between
++ * peers
++ */
++ if (port->nr_dports == 1)
++ distance = 0;
++ else
++ distance = p->nr_targets / cxl_rr->nr_targets;
+ for (i = 0; i < cxl_rr->nr_targets_set; i++)
+ if (ep->dport == cxlsd->target[i]) {
+ rc = check_last_peer(cxled, ep, cxl_rr,
+@@ -1538,8 +1563,19 @@ static struct cxl_region *to_cxl_region(struct device *dev)
+ static void unregister_region(void *dev)
+ {
+ struct cxl_region *cxlr = to_cxl_region(dev);
++ struct cxl_region_params *p = &cxlr->params;
++ int i;
+
+ device_del(dev);
++
++ /*
++ * Now that region sysfs is shutdown, the parameter block is now
++ * read-only, so no need to hold the region rwsem to access the
++ * region parameters.
++ */
++ for (i = 0; i < p->interleave_ways; i++)
++ detach_target(cxlr, i);
++
+ cxl_region_iomem_release(cxlr);
+ put_device(dev);
+ }
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index f680450f0b16c..ac75554b5d763 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -423,7 +423,7 @@ struct cxl_nvdimm {
+ struct device dev;
+ struct cxl_memdev *cxlmd;
+ struct cxl_nvdimm_bridge *bridge;
+- struct cxl_pmem_region *region;
++ struct xarray pmem_regions;
+ };
+
+ struct cxl_pmem_region_mapping {
+@@ -457,6 +457,7 @@ struct cxl_pmem_region {
+ * @regions: cxl_region_ref instances, regions mapped by this port
+ * @parent_dport: dport that points to this port in the parent
+ * @decoder_ida: allocator for decoder ids
++ * @nr_dports: number of entries in @dports
+ * @hdm_end: track last allocated HDM decoder instance for allocation ordering
+ * @commit_end: cursor to track highest committed decoder for commit ordering
+ * @component_reg_phys: component register capability base address (optional)
+@@ -475,6 +476,7 @@ struct cxl_port {
+ struct xarray regions;
+ struct cxl_dport *parent_dport;
+ struct ida decoder_ida;
++ int nr_dports;
+ int hdm_end;
+ int commit_end;
+ resource_size_t component_reg_phys;
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
+index 7dc0a2fa1a6b6..faade12279f02 100644
+--- a/drivers/cxl/pmem.c
++++ b/drivers/cxl/pmem.c
+@@ -30,17 +30,20 @@ static void unregister_nvdimm(void *nvdimm)
+ struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
+ struct cxl_nvdimm_bridge *cxl_nvb = cxl_nvd->bridge;
+ struct cxl_pmem_region *cxlr_pmem;
++ unsigned long index;
+
+ device_lock(&cxl_nvb->dev);
+- cxlr_pmem = cxl_nvd->region;
+ dev_set_drvdata(&cxl_nvd->dev, NULL);
+- cxl_nvd->region = NULL;
+- device_unlock(&cxl_nvb->dev);
++ xa_for_each(&cxl_nvd->pmem_regions, index, cxlr_pmem) {
++ get_device(&cxlr_pmem->dev);
++ device_unlock(&cxl_nvb->dev);
+
+- if (cxlr_pmem) {
+ device_release_driver(&cxlr_pmem->dev);
+ put_device(&cxlr_pmem->dev);
++
++ device_lock(&cxl_nvb->dev);
+ }
++ device_unlock(&cxl_nvb->dev);
+
+ nvdimm_delete(nvdimm);
+ cxl_nvd->bridge = NULL;
+@@ -366,25 +369,49 @@ static int match_cxl_nvdimm(struct device *dev, void *data)
+
+ static void unregister_nvdimm_region(void *nd_region)
+ {
+- struct cxl_nvdimm_bridge *cxl_nvb;
+- struct cxl_pmem_region *cxlr_pmem;
++ nvdimm_region_delete(nd_region);
++}
++
++static int cxl_nvdimm_add_region(struct cxl_nvdimm *cxl_nvd,
++ struct cxl_pmem_region *cxlr_pmem)
++{
++ int rc;
++
++ rc = xa_insert(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem,
++ cxlr_pmem, GFP_KERNEL);
++ if (rc)
++ return rc;
++
++ get_device(&cxlr_pmem->dev);
++ return 0;
++}
++
++static void cxl_nvdimm_del_region(struct cxl_nvdimm *cxl_nvd,
++ struct cxl_pmem_region *cxlr_pmem)
++{
++ /*
++ * It is possible this is called without a corresponding
++ * cxl_nvdimm_add_region for @cxlr_pmem
++ */
++ cxlr_pmem = xa_erase(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem);
++ if (cxlr_pmem)
++ put_device(&cxlr_pmem->dev);
++}
++
++static void release_mappings(void *data)
++{
+ int i;
++ struct cxl_pmem_region *cxlr_pmem = data;
++ struct cxl_nvdimm_bridge *cxl_nvb = cxlr_pmem->bridge;
+
+- cxlr_pmem = nd_region_provider_data(nd_region);
+- cxl_nvb = cxlr_pmem->bridge;
+ device_lock(&cxl_nvb->dev);
+ for (i = 0; i < cxlr_pmem->nr_mappings; i++) {
+ struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i];
+ struct cxl_nvdimm *cxl_nvd = m->cxl_nvd;
+
+- if (cxl_nvd->region) {
+- put_device(&cxlr_pmem->dev);
+- cxl_nvd->region = NULL;
+- }
++ cxl_nvdimm_del_region(cxl_nvd, cxlr_pmem);
+ }
+ device_unlock(&cxl_nvb->dev);
+-
+- nvdimm_region_delete(nd_region);
+ }
+
+ static void cxlr_pmem_remove_resource(void *res)
+@@ -422,7 +449,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ if (!cxl_nvb->nvdimm_bus) {
+ dev_dbg(dev, "nvdimm bus not found\n");
+ rc = -ENXIO;
+- goto err;
++ goto out_nvb;
+ }
+
+ memset(&mappings, 0, sizeof(mappings));
+@@ -431,7 +458,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+ if (!res) {
+ rc = -ENOMEM;
+- goto err;
++ goto out_nvb;
+ }
+
+ res->name = "Persistent Memory";
+@@ -442,11 +469,11 @@ static int cxl_pmem_region_probe(struct device *dev)
+
+ rc = insert_resource(&iomem_resource, res);
+ if (rc)
+- goto err;
++ goto out_nvb;
+
+ rc = devm_add_action_or_reset(dev, cxlr_pmem_remove_resource, res);
+ if (rc)
+- goto err;
++ goto out_nvb;
+
+ ndr_desc.res = res;
+ ndr_desc.provider_data = cxlr_pmem;
+@@ -462,7 +489,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
+ if (!nd_set) {
+ rc = -ENOMEM;
+- goto err;
++ goto out_nvb;
+ }
+
+ ndr_desc.memregion = cxlr->id;
+@@ -472,9 +499,13 @@ static int cxl_pmem_region_probe(struct device *dev)
+ info = kmalloc_array(cxlr_pmem->nr_mappings, sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ rc = -ENOMEM;
+- goto err;
++ goto out_nvb;
+ }
+
++ rc = devm_add_action_or_reset(dev, release_mappings, cxlr_pmem);
++ if (rc)
++ goto out_nvd;
++
+ for (i = 0; i < cxlr_pmem->nr_mappings; i++) {
+ struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i];
+ struct cxl_memdev *cxlmd = m->cxlmd;
+@@ -486,7 +517,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ dev_dbg(dev, "[%d]: %s: no cxl_nvdimm found\n", i,
+ dev_name(&cxlmd->dev));
+ rc = -ENODEV;
+- goto err;
++ goto out_nvd;
+ }
+
+ /* safe to drop ref now with bridge lock held */
+@@ -498,10 +529,17 @@ static int cxl_pmem_region_probe(struct device *dev)
+ dev_dbg(dev, "[%d]: %s: no nvdimm found\n", i,
+ dev_name(&cxlmd->dev));
+ rc = -ENODEV;
+- goto err;
++ goto out_nvd;
+ }
+- cxl_nvd->region = cxlr_pmem;
+- get_device(&cxlr_pmem->dev);
++
++ /*
++ * Pin the region per nvdimm device as those may be released
++ * out-of-order with respect to the region, and a single nvdimm
++ * maybe associated with multiple regions
++ */
++ rc = cxl_nvdimm_add_region(cxl_nvd, cxlr_pmem);
++ if (rc)
++ goto out_nvd;
+ m->cxl_nvd = cxl_nvd;
+ mappings[i] = (struct nd_mapping_desc) {
+ .nvdimm = nvdimm,
+@@ -527,27 +565,18 @@ static int cxl_pmem_region_probe(struct device *dev)
+ nvdimm_pmem_region_create(cxl_nvb->nvdimm_bus, &ndr_desc);
+ if (!cxlr_pmem->nd_region) {
+ rc = -ENOMEM;
+- goto err;
++ goto out_nvd;
+ }
+
+ rc = devm_add_action_or_reset(dev, unregister_nvdimm_region,
+ cxlr_pmem->nd_region);
+-out:
++out_nvd:
+ kfree(info);
++out_nvb:
+ device_unlock(&cxl_nvb->dev);
+ put_device(&cxl_nvb->dev);
+
+ return rc;
+-
+-err:
+- dev_dbg(dev, "failed to create nvdimm region\n");
+- for (i--; i >= 0; i--) {
+- nvdimm = mappings[i].nvdimm;
+- cxl_nvd = nvdimm_provider_data(nvdimm);
+- put_device(&cxl_nvd->region->dev);
+- cxl_nvd->region = NULL;
+- }
+- goto out;
+ }
+
+ static struct cxl_driver cxl_pmem_region_driver = {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 609ebedee9cb6..9022f5ee29aa8 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -2044,8 +2044,12 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
+ {
+ int ret = scmi_chan_setup(info, dev, prot_id, true);
+
+- if (!ret) /* Rx is optional, hence no error check */
+- scmi_chan_setup(info, dev, prot_id, false);
++ if (!ret) {
++ /* Rx is optional, report only memory errors */
++ ret = scmi_chan_setup(info, dev, prot_id, false);
++ if (ret && ret != -ENOMEM)
++ ret = 0;
++ }
+
+ return ret;
+ }
+@@ -2571,6 +2575,7 @@ MODULE_DEVICE_TABLE(of, scmi_of_match);
+ static struct platform_driver scmi_driver = {
+ .driver = {
+ .name = "arm-scmi",
++ .suppress_bind_attrs = true,
+ .of_match_table = scmi_of_match,
+ .dev_groups = versions_groups,
+ },
+diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
+index 14709dbc96a1a..33c9b81a55cd1 100644
+--- a/drivers/firmware/arm_scmi/virtio.c
++++ b/drivers/firmware/arm_scmi/virtio.c
+@@ -148,7 +148,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
+ {
+ unsigned long flags;
+ DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done);
+- void *deferred_wq = NULL;
+
+ /*
+ * Prepare to wait for the last release if not already released
+@@ -162,16 +161,11 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
+
+ vioch->shutdown_done = &vioch_shutdown_done;
+ virtio_break_device(vioch->vqueue->vdev);
+- if (!vioch->is_rx && vioch->deferred_tx_wq) {
+- deferred_wq = vioch->deferred_tx_wq;
++ if (!vioch->is_rx && vioch->deferred_tx_wq)
+ /* Cannot be kicked anymore after this...*/
+ vioch->deferred_tx_wq = NULL;
+- }
+ spin_unlock_irqrestore(&vioch->lock, flags);
+
+- if (deferred_wq)
+- destroy_workqueue(deferred_wq);
+-
+ scmi_vio_channel_release(vioch);
+
+ /* Let any possibly concurrent RX path release the channel */
+@@ -416,6 +410,11 @@ static bool virtio_chan_available(struct device *dev, int idx)
+ return vioch && !vioch->cinfo;
+ }
+
++static void scmi_destroy_tx_workqueue(void *deferred_tx_wq)
++{
++ destroy_workqueue(deferred_tx_wq);
++}
++
+ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ bool tx)
+ {
+@@ -430,6 +429,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+
+ /* Setup a deferred worker for polling. */
+ if (tx && !vioch->deferred_tx_wq) {
++ int ret;
++
+ vioch->deferred_tx_wq =
+ alloc_workqueue(dev_name(&scmi_vdev->dev),
+ WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
+@@ -437,6 +438,11 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ if (!vioch->deferred_tx_wq)
+ return -ENOMEM;
+
++ ret = devm_add_action_or_reset(dev, scmi_destroy_tx_workqueue,
++ vioch->deferred_tx_wq);
++ if (ret)
++ return ret;
++
+ INIT_WORK(&vioch->deferred_tx_work,
+ scmi_vio_deferred_tx_worker);
+ }
+@@ -444,12 +450,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ for (i = 0; i < vioch->max_msg; i++) {
+ struct scmi_vio_msg *msg;
+
+- msg = devm_kzalloc(cinfo->dev, sizeof(*msg), GFP_KERNEL);
++ msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ if (tx) {
+- msg->request = devm_kzalloc(cinfo->dev,
++ msg->request = devm_kzalloc(dev,
+ VIRTIO_SCMI_MAX_PDU_SIZE,
+ GFP_KERNEL);
+ if (!msg->request)
+@@ -458,7 +464,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ refcount_set(&msg->users, 1);
+ }
+
+- msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
++ msg->input = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE,
+ GFP_KERNEL);
+ if (!msg->input)
+ return -ENOMEM;
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index aa6d109fac08b..a06decee51e06 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -608,7 +608,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+
+ seed = early_memremap(efi_rng_seed, sizeof(*seed));
+ if (seed != NULL) {
+- size = READ_ONCE(seed->size);
++ size = min(seed->size, EFI_RANDOM_SEED_SIZE);
+ early_memunmap(seed, sizeof(*seed));
+ } else {
+ pr_err("Could not map UEFI random seed!\n");
+diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
+index 24aa375353724..33ab567695951 100644
+--- a/drivers/firmware/efi/libstub/random.c
++++ b/drivers/firmware/efi/libstub/random.c
+@@ -75,7 +75,12 @@ efi_status_t efi_random_get_seed(void)
+ if (status != EFI_SUCCESS)
+ return status;
+
+- status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
++ /*
++ * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
++ * allocation will survive a kexec reboot (although we refresh the seed
++ * beforehand)
++ */
++ status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+ sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
+ (void **)&seed);
+ if (status != EFI_SUCCESS)
+diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c
+index 8f665678e9e39..e8d69bd548f3f 100644
+--- a/drivers/firmware/efi/tpm.c
++++ b/drivers/firmware/efi/tpm.c
+@@ -97,7 +97,7 @@ int __init efi_tpm_eventlog_init(void)
+ goto out_calc;
+ }
+
+- memblock_reserve((unsigned long)final_tbl,
++ memblock_reserve(efi.tpm_final_log,
+ tbl_size + sizeof(*final_tbl));
+ efi_tpm_final_log_size = tbl_size;
+
+diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
+index 433b615871395..0ba9f18312f5b 100644
+--- a/drivers/firmware/efi/vars.c
++++ b/drivers/firmware/efi/vars.c
+@@ -21,29 +21,22 @@ static struct efivars *__efivars;
+
+ static DEFINE_SEMAPHORE(efivars_lock);
+
+-static efi_status_t check_var_size(u32 attributes, unsigned long size)
+-{
+- const struct efivar_operations *fops;
+-
+- fops = __efivars->ops;
+-
+- if (!fops->query_variable_store)
+- return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+-
+- return fops->query_variable_store(attributes, size, false);
+-}
+-
+-static
+-efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
++static efi_status_t check_var_size(bool nonblocking, u32 attributes,
++ unsigned long size)
+ {
+ const struct efivar_operations *fops;
++ efi_status_t status;
+
+ fops = __efivars->ops;
+
+ if (!fops->query_variable_store)
++ status = EFI_UNSUPPORTED;
++ else
++ status = fops->query_variable_store(attributes, size,
++ nonblocking);
++ if (status == EFI_UNSUPPORTED)
+ return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+-
+- return fops->query_variable_store(attributes, size, true);
++ return status;
+ }
+
+ /**
+@@ -195,26 +188,6 @@ efi_status_t efivar_get_next_variable(unsigned long *name_size,
+ }
+ EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, EFIVAR);
+
+-/*
+- * efivar_set_variable_blocking() - local helper function for set_variable
+- *
+- * Must be called with efivars_lock held.
+- */
+-static efi_status_t
+-efivar_set_variable_blocking(efi_char16_t *name, efi_guid_t *vendor,
+- u32 attr, unsigned long data_size, void *data)
+-{
+- efi_status_t status;
+-
+- if (data_size > 0) {
+- status = check_var_size(attr, data_size +
+- ucs2_strsize(name, 1024));
+- if (status != EFI_SUCCESS)
+- return status;
+- }
+- return __efivars->ops->set_variable(name, vendor, attr, data_size, data);
+-}
+-
+ /*
+ * efivar_set_variable_locked() - set a variable identified by name/vendor
+ *
+@@ -228,23 +201,21 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
+ efi_set_variable_t *setvar;
+ efi_status_t status;
+
+- if (!nonblocking)
+- return efivar_set_variable_blocking(name, vendor, attr,
+- data_size, data);
++ if (data_size > 0) {
++ status = check_var_size(nonblocking, attr,
++ data_size + ucs2_strsize(name, 1024));
++ if (status != EFI_SUCCESS)
++ return status;
++ }
+
+ /*
+ * If no _nonblocking variant exists, the ordinary one
+ * is assumed to be non-blocking.
+ */
+- setvar = __efivars->ops->set_variable_nonblocking ?:
+- __efivars->ops->set_variable;
++ setvar = __efivars->ops->set_variable_nonblocking;
++ if (!setvar || !nonblocking)
++ setvar = __efivars->ops->set_variable;
+
+- if (data_size > 0) {
+- status = check_var_size_nonblocking(attr, data_size +
+- ucs2_strsize(name, 1024));
+- if (status != EFI_SUCCESS)
+- return status;
+- }
+ return setvar(name, vendor, attr, data_size, data);
+ }
+ EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, EFIVAR);
+@@ -264,7 +235,8 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ if (efivar_lock())
+ return EFI_ABORTED;
+
+- status = efivar_set_variable_blocking(name, vendor, attr, data_size, data);
++ status = efivar_set_variable_locked(name, vendor, attr, data_size,
++ data, false);
+ efivar_unlock();
+ return status;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+index 5e53a52939356..0d939f07d5061 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -703,6 +703,13 @@ err:
+
+ void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
+ {
++ /* Temporary workaround to fix issues observed in some
++ * compute applications when GFXOFF is enabled on GFX11.
++ */
++ if (IP_VERSION_MAJ(adev->ip_versions[GC_HWIP][0]) == 11) {
++ pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
++ amdgpu_gfx_off_ctrl(adev, idle);
++ }
+ amdgpu_dpm_switch_power_profile(adev,
+ PP_SMC_POWER_PROFILE_COMPUTE,
+ !idle);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
+index 0b0a72ca56956..7e80caa05060b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
+@@ -111,7 +111,7 @@ static int init_interrupts_v11(struct amdgpu_device *adev, uint32_t pipe_id)
+
+ lock_srbm(adev, mec, pipe, 0, 0);
+
+- WREG32(SOC15_REG_OFFSET(GC, 0, regCPC_INT_CNTL),
++ WREG32_SOC15(GC, 0, regCPC_INT_CNTL,
+ CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
+ CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+index 9be57389301b4..af5aeb0ec2e92 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+@@ -726,6 +726,12 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
+ adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
+ }
+
++ if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)
++ /* VF MMIO access (except mailbox range) from CPU
++ * will be blocked during sriov runtime
++ */
++ adev->virt.caps |= AMDGPU_VF_MMIO_ACCESS_PROTECT;
++
+ /* we have the ability to check now */
+ if (amdgpu_sriov_vf(adev)) {
+ switch (adev->asic_type) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index 239f232f9c026..617d072275ebe 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -31,6 +31,7 @@
+ #define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */
+ #define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */
+ #define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */
++#define AMDGPU_VF_MMIO_ACCESS_PROTECT (1 << 5) /* MMIO write access is not allowed in sriov runtime */
+
+ /* flags for indirect register access path supported by rlcg for sriov */
+ #define AMDGPU_RLCG_GC_WRITE_LEGACY (0x8 << 28)
+@@ -294,6 +295,9 @@ struct amdgpu_video_codec_info;
+ #define amdgpu_passthrough(adev) \
+ ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
+
++#define amdgpu_sriov_vf_mmio_access_protection(adev) \
++((adev)->virt.caps & AMDGPU_VF_MMIO_ACCESS_PROTECT)
++
+ static inline bool is_virtual_machine(void)
+ {
+ #if defined(CONFIG_X86)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 690fd4f639f19..04130f8813ef1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -2301,7 +2301,11 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
+ */
+ #ifdef CONFIG_X86_64
+ if (amdgpu_vm_update_mode == -1) {
+- if (amdgpu_gmc_vram_full_visible(&adev->gmc))
++ /* For asic with VF MMIO access protection
++ * avoid using CPU for VM table updates
++ */
++ if (amdgpu_gmc_vram_full_visible(&adev->gmc) &&
++ !amdgpu_sriov_vf_mmio_access_protection(adev))
+ adev->vm_manager.vm_update_mode =
+ AMDGPU_VM_USE_CPU_FOR_COMPUTE;
+ else
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index daf8ba8235cd0..03775e0a81004 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -1729,7 +1729,7 @@ static void gfx_v11_0_init_compute_vmid(struct amdgpu_device *adev)
+ WREG32_SOC15(GC, 0, regSH_MEM_BASES, sh_mem_bases);
+
+ /* Enable trap for each kfd vmid. */
+- data = RREG32(SOC15_REG_OFFSET(GC, 0, regSPI_GDBG_PER_VMID_CNTL));
++ data = RREG32_SOC15(GC, 0, regSPI_GDBG_PER_VMID_CNTL);
+ data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
+ }
+ soc21_grbm_select(adev, 0, 0, 0, 0);
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+index 1471bfb9ae38e..2475fdbe80104 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+@@ -185,6 +185,10 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ /* Use register 17 for GART */
+ const unsigned eng = 17;
+ unsigned int i;
++ unsigned char hub_ip = 0;
++
++ hub_ip = (vmhub == AMDGPU_GFXHUB_0) ?
++ GC_HWIP : MMHUB_HWIP;
+
+ spin_lock(&adev->gmc.invalidate_lock);
+ /*
+@@ -198,8 +202,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ if (use_semaphore) {
+ for (i = 0; i < adev->usec_timeout; i++) {
+ /* a read return value of 1 means semaphore acuqire */
+- tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem +
+- hub->eng_distance * eng);
++ tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
++ hub->eng_distance * eng, hub_ip);
+ if (tmp & 0x1)
+ break;
+ udelay(1);
+@@ -209,12 +213,12 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
+ }
+
+- WREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req);
++ WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req, hub_ip);
+
+ /* Wait for ACK with a delay.*/
+ for (i = 0; i < adev->usec_timeout; i++) {
+- tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack +
+- hub->eng_distance * eng);
++ tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_ack +
++ hub->eng_distance * eng, hub_ip);
+ tmp &= 1 << vmid;
+ if (tmp)
+ break;
+@@ -228,8 +232,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ * add semaphore release after invalidation,
+ * write with 0 means semaphore release
+ */
+- WREG32_NO_KIQ(hub->vm_inv_eng0_sem +
+- hub->eng_distance * eng, 0);
++ WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
++ hub->eng_distance * eng, 0, hub_ip);
+
+ /* Issue additional private vm invalidation to MMHUB */
+ if ((vmhub != AMDGPU_GFXHUB_0) &&
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index f92744b8d79df..2dd827472d6e4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -1145,6 +1145,42 @@ static int mes_v11_0_sw_fini(void *handle)
+ return 0;
+ }
+
++static void mes_v11_0_kiq_dequeue_sched(struct amdgpu_device *adev)
++{
++ uint32_t data;
++ int i;
++
++ mutex_lock(&adev->srbm_mutex);
++ soc21_grbm_select(adev, 3, AMDGPU_MES_SCHED_PIPE, 0, 0);
++
++ /* disable the queue if it's active */
++ if (RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1) {
++ WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 1);
++ for (i = 0; i < adev->usec_timeout; i++) {
++ if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
++ break;
++ udelay(1);
++ }
++ }
++ data = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL);
++ data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
++ DOORBELL_EN, 0);
++ data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
++ DOORBELL_HIT, 1);
++ WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, data);
++
++ WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, 0);
++
++ WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_LO, 0);
++ WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_HI, 0);
++ WREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR, 0);
++
++ soc21_grbm_select(adev, 0, 0, 0, 0);
++ mutex_unlock(&adev->srbm_mutex);
++
++ adev->mes.ring.sched.ready = false;
++}
++
+ static void mes_v11_0_kiq_setting(struct amdgpu_ring *ring)
+ {
+ uint32_t tmp;
+@@ -1196,6 +1232,9 @@ failure:
+
+ static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev)
+ {
++ if (adev->mes.ring.sched.ready)
++ mes_v11_0_kiq_dequeue_sched(adev);
++
+ mes_v11_0_enable(adev, false);
+ return 0;
+ }
+@@ -1251,9 +1290,6 @@ failure:
+
+ static int mes_v11_0_hw_fini(void *handle)
+ {
+- struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+-
+- adev->mes.ring.sched.ready = false;
+ return 0;
+ }
+
+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 6d721fadcbee6..7f5e039893e89 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -847,7 +847,7 @@ static const struct resource_caps res_cap_dcn314 = {
+ .num_ddc = 5,
+ .num_vmid = 16,
+ .num_mpc_3dlut = 2,
+- .num_dsc = 3,
++ .num_dsc = 4,
+ };
+
+ static const struct dc_plane_cap plane_cap = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index b6369758b4912..aa976fe4d426d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -119,15 +119,15 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ },
+ },
+ .num_states = 1,
+- .sr_exit_time_us = 12.36,
+- .sr_enter_plus_exit_time_us = 16.72,
++ .sr_exit_time_us = 19.95,
++ .sr_enter_plus_exit_time_us = 24.36,
+ .sr_exit_z8_time_us = 285.0,
+ .sr_enter_plus_exit_z8_time_us = 320,
+ .writeback_latency_us = 12.0,
+ .round_trip_ping_latency_dcfclk_cycles = 263,
+- .urgent_latency_pixel_data_only_us = 4.0,
+- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+- .urgent_latency_vm_data_only_us = 4.0,
++ .urgent_latency_pixel_data_only_us = 9.35,
++ .urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
++ .urgent_latency_vm_data_only_us = 9.35,
+ .fclk_change_latency_us = 20,
+ .usr_retraining_latency_us = 2,
+ .smn_latency_us = 2,
+diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+index e85364dff4e04..5cb3e8634739d 100644
+--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+@@ -262,8 +262,9 @@ struct kfd2kgd_calls {
+ uint32_t queue_id);
+
+ int (*hqd_destroy)(struct amdgpu_device *adev, void *mqd,
+- uint32_t reset_type, unsigned int timeout,
+- uint32_t pipe_id, uint32_t queue_id);
++ enum kfd_preempt_type reset_type,
++ unsigned int timeout, uint32_t pipe_id,
++ uint32_t queue_id);
+
+ bool (*hqd_sdma_is_occupied)(struct amdgpu_device *adev, void *mqd);
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 93f9b8377539a..750d8da84fac4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -210,7 +210,8 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu)
+ return 0;
+
+ if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7)) ||
+- (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)))
++ (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) ||
++ (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)))
+ return 0;
+
+ /* override pptable_id from driver parameter */
+diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
+index 19122bc6d2aba..b5f65b093c106 100644
+--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
+@@ -2747,13 +2747,10 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
+ if (!intel_sdvo_connector)
+ return false;
+
+- if (device == 0) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
++ if (device == 0)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
+- } else if (device == 1) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
++ else if (device == 1)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
+- }
+
+ intel_connector = &intel_sdvo_connector->base;
+ connector = &intel_connector->base;
+@@ -2808,7 +2805,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
+ encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+ connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+
+- intel_sdvo->controlled_output |= type;
+ intel_sdvo_connector->output_flag = type;
+
+ if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+@@ -2849,13 +2845,10 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
+ encoder->encoder_type = DRM_MODE_ENCODER_DAC;
+ connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+
+- if (device == 0) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
++ if (device == 0)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
+- } else if (device == 1) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
++ else if (device == 1)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
+- }
+
+ if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+ kfree(intel_sdvo_connector);
+@@ -2885,13 +2878,10 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+ encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+
+- if (device == 0) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
++ if (device == 0)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
+- } else if (device == 1) {
+- intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
++ else if (device == 1)
+ intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
+- }
+
+ if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+ kfree(intel_sdvo_connector);
+@@ -2926,16 +2916,39 @@ err:
+ return false;
+ }
+
++static u16 intel_sdvo_filter_output_flags(u16 flags)
++{
++ flags &= SDVO_OUTPUT_MASK;
++
++ /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
++ if (!(flags & SDVO_OUTPUT_TMDS0))
++ flags &= ~SDVO_OUTPUT_TMDS1;
++
++ if (!(flags & SDVO_OUTPUT_RGB0))
++ flags &= ~SDVO_OUTPUT_RGB1;
++
++ if (!(flags & SDVO_OUTPUT_LVDS0))
++ flags &= ~SDVO_OUTPUT_LVDS1;
++
++ return flags;
++}
++
+ static bool
+ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ {
+- /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
++ struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev);
++
++ flags = intel_sdvo_filter_output_flags(flags);
++
++ intel_sdvo->controlled_output = flags;
++
++ intel_sdvo_select_ddc_bus(i915, intel_sdvo);
+
+ if (flags & SDVO_OUTPUT_TMDS0)
+ if (!intel_sdvo_dvi_init(intel_sdvo, 0))
+ return false;
+
+- if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
++ if (flags & SDVO_OUTPUT_TMDS1)
+ if (!intel_sdvo_dvi_init(intel_sdvo, 1))
+ return false;
+
+@@ -2956,7 +2969,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ if (!intel_sdvo_analog_init(intel_sdvo, 0))
+ return false;
+
+- if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
++ if (flags & SDVO_OUTPUT_RGB1)
+ if (!intel_sdvo_analog_init(intel_sdvo, 1))
+ return false;
+
+@@ -2964,14 +2977,13 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ if (!intel_sdvo_lvds_init(intel_sdvo, 0))
+ return false;
+
+- if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
++ if (flags & SDVO_OUTPUT_LVDS1)
+ if (!intel_sdvo_lvds_init(intel_sdvo, 1))
+ return false;
+
+- if ((flags & SDVO_OUTPUT_MASK) == 0) {
++ if (flags == 0) {
+ unsigned char bytes[2];
+
+- intel_sdvo->controlled_output = 0;
+ memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
+ DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
+ SDVO_NAME(intel_sdvo),
+@@ -3383,8 +3395,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
+ */
+ intel_sdvo->base.cloneable = 0;
+
+- intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
+-
+ /* Set the input timing to the screen. Assume always input 0. */
+ if (!intel_sdvo_set_target_input(intel_sdvo))
+ goto err_output;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+index c698f95af15fe..629acb403a2c9 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+@@ -6,7 +6,6 @@
+
+ #include <linux/scatterlist.h>
+ #include <linux/slab.h>
+-#include <linux/swiotlb.h>
+
+ #include "i915_drv.h"
+ #include "i915_gem.h"
+@@ -38,22 +37,12 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
+ struct scatterlist *sg;
+ unsigned int sg_page_sizes;
+ unsigned int npages;
+- int max_order;
++ int max_order = MAX_ORDER;
++ unsigned int max_segment;
+ gfp_t gfp;
+
+- max_order = MAX_ORDER;
+-#ifdef CONFIG_SWIOTLB
+- if (is_swiotlb_active(obj->base.dev->dev)) {
+- unsigned int max_segment;
+-
+- max_segment = swiotlb_max_segment();
+- if (max_segment) {
+- max_segment = max_t(unsigned int, max_segment,
+- PAGE_SIZE) >> PAGE_SHIFT;
+- max_order = min(max_order, ilog2(max_segment));
+- }
+- }
+-#endif
++ max_segment = i915_sg_segment_size(i915->drm.dev) >> PAGE_SHIFT;
++ max_order = min(max_order, get_order(max_segment));
+
+ gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
+ if (IS_I965GM(i915) || IS_I965G(i915)) {
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+index 4eed3dd90ba8b..34b9c76cd8e66 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+@@ -194,7 +194,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
+ struct intel_memory_region *mem = obj->mm.region;
+ struct address_space *mapping = obj->base.filp->f_mapping;
+ const unsigned long page_count = obj->base.size / PAGE_SIZE;
+- unsigned int max_segment = i915_sg_segment_size();
++ unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+ struct sg_table *st;
+ struct sgt_iter sgt_iter;
+ struct page *page;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+index 6f3ab7ade41ad..e85cfc36359a4 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+@@ -189,7 +189,7 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
+ struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
+ struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
+ struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
+- const unsigned int max_segment = i915_sg_segment_size();
++ const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+ const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+ struct file *filp = i915_tt->filp;
+ struct sgt_iter sgt_iter;
+@@ -568,7 +568,7 @@ static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
+ ret = sg_alloc_table_from_pages_segment(st,
+ ttm->pages, ttm->num_pages,
+ 0, (unsigned long)ttm->num_pages << PAGE_SHIFT,
+- i915_sg_segment_size(), GFP_KERNEL);
++ i915_sg_segment_size(i915_tt->dev), GFP_KERNEL);
+ if (ret) {
+ st->sgl = NULL;
+ return ERR_PTR(ret);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+index 8423df021b713..e4515d6acd43c 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+@@ -129,7 +129,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj)
+ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
+ {
+ const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
+- unsigned int max_segment = i915_sg_segment_size();
++ unsigned int max_segment = i915_sg_segment_size(obj->base.dev->dev);
+ struct sg_table *st;
+ unsigned int sg_page_sizes;
+ struct page **pvec;
+diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h b/drivers/gpu/drm/i915/i915_scatterlist.h
+index 9ddb3e743a3e5..b0a1db44f8950 100644
+--- a/drivers/gpu/drm/i915/i915_scatterlist.h
++++ b/drivers/gpu/drm/i915/i915_scatterlist.h
+@@ -9,7 +9,8 @@
+
+ #include <linux/pfn.h>
+ #include <linux/scatterlist.h>
+-#include <linux/swiotlb.h>
++#include <linux/dma-mapping.h>
++#include <xen/xen.h>
+
+ #include "i915_gem.h"
+
+@@ -127,19 +128,26 @@ static inline unsigned int i915_sg_dma_sizes(struct scatterlist *sg)
+ return page_sizes;
+ }
+
+-static inline unsigned int i915_sg_segment_size(void)
++static inline unsigned int i915_sg_segment_size(struct device *dev)
+ {
+- unsigned int size = swiotlb_max_segment();
+-
+- if (size == 0)
+- size = UINT_MAX;
+-
+- size = rounddown(size, PAGE_SIZE);
+- /* swiotlb_max_segment_size can return 1 byte when it means one page. */
+- if (size < PAGE_SIZE)
+- size = PAGE_SIZE;
+-
+- return size;
++ size_t max = min_t(size_t, UINT_MAX, dma_max_mapping_size(dev));
++
++ /*
++ * For Xen PV guests pages aren't contiguous in DMA (machine) address
++ * space. The DMA API takes care of that both in dma_alloc_* (by
++ * calling into the hypervisor to make the pages contiguous) and in
++ * dma_map_* (by bounce buffering). But i915 abuses ignores the
++ * coherency aspects of the DMA API and thus can't cope with bounce
++ * buffering actually happening, so add a hack here to force small
++ * allocations and mappings when running in PV mode on Xen.
++ *
++ * Note this will still break if bounce buffering is required for other
++ * reasons, like confidential computing hypervisors or PCIe root ports
++ * with addressing limitations.
++ */
++ if (xen_pv_domain())
++ max = PAGE_SIZE;
++ return round_down(max, PAGE_SIZE);
+ }
+
+ bool i915_sg_trim(struct sg_table *orig_st);
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index 110e83aad9bb4..1aa3700551f4d 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -1031,23 +1031,31 @@ static int dw_mipi_dsi_rockchip_host_attach(void *priv_data,
+ if (ret) {
+ DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n",
+ ret);
+- return ret;
++ goto out;
+ }
+
+ second = dw_mipi_dsi_rockchip_find_second(dsi);
+- if (IS_ERR(second))
+- return PTR_ERR(second);
++ if (IS_ERR(second)) {
++ ret = PTR_ERR(second);
++ goto out;
++ }
+ if (second) {
+ ret = component_add(second, &dw_mipi_dsi_rockchip_ops);
+ if (ret) {
+ DRM_DEV_ERROR(second,
+ "Failed to register component: %d\n",
+ ret);
+- return ret;
++ goto out;
+ }
+ }
+
+ return 0;
++
++out:
++ mutex_lock(&dsi->usage_mutex);
++ dsi->usage_mode = DW_DSI_USAGE_IDLE;
++ mutex_unlock(&dsi->usage_mutex);
++ return ret;
+ }
+
+ static int dw_mipi_dsi_rockchip_host_detach(void *priv_data,
+@@ -1634,5 +1642,11 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
+ .of_match_table = dw_mipi_dsi_rockchip_dt_ids,
+ .pm = &dw_mipi_dsi_rockchip_pm_ops,
+ .name = "dw-mipi-dsi-rockchip",
++ /*
++ * For dual-DSI display, one DSI pokes at the other DSI's
++ * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not
++ * safe for asynchronous probe.
++ */
++ .probe_type = PROBE_FORCE_SYNCHRONOUS,
+ },
+ };
+diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+index c14f888938688..2f4b8f64cbad3 100644
+--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+@@ -565,7 +565,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
+
+ ret = rockchip_hdmi_parse_dt(hdmi);
+ if (ret) {
+- DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
++ if (ret != -EPROBE_DEFER)
++ DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+index 985584147da10..cf8322c300bd5 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+@@ -364,9 +364,12 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
+ {
+ struct rockchip_gem_object *rk_obj;
+ struct drm_gem_object *obj;
++ bool is_framebuffer;
+ int ret;
+
+- rk_obj = rockchip_gem_create_object(drm, size, false);
++ is_framebuffer = drm->fb_helper && file_priv == drm->fb_helper->client.file;
++
++ rk_obj = rockchip_gem_create_object(drm, size, is_framebuffer);
+ if (IS_ERR(rk_obj))
+ return ERR_CAST(rk_obj);
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 780a19a75c3f5..874c6bd787c56 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2869,6 +2869,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+ unsigned long __maybe_unused flags;
+ u32 __maybe_unused value;
++ unsigned long rate;
+ int ret;
+
+ /*
+@@ -2884,6 +2885,21 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ if (ret)
+ return ret;
+
++ /*
++ * Whenever the RaspberryPi boots without an HDMI monitor
++ * plugged in, the firmware won't have initialized the HSM clock
++ * rate and it will be reported as 0.
++ *
++ * If we try to access a register of the controller in such a
++ * case, it will lead to a silent CPU stall. Let's make sure we
++ * prevent such a case.
++ */
++ rate = clk_get_rate(vc4_hdmi->hsm_clock);
++ if (!rate) {
++ ret = -EINVAL;
++ goto err_disable_clk;
++ }
++
+ if (vc4_hdmi->variant->reset)
+ vc4_hdmi->variant->reset(vc4_hdmi);
+
+@@ -2905,6 +2921,10 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ #endif
+
+ return 0;
++
++err_disable_clk:
++ clk_disable_unprepare(vc4_hdmi->hsm_clock);
++ return ret;
+ }
+
+ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 043cf1cc87946..256795ed6247e 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -867,6 +867,7 @@
+ #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540
+ #define USB_DEVICE_ID_MADCATZ_RAT5 0x1705
+ #define USB_DEVICE_ID_MADCATZ_RAT9 0x1709
++#define USB_DEVICE_ID_MADCATZ_MMO7 0x1713
+
+ #define USB_VENDOR_ID_MCC 0x09db
+ #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 70f602c64fd13..50e1c717fc0a3 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -620,6 +620,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) },
+ #endif
+ #if IS_ENABLED(CONFIG_HID_SAMSUNG)
+ { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
+diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c
+index c7bf14c019605..b84e975977c42 100644
+--- a/drivers/hid/hid-saitek.c
++++ b/drivers/hid/hid-saitek.c
+@@ -187,6 +187,8 @@ static const struct hid_device_id saitek_devices[] = {
+ .driver_data = SAITEK_RELEASE_MODE_RAT7 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7),
+ .driver_data = SAITEK_RELEASE_MODE_MMO7 },
++ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7),
++ .driver_data = SAITEK_RELEASE_MODE_MMO7 },
+ { }
+ };
+
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index 39cb1b7bb8656..809fbd014cd68 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -1080,6 +1080,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ "", &piix4_main_adapters[0]);
+ if (retval < 0)
+ return retval;
++ piix4_adapter_count = 1;
+ }
+
+ /* Check for auxiliary SMBus on some AMD chipsets */
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index b3fe6b2aa3ca9..277a02455cddd 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -920,6 +920,7 @@ static struct platform_driver xiic_i2c_driver = {
+
+ module_platform_driver(xiic_i2c_driver);
+
++MODULE_ALIAS("platform:" DRIVER_NAME);
+ MODULE_AUTHOR("info@mocean-labs.com");
+ MODULE_DESCRIPTION("Xilinx I2C bus driver");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
+index 130e8dd6f0c89..7719f7f93c3f0 100644
+--- a/drivers/iio/adc/stm32-adc.c
++++ b/drivers/iio/adc/stm32-adc.c
+@@ -2064,18 +2064,19 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
+ stm32_adc_chan_init_one(indio_dev, &channels[scan_index], val,
+ vin[1], scan_index, differential);
+
++ val = 0;
+ ret = of_property_read_u32(child, "st,min-sample-time-ns", &val);
+ /* st,min-sample-time-ns is optional */
+- if (!ret) {
+- stm32_adc_smpr_init(adc, channels[scan_index].channel, val);
+- if (differential)
+- stm32_adc_smpr_init(adc, vin[1], val);
+- } else if (ret != -EINVAL) {
++ if (ret && ret != -EINVAL) {
+ dev_err(&indio_dev->dev, "Invalid st,min-sample-time-ns property %d\n",
+ ret);
+ goto err;
+ }
+
++ stm32_adc_smpr_init(adc, channels[scan_index].channel, val);
++ if (differential)
++ stm32_adc_smpr_init(adc, vin[1], val);
++
+ scan_index++;
+ }
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index be317f2665a9e..ff8821f79feca 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -1556,7 +1556,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
+ return false;
+
+ memset(&fl4, 0, sizeof(fl4));
+- fl4.flowi4_iif = net_dev->ifindex;
++ fl4.flowi4_oif = net_dev->ifindex;
+ fl4.daddr = daddr;
+ fl4.saddr = saddr;
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index d275db195f1a1..4053a09b8d33e 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -2815,10 +2815,18 @@ static int __init ib_core_init(void)
+
+ nldev_init();
+ rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table);
+- roce_gid_mgmt_init();
++ ret = roce_gid_mgmt_init();
++ if (ret) {
++ pr_warn("Couldn't init RoCE GID management\n");
++ goto err_parent;
++ }
+
+ return 0;
+
++err_parent:
++ rdma_nl_unregister(RDMA_NL_LS);
++ nldev_exit();
++ unregister_pernet_device(&rdma_dev_net_ops);
+ err_compat:
+ unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+ err_sa:
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index b92358f606d00..12dc97067ed2b 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -2537,7 +2537,7 @@ void __init nldev_init(void)
+ rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table);
+ }
+
+-void __exit nldev_exit(void)
++void nldev_exit(void)
+ {
+ rdma_nl_unregister(RDMA_NL_NLDEV);
+ }
+diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
+index 3d42bd2b36bd4..51ae58c02b15c 100644
+--- a/drivers/infiniband/hw/hfi1/pio.c
++++ b/drivers/infiniband/hw/hfi1/pio.c
+@@ -913,8 +913,7 @@ void sc_disable(struct send_context *sc)
+ spin_unlock(&sc->release_lock);
+
+ write_seqlock(&sc->waitlock);
+- if (!list_empty(&sc->piowait))
+- list_move(&sc->piowait, &wake_list);
++ list_splice_init(&sc->piowait, &wake_list);
+ write_sequnlock(&sc->waitlock);
+ while (!list_empty(&wake_list)) {
+ struct iowait *wait;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index c780646bd60ac..105888c6ccb77 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -118,7 +118,6 @@ static const u32 hns_roce_op_code[] = {
+ HR_OPC_MAP(ATOMIC_CMP_AND_SWP, ATOM_CMP_AND_SWAP),
+ HR_OPC_MAP(ATOMIC_FETCH_AND_ADD, ATOM_FETCH_AND_ADD),
+ HR_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV),
+- HR_OPC_MAP(LOCAL_INV, LOCAL_INV),
+ HR_OPC_MAP(MASKED_ATOMIC_CMP_AND_SWP, ATOM_MSK_CMP_AND_SWAP),
+ HR_OPC_MAP(MASKED_ATOMIC_FETCH_AND_ADD, ATOM_MSK_FETCH_AND_ADD),
+ HR_OPC_MAP(REG_MR, FAST_REG_PMR),
+@@ -560,9 +559,6 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev,
+ else
+ ret = -EOPNOTSUPP;
+ break;
+- case IB_WR_LOCAL_INV:
+- hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO);
+- fallthrough;
+ case IB_WR_SEND_WITH_INV:
+ rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
+ break;
+@@ -2809,8 +2805,12 @@ static int free_mr_modify_qp(struct hns_roce_dev *hr_dev)
+
+ static int free_mr_init(struct hns_roce_dev *hr_dev)
+ {
++ struct hns_roce_v2_priv *priv = hr_dev->priv;
++ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
+ int ret;
+
++ mutex_init(&free_mr->mutex);
++
+ ret = free_mr_alloc_res(hr_dev);
+ if (ret)
+ return ret;
+@@ -3226,7 +3226,6 @@ static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev,
+
+ hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID);
+ hr_reg_write(mpt_entry, MPT_PD, mr->pd);
+- hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+
+ hr_reg_write_bool(mpt_entry, MPT_BIND_EN,
+ mr->access & IB_ACCESS_MW_BIND);
+@@ -3317,7 +3316,6 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
+
+ hr_reg_enable(mpt_entry, MPT_RA_EN);
+ hr_reg_enable(mpt_entry, MPT_R_INV_EN);
+- hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+
+ hr_reg_enable(mpt_entry, MPT_FRE);
+ hr_reg_clear(mpt_entry, MPT_MR_MW);
+@@ -3349,7 +3347,6 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw)
+ hr_reg_write(mpt_entry, MPT_PD, mw->pdn);
+
+ hr_reg_enable(mpt_entry, MPT_R_INV_EN);
+- hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+ hr_reg_enable(mpt_entry, MPT_LW_EN);
+
+ hr_reg_enable(mpt_entry, MPT_MR_MW);
+@@ -3798,7 +3795,6 @@ static const u32 wc_send_op_map[] = {
+ HR_WC_OP_MAP(RDMA_READ, RDMA_READ),
+ HR_WC_OP_MAP(RDMA_WRITE, RDMA_WRITE),
+ HR_WC_OP_MAP(RDMA_WRITE_WITH_IMM, RDMA_WRITE),
+- HR_WC_OP_MAP(LOCAL_INV, LOCAL_INV),
+ HR_WC_OP_MAP(ATOM_CMP_AND_SWAP, COMP_SWAP),
+ HR_WC_OP_MAP(ATOM_FETCH_AND_ADD, FETCH_ADD),
+ HR_WC_OP_MAP(ATOM_MSK_CMP_AND_SWAP, MASKED_COMP_SWAP),
+@@ -3848,9 +3844,6 @@ static void fill_send_wc(struct ib_wc *wc, struct hns_roce_v2_cqe *cqe)
+ case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM:
+ wc->wc_flags |= IB_WC_WITH_IMM;
+ break;
+- case HNS_ROCE_V2_WQE_OP_LOCAL_INV:
+- wc->wc_flags |= IB_WC_WITH_INVALIDATE;
+- break;
+ case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP:
+ case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD:
+ case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP:
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 64797109bab63..4544a8775ce5a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -182,7 +182,6 @@ enum {
+ HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP = 0x8,
+ HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9,
+ HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa,
+- HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb,
+ HNS_ROCE_V2_WQE_OP_BIND_MW = 0xc,
+ HNS_ROCE_V2_WQE_OP_MASK = 0x1f,
+ };
+@@ -916,7 +915,6 @@ 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/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
+index 5152f10d2e6de..ba0c3e4c07d85 100644
+--- a/drivers/infiniband/hw/qedr/main.c
++++ b/drivers/infiniband/hw/qedr/main.c
+@@ -344,6 +344,10 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
+ if (IS_IWARP(dev)) {
+ xa_init(&dev->qps);
+ dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq");
++ if (!dev->iwarp_wq) {
++ rc = -ENOMEM;
++ goto err1;
++ }
+ }
+
+ /* Allocate Status blocks for CNQ */
+@@ -351,7 +355,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
+ GFP_KERNEL);
+ if (!dev->sb_array) {
+ rc = -ENOMEM;
+- goto err1;
++ goto err_destroy_wq;
+ }
+
+ dev->cnq_array = kcalloc(dev->num_cnq,
+@@ -402,6 +406,9 @@ err3:
+ kfree(dev->cnq_array);
+ err2:
+ kfree(dev->sb_array);
++err_destroy_wq:
++ if (IS_IWARP(dev))
++ destroy_workqueue(dev->iwarp_wq);
+ err1:
+ kfree(dev->sgid_tbl);
+ return rc;
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index 7c336db5cb547..f8b1d9fa04941 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -806,8 +806,10 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+
+ skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload,
+ res->cur_psn, AETH_ACK_UNLIMITED);
+- if (!skb)
++ if (!skb) {
++ rxe_put(mr);
+ return RESPST_ERR_RNR;
++ }
+
+ rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
+ payload, RXE_FROM_MR_OBJ);
+diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
+index a52f275f82634..f8447135a9022 100644
+--- a/drivers/isdn/hardware/mISDN/netjet.c
++++ b/drivers/isdn/hardware/mISDN/netjet.c
+@@ -956,7 +956,7 @@ nj_release(struct tiger_hw *card)
+ }
+ if (card->irq > 0)
+ free_irq(card->irq, card);
+- if (card->isac.dch.dev.dev.class)
++ if (device_is_registered(&card->isac.dch.dev.dev))
+ mISDN_unregister_device(&card->isac.dch.dev);
+
+ for (i = 0; i < 2; i++) {
+diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
+index a41b4b2645941..7ea0100f218a0 100644
+--- a/drivers/isdn/mISDN/core.c
++++ b/drivers/isdn/mISDN/core.c
+@@ -233,11 +233,12 @@ mISDN_register_device(struct mISDNdevice *dev,
+ if (debug & DEBUG_CORE)
+ printk(KERN_DEBUG "mISDN_register %s %d\n",
+ dev_name(&dev->dev), dev->id);
++ dev->dev.class = &mISDN_class;
++
+ err = create_stack(dev);
+ if (err)
+ goto error1;
+
+- dev->dev.class = &mISDN_class;
+ dev->dev.platform_data = dev;
+ dev->dev.parent = parent;
+ dev_set_drvdata(&dev->dev, dev);
+@@ -249,8 +250,8 @@ mISDN_register_device(struct mISDNdevice *dev,
+
+ error3:
+ delete_stack(dev);
+- return err;
+ error1:
++ put_device(&dev->dev);
+ return err;
+
+ }
+diff --git a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
+index 3b583ed4da9df..6ebedc71d67d4 100644
+--- a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
++++ b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
+@@ -44,6 +44,8 @@ static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+ uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+ unsigned int len = cros_ec->event_size;
+
++ if (len > CEC_MAX_MSG_SIZE)
++ len = CEC_MAX_MSG_SIZE;
+ cros_ec_cec->rx_msg.len = len;
+ memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+@@ -221,6 +223,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
+ { "Google", "Moli", "0000:00:02.0", "Port B" },
+ /* Google Kinox */
+ { "Google", "Kinox", "0000:00:02.0", "Port B" },
++ /* Google Kuldax */
++ { "Google", "Kuldax", "0000:00:02.0", "Port B" },
+ };
+
+ static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c
+index ce9a9d922f116..0a30e7acdc10e 100644
+--- a/drivers/media/cec/platform/s5p/s5p_cec.c
++++ b/drivers/media/cec/platform/s5p/s5p_cec.c
+@@ -115,6 +115,8 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
+ dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
+ cec->rx = STATE_BUSY;
+ cec->msg.len = status >> 24;
++ if (cec->msg.len > CEC_MAX_MSG_SIZE)
++ cec->msg.len = CEC_MAX_MSG_SIZE;
+ cec->msg.rx_status = CEC_RX_STATUS_OK;
+ s5p_cec_get_rx_buf(cec, cec->msg.len,
+ cec->msg.msg);
+diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
+index 9430295a8175c..ef0d063ec3526 100644
+--- a/drivers/media/dvb-frontends/drxk_hard.c
++++ b/drivers/media/dvb-frontends/drxk_hard.c
+@@ -6660,7 +6660,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
+ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+ {
+ struct drxk_state *state = fe->demodulator_priv;
+- u16 err;
++ u16 err = 0;
+
+ dprintk(1, "\n");
+
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+index d5904c96ff3fc..c66963a2ccd99 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+@@ -1273,11 +1273,12 @@ static int rkisp1_capture_link_validate(struct media_link *link)
+ struct rkisp1_capture *cap = video_get_drvdata(vdev);
+ const struct rkisp1_capture_fmt_cfg *fmt =
+ rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
+- struct v4l2_subdev_format sd_fmt;
++ struct v4l2_subdev_format sd_fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = link->source->index,
++ };
+ int ret;
+
+- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+- sd_fmt.pad = link->source->index;
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+ if (ret)
+ return ret;
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+index 383a3ec83ca9f..00032b849a076 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+@@ -472,23 +472,43 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+ struct v4l2_mbus_framefmt *format,
+ unsigned int which)
+ {
+- const struct rkisp1_mbus_info *mbus_info;
++ const struct rkisp1_mbus_info *sink_info;
++ const struct rkisp1_mbus_info *src_info;
++ struct v4l2_mbus_framefmt *sink_fmt;
+ struct v4l2_mbus_framefmt *src_fmt;
+ const struct v4l2_rect *src_crop;
+
++ sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
++ RKISP1_ISP_PAD_SINK_VIDEO, which);
+ src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ src_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+
++ /*
++ * Media bus code. The ISP can operate in pass-through mode (Bayer in,
++ * Bayer out or YUV in, YUV out) or process Bayer data to YUV, but
++ * can't convert from YUV to Bayer.
++ */
++ sink_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
++
+ src_fmt->code = format->code;
+- mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
+- if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
++ src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
++ if (!src_info || !(src_info->direction & RKISP1_ISP_SD_SRC)) {
+ src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+- mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
++ src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
+ }
+- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+- isp->src_fmt = mbus_info;
++
++ if (sink_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
++ src_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
++ src_fmt->code = sink_fmt->code;
++ src_info = sink_info;
++ }
++
++ /*
++ * The source width and height must be identical to the source crop
++ * size.
++ */
+ src_fmt->width = src_crop->width;
+ src_fmt->height = src_crop->height;
+
+@@ -498,14 +518,18 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+ */
+ if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
+ format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
+- mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
++ src_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+- else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
++ else if (src_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+ else
+ src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+ *format = *src_fmt;
++
++ /* Store the source format info when setting the active format. */
++ if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
++ isp->src_fmt = src_info;
+ }
+
+ static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+index 9da7dc1bc6909..02ac3043badd4 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+@@ -343,7 +343,7 @@ static void rkisp1_lsc_config(struct rkisp1_params *params,
+ RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4, data);
+
+ /* program x grad tables */
+- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
++ data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2],
+ arg->x_grad_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4, data);
+@@ -355,7 +355,7 @@ static void rkisp1_lsc_config(struct rkisp1_params *params,
+ RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4, data);
+
+ /* program y grad tables */
+- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
++ data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2],
+ arg->y_grad_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4, data);
+@@ -1066,7 +1066,7 @@ static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
+ }
+ }
+
+-static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
++static void rkisp1_csm_config(struct rkisp1_params *params)
+ {
+ static const u16 full_range_coeff[] = {
+ 0x0026, 0x004b, 0x000f,
+@@ -1080,7 +1080,7 @@ static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
+ };
+ unsigned int i;
+
+- if (full_range) {
++ if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) {
+ for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_CC_COEFF_0 + i * 4,
+@@ -1552,11 +1552,7 @@ static void rkisp1_params_config_parameter(struct rkisp1_params *params)
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
+ rkisp1_hst_params_default_config.mode);
+
+- /* set the range */
+- if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+- rkisp1_csm_config(params, true);
+- else
+- rkisp1_csm_config(params, false);
++ rkisp1_csm_config(params);
+
+ spin_lock_irq(¶ms->config_lock);
+
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+index dd3e6c38be677..025491f8793f6 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+@@ -576,7 +576,7 @@
+ (((v0) & 0x1FFF) | (((v1) & 0x1FFF) << 13))
+ #define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1) \
+ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+-#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1) \
++#define RKISP1_CIF_ISP_LSC_SECT_GRAD(v0, v1) \
+ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+
+ /* LSC: ISP_LSC_TABLE_SEL */
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+index f4caa8f684aad..a2dc6f60d9cf6 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+@@ -411,6 +411,10 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
+ sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+ sink_fmt->field = V4L2_FIELD_NONE;
+ sink_fmt->code = RKISP1_DEF_FMT;
++ sink_fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
++ sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
++ sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+
+ sink_crop = v4l2_subdev_get_try_crop(sd, sd_state,
+ RKISP1_RSZ_PAD_SINK);
+diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
+index 263e41191c292..0d20ebafbd03a 100644
+--- a/drivers/net/dsa/dsa_loop.c
++++ b/drivers/net/dsa/dsa_loop.c
+@@ -378,6 +378,17 @@ static struct mdio_driver dsa_loop_drv = {
+
+ #define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2)
+
++static void dsa_loop_phydevs_unregister(void)
++{
++ unsigned int i;
++
++ for (i = 0; i < NUM_FIXED_PHYS; i++)
++ if (!IS_ERR(phydevs[i])) {
++ fixed_phy_unregister(phydevs[i]);
++ phy_device_free(phydevs[i]);
++ }
++}
++
+ static int __init dsa_loop_init(void)
+ {
+ struct fixed_phy_status status = {
+@@ -385,23 +396,23 @@ static int __init dsa_loop_init(void)
+ .speed = SPEED_100,
+ .duplex = DUPLEX_FULL,
+ };
+- unsigned int i;
++ unsigned int i, ret;
+
+ for (i = 0; i < NUM_FIXED_PHYS; i++)
+ phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL);
+
+- return mdio_driver_register(&dsa_loop_drv);
++ ret = mdio_driver_register(&dsa_loop_drv);
++ if (ret)
++ dsa_loop_phydevs_unregister();
++
++ return ret;
+ }
+ module_init(dsa_loop_init);
+
+ static void __exit dsa_loop_exit(void)
+ {
+- unsigned int i;
+-
+ mdio_driver_unregister(&dsa_loop_drv);
+- for (i = 0; i < NUM_FIXED_PHYS; i++)
+- if (!IS_ERR(phydevs[i]))
+- fixed_phy_unregister(phydevs[i]);
++ dsa_loop_phydevs_unregister();
+ }
+ module_exit(dsa_loop_exit);
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index a486435ceee2c..5aa254eaa8d02 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -657,7 +657,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+ dev_kfree_skb_any(skb);
+ if (net_ratelimit())
+ netdev_err(ndev, "Tx DMA memory map failed\n");
+- return NETDEV_TX_BUSY;
++ return NETDEV_TX_OK;
+ }
+
+ bdp->cbd_datlen = cpu_to_fec16(size);
+@@ -719,7 +719,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+ dev_kfree_skb_any(skb);
+ if (net_ratelimit())
+ netdev_err(ndev, "Tx DMA memory map failed\n");
+- return NETDEV_TX_BUSY;
++ return NETDEV_TX_OK;
+ }
+ }
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 5ab7c0f81e9af..e6b141536879f 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -3007,19 +3007,19 @@ static void __ibmvnic_reset(struct work_struct *work)
+ rwi = get_next_rwi(adapter);
+
+ /*
+- * If there is another reset queued, free the previous rwi
+- * and process the new reset even if previous reset failed
+- * (the previous reset could have failed because of a fail
+- * over for instance, so process the fail over).
+- *
+ * If there are no resets queued and the previous reset failed,
+ * the adapter would be in an undefined state. So retry the
+ * previous reset as a hard reset.
++ *
++ * Else, free the previous rwi and, if there is another reset
++ * queued, process the new reset even if previous reset failed
++ * (the previous reset could have failed because of a fail
++ * over for instance, so process the fail over).
+ */
+- if (rwi)
+- kfree(tmprwi);
+- else if (rc)
++ if (!rwi && rc)
+ rwi = tmprwi;
++ else
++ kfree(tmprwi);
+
+ if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
+ rwi->reset_reason == VNIC_RESET_MOBILITY || rc))
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+index 69f741db25b1f..3a1a0f9178c01 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+@@ -414,13 +414,15 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ /* Get the received frame and unmap it */
+ db = &rx->dcbs[rx->dcb_index].db[rx->db_index];
+ page = rx->page[rx->dcb_index][rx->db_index];
++
++ dma_sync_single_for_cpu(lan966x->dev, (dma_addr_t)db->dataptr,
++ FDMA_DCB_STATUS_BLOCKL(db->status),
++ DMA_FROM_DEVICE);
++
+ skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order);
+ if (unlikely(!skb))
+ goto unmap_page;
+
+- dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr,
+- FDMA_DCB_STATUS_BLOCKL(db->status),
+- DMA_FROM_DEVICE);
+ skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
+
+ lan966x_ifh_get_src_port(skb->data, &src_port);
+@@ -429,6 +431,10 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ if (WARN_ON(src_port >= lan966x->num_phys_ports))
+ goto free_skb;
+
++ dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
++ PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++
+ skb->dev = lan966x->ports[src_port]->dev;
+ skb_pull(skb, IFH_LEN * sizeof(u32));
+
+@@ -454,9 +460,9 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ free_skb:
+ kfree_skb(skb);
+ unmap_page:
+- dma_unmap_page(lan966x->dev, (dma_addr_t)db->dataptr,
+- FDMA_DCB_STATUS_BLOCKL(db->status),
+- DMA_FROM_DEVICE);
++ dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
++ PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
+ __free_pages(page, rx->page_order);
+
+ return NULL;
+@@ -668,12 +674,14 @@ static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x)
+ int i;
+
+ for (i = 0; i < lan966x->num_phys_ports; ++i) {
++ struct lan966x_port *port;
+ int mtu;
+
+- if (!lan966x->ports[i])
++ port = lan966x->ports[i];
++ if (!port)
+ continue;
+
+- mtu = lan966x->ports[i]->dev->mtu;
++ mtu = lan_rd(lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ if (mtu > max_mtu)
+ max_mtu = mtu;
+ }
+@@ -733,6 +741,8 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
+
+ max_mtu = lan966x_fdma_get_max_mtu(lan966x);
+ max_mtu += IFH_LEN * sizeof(u32);
++ max_mtu += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++ max_mtu += VLAN_HLEN * 2;
+
+ if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
+ lan966x->rx.page_order)
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+index d928b75f37803..4a3cb75794202 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+@@ -385,7 +385,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
+ int old_mtu = dev->mtu;
+ int err;
+
+- lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(new_mtu),
++ lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(new_mtu)),
+ lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ dev->mtu = new_mtu;
+
+@@ -394,7 +394,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
+
+ err = lan966x_fdma_change_mtu(lan966x);
+ if (err) {
+- lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(old_mtu),
++ lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(old_mtu)),
+ lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ dev->mtu = old_mtu;
+ }
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+index 2787055c18475..e316bfe186d74 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+@@ -24,6 +24,8 @@
+ #define LAN966X_BUFFER_MEMORY (160 * 1024)
+ #define LAN966X_BUFFER_MIN_SZ 60
+
++#define LAN966X_HW_MTU(mtu) ((mtu) + ETH_HLEN + ETH_FCS_LEN)
++
+ #define PGID_AGGR 64
+ #define PGID_SRC 80
+ #define PGID_ENTRIES 89
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+index 8265ad89f0bcb..357ecc2f1089d 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+@@ -444,6 +444,21 @@ enum lan966x_target {
+ #define DEV_MAC_MAXLEN_CFG_MAX_LEN_GET(x)\
+ FIELD_GET(DEV_MAC_MAXLEN_CFG_MAX_LEN, x)
+
++/* DEV:MAC_CFG_STATUS:MAC_TAGS_CFG */
++#define DEV_MAC_TAGS_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 12, 0, 1, 4)
++
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA BIT(1)
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(x)\
++ FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_GET(x)\
++ FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
++
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
++ FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
++ FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
++
+ /* DEV:MAC_CFG_STATUS:MAC_IFG_CFG */
+ #define DEV_MAC_IFG_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 20, 0, 1, 4)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+index 8d7260cd7da9c..3c44660128dae 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+@@ -169,6 +169,12 @@ void lan966x_vlan_port_apply(struct lan966x_port *port)
+ ANA_VLAN_CFG_VLAN_POP_CNT,
+ lan966x, ANA_VLAN_CFG(port->chip_port));
+
++ lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) |
++ DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware),
++ DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
++ DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA,
++ lan966x, DEV_MAC_TAGS_CFG(port->chip_port));
++
+ /* Drop frames with multicast source address */
+ val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
+ if (port->vlan_aware && !pvid)
+diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
+index 153d68e29b8b3..68a68477ab7bc 100644
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -1059,8 +1059,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
+
+ /* Allocate and initialise a struct net_device */
+ net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES);
+- if (!net_dev)
+- return -ENOMEM;
++ if (!net_dev) {
++ rc = -ENOMEM;
++ goto fail0;
++ }
+ probe_ptr = netdev_priv(net_dev);
+ *probe_ptr = probe_data;
+ efx->net_dev = net_dev;
+@@ -1132,6 +1134,8 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
+ WARN_ON(rc > 0);
+ netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc);
+ free_netdev(net_dev);
++ fail0:
++ kfree(probe_data);
+ return rc;
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index 017dbbda0c1c4..79fa7870563b8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -51,7 +51,6 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ struct stmmac_resources res;
+ struct device_node *np;
+ int ret, i, phy_mode;
+- bool mdio = false;
+
+ np = dev_of_node(&pdev->dev);
+
+@@ -69,12 +68,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ if (!plat)
+ return -ENOMEM;
+
++ plat->mdio_node = of_get_child_by_name(np, "mdio");
+ if (plat->mdio_node) {
+- dev_err(&pdev->dev, "Found MDIO subnode\n");
+- mdio = true;
+- }
++ dev_info(&pdev->dev, "Found MDIO subnode\n");
+
+- if (mdio) {
+ plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+ sizeof(*plat->mdio_bus_data),
+ GFP_KERNEL);
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 8a2dbe849866d..1bc988d9f2e8a 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -583,7 +583,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; i++) {
+- if ((bus->phy_mask & (1 << i)) == 0) {
++ if ((bus->phy_mask & BIT(i)) == 0) {
+ struct phy_device *phydev;
+
+ phydev = mdiobus_scan(bus, i);
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index db736b944016e..b02bd0a6c0a93 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1459,7 +1459,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
+ int err;
+ int i;
+
+- if (it->nr_segs > MAX_SKB_FRAGS + 1)
++ if (it->nr_segs > MAX_SKB_FRAGS + 1 ||
++ len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN))
+ return ERR_PTR(-EMSGSIZE);
+
+ local_bh_disable();
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+index bc3f4e4edcdf9..dac7eb77799bd 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+@@ -228,6 +228,10 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
+ brcmf_fweh_event_name(event->code), event->code,
+ event->emsg.ifidx, event->emsg.bsscfgidx,
+ event->emsg.addr);
++ if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) {
++ bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx);
++ goto event_free;
++ }
+
+ /* convert event message */
+ emsg_be = &event->emsg;
+diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c
+index c6b3334f24c9e..f12f903a9dd13 100644
+--- a/drivers/nfc/fdp/fdp.c
++++ b/drivers/nfc/fdp/fdp.c
+@@ -249,11 +249,19 @@ static int fdp_nci_close(struct nci_dev *ndev)
+ static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ {
+ struct fdp_nci_info *info = nci_get_drvdata(ndev);
++ int ret;
+
+ if (atomic_dec_and_test(&info->data_pkt_counter))
+ info->data_pkt_counter_cb(ndev);
+
+- return info->phy_ops->write(info->phy, skb);
++ ret = info->phy_ops->write(info->phy, skb);
++ if (ret < 0) {
++ kfree_skb(skb);
++ return ret;
++ }
++
++ consume_skb(skb);
++ return 0;
+ }
+
+ static int fdp_nci_request_firmware(struct nci_dev *ndev)
+diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
+index 01329b91d59d5..a902720cd8493 100644
+--- a/drivers/nfc/nfcmrvl/i2c.c
++++ b/drivers/nfc/nfcmrvl/i2c.c
+@@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
+ ret = -EREMOTEIO;
+ } else
+ ret = 0;
++ }
++
++ if (ret) {
+ kfree_skb(skb);
++ return ret;
+ }
+
+- return ret;
++ consume_skb(skb);
++ return 0;
+ }
+
+ static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
+diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c
+index 7c93d484dc1bc..580cb6ecffee4 100644
+--- a/drivers/nfc/nxp-nci/core.c
++++ b/drivers/nfc/nxp-nci/core.c
+@@ -80,10 +80,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ return -EINVAL;
+
+ r = info->phy_ops->write(info->phy_id, skb);
+- if (r < 0)
++ if (r < 0) {
+ kfree_skb(skb);
++ return r;
++ }
+
+- return r;
++ consume_skb(skb);
++ return 0;
+ }
+
+ static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
+diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c
+index 1c412007fabb6..0270e05b68dff 100644
+--- a/drivers/nfc/s3fwrn5/core.c
++++ b/drivers/nfc/s3fwrn5/core.c
+@@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ }
+
+ ret = s3fwrn5_write(info, skb);
+- if (ret < 0)
++ if (ret < 0) {
+ kfree_skb(skb);
++ mutex_unlock(&info->mutex);
++ return ret;
++ }
+
++ consume_skb(skb);
+ mutex_unlock(&info->mutex);
+- return ret;
++ return 0;
+ }
+
+ static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 57cc2bb5b1a2b..554468ea5a2a9 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3508,6 +3508,16 @@ static const struct pci_device_id nvme_id_table[] = {
+ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
+ { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */
+ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
++ { PCI_DEVICE(0x2646, 0x5018), /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */
++ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++ { PCI_DEVICE(0x2646, 0x5016), /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */
++ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++ { PCI_DEVICE(0x2646, 0x501A), /* KINGSTON OM8PGP4xxxxP OS21005 NVMe SSD */
++ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++ { PCI_DEVICE(0x2646, 0x501B), /* KINGSTON OM8PGP4xxxxQ OS21005 NVMe SSD */
++ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++ { PCI_DEVICE(0x2646, 0x501E), /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
++ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ { PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */
+ .driver_data = NVME_QUIRK_BOGUS_NID, },
+ { PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */
+diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
+index bdef7a8d6ab8e..bcc1dae007803 100644
+--- a/drivers/parisc/iosapic.c
++++ b/drivers/parisc/iosapic.c
+@@ -866,6 +866,7 @@ int iosapic_serial_irq(struct parisc_device *dev)
+
+ return vi->txn_irq;
+ }
++EXPORT_SYMBOL(iosapic_serial_irq);
+ #endif
+
+
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 5d61f58399dca..dc41d7c6b9b19 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -828,6 +828,14 @@ store_state_field(struct device *dev, struct device_attribute *attr,
+ }
+
+ mutex_lock(&sdev->state_mutex);
++ switch (sdev->sdev_state) {
++ case SDEV_RUNNING:
++ case SDEV_OFFLINE:
++ break;
++ default:
++ mutex_unlock(&sdev->state_mutex);
++ return -EINVAL;
++ }
+ if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) {
+ ret = 0;
+ } else {
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index 2036f72eeb4af..1dd8312d824ce 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -251,6 +251,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+
+ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ {
++ struct hantro_ctx *ctx;
++
++ ctx = container_of(ctrl->handler,
++ struct hantro_ctx, ctrl_handler);
++
+ if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
+ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+@@ -272,6 +277,8 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ if (sps->bit_depth_luma_minus8 != 0)
+ /* Only 8-bit is supported */
+ return -EINVAL;
++
++ ctx->bit_depth = sps->bit_depth_luma_minus8 + 8;
+ } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+ const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 233ecd863d5f1..a917079a6ed30 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -12,7 +12,7 @@
+
+ static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx)
+ {
+- return ctx->dst_fmt.width * ctx->dst_fmt.height;
++ return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8;
+ }
+
+ static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx)
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index b990bc98164c3..9383fb7081f6c 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -104,7 +104,7 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ hevc_dec->tile_bsd.cpu = NULL;
+ }
+
+- size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1);
++ size = (VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8;
+ hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size,
+ &hevc_dec->tile_filter.dma,
+ GFP_KERNEL);
+@@ -112,7 +112,7 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ goto err_free_tile_buffers;
+ hevc_dec->tile_filter.size = size;
+
+- size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1);
++ size = (VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8;
+ hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size,
+ &hevc_dec->tile_sao.dma,
+ GFP_KERNEL);
+diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
+index 8549d95be0f25..52f224d8def10 100644
+--- a/drivers/staging/media/meson/vdec/vdec.c
++++ b/drivers/staging/media/meson/vdec/vdec.c
+@@ -1102,6 +1102,7 @@ static int vdec_probe(struct platform_device *pdev)
+
+ err_vdev_release:
+ video_device_release(vdev);
++ v4l2_device_unregister(&core->v4l2_dev);
+ return ret;
+ }
+
+@@ -1110,6 +1111,7 @@ static int vdec_remove(struct platform_device *pdev)
+ struct amvdec_core *core = platform_get_drvdata(pdev);
+
+ video_unregister_device(core->vdev_dec);
++ v4l2_device_unregister(&core->v4l2_dev);
+
+ return 0;
+ }
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index d0b49e15fbf5e..7b3ffb7f50aba 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -118,7 +118,7 @@ config SERIAL_8250_CONSOLE
+
+ config SERIAL_8250_GSC
+ tristate
+- depends on SERIAL_8250 && GSC
++ depends on SERIAL_8250 && PARISC
+ default SERIAL_8250
+
+ config SERIAL_8250_DMA
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index ccc818b409774..21c478df6aef4 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -289,8 +289,10 @@ static void prelim_release(struct preftree *preftree)
+ struct prelim_ref *ref, *next_ref;
+
+ rbtree_postorder_for_each_entry_safe(ref, next_ref,
+- &preftree->root.rb_root, rbnode)
++ &preftree->root.rb_root, rbnode) {
++ free_inode_elem_list(ref->inode_list);
+ free_pref(ref);
++ }
+
+ preftree->root = RB_ROOT_CACHED;
+ preftree->count = 0;
+@@ -648,6 +650,18 @@ unode_aux_to_inode_list(struct ulist_node *node)
+ return (struct extent_inode_elem *)(uintptr_t)node->aux;
+ }
+
++static void free_leaf_list(struct ulist *ulist)
++{
++ struct ulist_node *node;
++ struct ulist_iterator uiter;
++
++ ULIST_ITER_INIT(&uiter);
++ while ((node = ulist_next(ulist, &uiter)))
++ free_inode_elem_list(unode_aux_to_inode_list(node));
++
++ ulist_free(ulist);
++}
++
+ /*
+ * We maintain three separate rbtrees: one for direct refs, one for
+ * indirect refs which have a key, and one for indirect refs which do not
+@@ -762,7 +776,11 @@ static int resolve_indirect_refs(struct btrfs_fs_info *fs_info,
+ cond_resched();
+ }
+ out:
+- ulist_free(parents);
++ /*
++ * We may have inode lists attached to refs in the parents ulist, so we
++ * must free them before freeing the ulist and its refs.
++ */
++ free_leaf_list(parents);
+ return ret;
+ }
+
+@@ -1368,6 +1386,12 @@ again:
+ if (ret < 0)
+ goto out;
+ ref->inode_list = eie;
++ /*
++ * We transferred the list ownership to the ref,
++ * so set to NULL to avoid a double free in case
++ * an error happens after this.
++ */
++ eie = NULL;
+ }
+ ret = ulist_add_merge_ptr(refs, ref->parent,
+ ref->inode_list,
+@@ -1393,6 +1417,14 @@ again:
+ eie->next = ref->inode_list;
+ }
+ eie = NULL;
++ /*
++ * We have transferred the inode list ownership from
++ * this ref to the ref we added to the 'refs' ulist.
++ * So set this ref's inode list to NULL to avoid
++ * use-after-free when our caller uses it or double
++ * frees in case an error happens before we return.
++ */
++ ref->inode_list = NULL;
+ }
+ cond_resched();
+ }
+@@ -1409,24 +1441,6 @@ out:
+ return ret;
+ }
+
+-static void free_leaf_list(struct ulist *blocks)
+-{
+- struct ulist_node *node = NULL;
+- struct extent_inode_elem *eie;
+- struct ulist_iterator uiter;
+-
+- ULIST_ITER_INIT(&uiter);
+- while ((node = ulist_next(blocks, &uiter))) {
+- if (!node->aux)
+- continue;
+- eie = unode_aux_to_inode_list(node);
+- free_inode_elem_list(eie);
+- node->aux = 0;
+- }
+-
+- ulist_free(blocks);
+-}
+-
+ /*
+ * Finds all leafs with a reference to the specified combination of bytenr and
+ * offset. key_list_head will point to a list of corresponding keys (caller must
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index df8c99c99df92..bad06add93d7e 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -3407,7 +3407,10 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
+ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
+ const struct btrfs_ioctl_encoded_io_args *encoded);
+
+-ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before);
++ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
++ size_t done_before);
++struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
++ size_t done_before);
+
+ extern const struct dentry_operations btrfs_dentry_operations;
+
+diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
+index 1d4c2397d0d62..fab7eb76e53b2 100644
+--- a/fs/btrfs/export.c
++++ b/fs/btrfs/export.c
+@@ -58,7 +58,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
+ }
+
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+- u64 root_objectid, u32 generation,
++ u64 root_objectid, u64 generation,
+ int check_generation)
+ {
+ struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+diff --git a/fs/btrfs/export.h b/fs/btrfs/export.h
+index f32f4113c976a..5afb7ca428289 100644
+--- a/fs/btrfs/export.h
++++ b/fs/btrfs/export.h
+@@ -19,7 +19,7 @@ struct btrfs_fid {
+ } __attribute__ ((packed));
+
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+- u64 root_objectid, u32 generation,
++ u64 root_objectid, u64 generation,
+ int check_generation);
+ struct dentry *btrfs_get_parent(struct dentry *child);
+
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index cfbbd7dc3c46b..32c3a5e5a3dd7 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -3294,21 +3294,22 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ }
+
+ /*
+- * If this is a leaf and there are tree mod log users, we may
+- * have recorded mod log operations that point to this leaf.
+- * So we must make sure no one reuses this leaf's extent before
+- * mod log operations are applied to a node, otherwise after
+- * rewinding a node using the mod log operations we get an
+- * inconsistent btree, as the leaf's extent may now be used as
+- * a node or leaf for another different btree.
++ * If there are tree mod log users we may have recorded mod log
++ * operations for this node. If we re-allocate this node we
++ * could replay operations on this node that happened when it
++ * existed in a completely different root. For example if it
++ * was part of root A, then was reallocated to root B, and we
++ * are doing a btrfs_old_search_slot(root b), we could replay
++ * operations that happened when the block was part of root A,
++ * giving us an inconsistent view of the btree.
++ *
+ * We are safe from races here because at this point no other
+ * node or root points to this extent buffer, so if after this
+- * check a new tree mod log user joins, it will not be able to
+- * find a node pointing to this leaf and record operations that
+- * point to this leaf.
++ * check a new tree mod log user joins we will not have an
++ * existing log of operations on this node that we have to
++ * contend with.
+ */
+- if (btrfs_header_level(buf) == 0 &&
+- test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
++ if (test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
+ must_pin = true;
+
+ if (must_pin || btrfs_is_zoned(fs_info)) {
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 19e9df0c86496..db7c6d22190de 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1889,6 +1889,7 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
+ loff_t endbyte;
+ ssize_t err;
+ unsigned int ilock_flags = 0;
++ struct iomap_dio *dio;
+
+ if (iocb->ki_flags & IOCB_NOWAIT)
+ ilock_flags |= BTRFS_ILOCK_TRY;
+@@ -1949,11 +1950,22 @@ relock:
+ * So here we disable page faults in the iov_iter and then retry if we
+ * got -EFAULT, faulting in the pages before the retry.
+ */
+-again:
+ from->nofault = true;
+- err = btrfs_dio_rw(iocb, from, written);
++ dio = btrfs_dio_write(iocb, from, written);
+ from->nofault = false;
+
++ /*
++ * iomap_dio_complete() will call btrfs_sync_file() if we have a dsync
++ * iocb, and that needs to lock the inode. So unlock it before calling
++ * iomap_dio_complete() to avoid a deadlock.
++ */
++ btrfs_inode_unlock(inode, ilock_flags);
++
++ if (IS_ERR_OR_NULL(dio))
++ err = PTR_ERR_OR_ZERO(dio);
++ else
++ err = iomap_dio_complete(dio);
++
+ /* No increment (+=) because iomap returns a cumulative value. */
+ if (err > 0)
+ written = err;
+@@ -1979,12 +1991,10 @@ again:
+ } else {
+ fault_in_iov_iter_readable(from, left);
+ prev_left = left;
+- goto again;
++ goto relock;
+ }
+ }
+
+- btrfs_inode_unlock(inode, ilock_flags);
+-
+ /*
+ * If 'err' is -ENOTBLK or we have not written all data, then it means
+ * we must fallback to buffered IO.
+@@ -3787,7 +3797,7 @@ again:
+ */
+ pagefault_disable();
+ to->nofault = true;
+- ret = btrfs_dio_rw(iocb, to, read);
++ ret = btrfs_dio_read(iocb, to, read);
+ to->nofault = false;
+ pagefault_enable();
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 1372210869b14..893693112fb80 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8142,7 +8142,7 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
+ */
+ status = BLK_STS_RESOURCE;
+ dip->csums = kcalloc(nr_sectors, fs_info->csum_size, GFP_NOFS);
+- if (!dip)
++ if (!dip->csums)
+ goto out_err;
+
+ status = btrfs_lookup_bio_sums(inode, dio_bio, dip->csums);
+@@ -8241,13 +8241,21 @@ static const struct iomap_dio_ops btrfs_dio_ops = {
+ .bio_set = &btrfs_dio_bioset,
+ };
+
+-ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before)
++ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter, size_t done_before)
+ {
+ struct btrfs_dio_data data;
+
+ return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
+- IOMAP_DIO_PARTIAL | IOMAP_DIO_NOSYNC,
+- &data, done_before);
++ IOMAP_DIO_PARTIAL, &data, done_before);
++}
++
++struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
++ size_t done_before)
++{
++ struct btrfs_dio_data data;
++
++ return __iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
++ IOMAP_DIO_PARTIAL, &data, done_before);
+ }
+
+ static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
+index eee1e44595410..843dd3d3adbe7 100644
+--- a/fs/btrfs/tests/qgroup-tests.c
++++ b/fs/btrfs/tests/qgroup-tests.c
+@@ -232,8 +232,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+
+ ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+ BTRFS_FS_TREE_OBJECTID);
+- if (ret)
++ if (ret) {
++ ulist_free(old_roots);
+ return ret;
++ }
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+@@ -266,8 +268,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ }
+
+ ret = remove_extent_item(root, nodesize, nodesize);
+- if (ret)
++ if (ret) {
++ ulist_free(old_roots);
+ return -EINVAL;
++ }
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+@@ -329,8 +333,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+ BTRFS_FS_TREE_OBJECTID);
+- if (ret)
++ if (ret) {
++ ulist_free(old_roots);
+ return ret;
++ }
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+@@ -362,8 +368,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = add_tree_ref(root, nodesize, nodesize, 0,
+ BTRFS_FIRST_FREE_OBJECTID);
+- if (ret)
++ if (ret) {
++ ulist_free(old_roots);
+ return ret;
++ }
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+@@ -401,8 +409,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = remove_extent_ref(root, nodesize, nodesize, 0,
+ BTRFS_FIRST_FREE_OBJECTID);
+- if (ret)
++ if (ret) {
++ ulist_free(old_roots);
+ return ret;
++ }
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index f63ff91e28837..5d004772ab493 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7029,6 +7029,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ u64 devid;
+ u64 type;
+ u8 uuid[BTRFS_UUID_SIZE];
++ int index;
+ int num_stripes;
+ int ret;
+ int i;
+@@ -7036,6 +7037,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ logical = key->offset;
+ length = btrfs_chunk_length(leaf, chunk);
+ type = btrfs_chunk_type(leaf, chunk);
++ index = btrfs_bg_flags_to_raid_index(type);
+ num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+
+ #if BITS_PER_LONG == 32
+@@ -7089,7 +7091,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ map->io_align = btrfs_chunk_io_align(leaf, chunk);
+ map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+ map->type = type;
+- map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
++ /*
++ * We can't use the sub_stripes value, as for profiles other than
++ * RAID10, they may have 0 as sub_stripes for filesystems created by
++ * older mkfs (<v5.4).
++ * In that case, it can cause divide-by-zero errors later.
++ * Since currently sub_stripes is fixed for each profile, let's
++ * use the trusted value instead.
++ */
++ map->sub_stripes = btrfs_raid_array[index].sub_stripes;
+ map->verified_stripes = 0;
+ em->orig_block_len = btrfs_calc_stripe_length(em);
+ for (i = 0; i < num_stripes; i++) {
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index e960dda893c63..c2c36451a8837 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3921,12 +3921,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+ pSMB->AndXCommand = 0xFF;
+ pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+ bcc_ptr = &pSMB->Password[0];
+- if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
+- pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
+- *bcc_ptr = 0; /* password is null byte */
+- bcc_ptr++; /* skip password */
+- /* already aligned so no need to do it below */
+- }
++
++ pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
++ *bcc_ptr = 0; /* password is null byte */
++ bcc_ptr++; /* skip password */
++ /* already aligned so no need to do it below */
+
+ if (ses->server->sign)
+ smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
+index 3afdaa0847736..577cae7facb01 100644
+--- a/fs/crypto/fscrypt_private.h
++++ b/fs/crypto/fscrypt_private.h
+@@ -225,7 +225,7 @@ struct fscrypt_info {
+ * will be NULL if the master key was found in a process-subscribed
+ * keyring rather than in the filesystem-level keyring.
+ */
+- struct key *ci_master_key;
++ struct fscrypt_master_key *ci_master_key;
+
+ /*
+ * Link in list of inodes that were unlocked with the master key.
+@@ -436,6 +436,40 @@ struct fscrypt_master_key_secret {
+ */
+ struct fscrypt_master_key {
+
++ /*
++ * Back-pointer to the super_block of the filesystem to which this
++ * master key has been added. Only valid if ->mk_active_refs > 0.
++ */
++ struct super_block *mk_sb;
++
++ /*
++ * Link in ->mk_sb->s_master_keys->key_hashtable.
++ * Only valid if ->mk_active_refs > 0.
++ */
++ struct hlist_node mk_node;
++
++ /* Semaphore that protects ->mk_secret and ->mk_users */
++ struct rw_semaphore mk_sem;
++
++ /*
++ * Active and structural reference counts. An active ref guarantees
++ * that the struct continues to exist, continues to be in the keyring
++ * ->mk_sb->s_master_keys, and that any embedded subkeys (e.g.
++ * ->mk_direct_keys) that have been prepared continue to exist.
++ * A structural ref only guarantees that the struct continues to exist.
++ *
++ * There is one active ref associated with ->mk_secret being present,
++ * and one active ref for each inode in ->mk_decrypted_inodes.
++ *
++ * There is one structural ref associated with the active refcount being
++ * nonzero. Finding a key in the keyring also takes a structural ref,
++ * which is then held temporarily while the key is operated on.
++ */
++ refcount_t mk_active_refs;
++ refcount_t mk_struct_refs;
++
++ struct rcu_head mk_rcu_head;
++
+ /*
+ * The secret key material. After FS_IOC_REMOVE_ENCRYPTION_KEY is
+ * executed, this is wiped and no new inodes can be unlocked with this
+@@ -444,7 +478,10 @@ struct fscrypt_master_key {
+ * FS_IOC_REMOVE_ENCRYPTION_KEY can be retried, or
+ * FS_IOC_ADD_ENCRYPTION_KEY can add the secret again.
+ *
+- * Locking: protected by this master key's key->sem.
++ * While ->mk_secret is present, one ref in ->mk_active_refs is held.
++ *
++ * Locking: protected by ->mk_sem. The manipulation of ->mk_active_refs
++ * associated with this field is protected by ->mk_sem as well.
+ */
+ struct fscrypt_master_key_secret mk_secret;
+
+@@ -465,22 +502,12 @@ struct fscrypt_master_key {
+ *
+ * This is NULL for v1 policy keys; those can only be added by root.
+ *
+- * Locking: in addition to this keyring's own semaphore, this is
+- * protected by this master key's key->sem, so we can do atomic
+- * search+insert. It can also be searched without taking any locks, but
+- * in that case the returned key may have already been removed.
++ * Locking: protected by ->mk_sem. (We don't just rely on the keyrings
++ * subsystem semaphore ->mk_users->sem, as we need support for atomic
++ * search+insert along with proper synchronization with ->mk_secret.)
+ */
+ struct key *mk_users;
+
+- /*
+- * Length of ->mk_decrypted_inodes, plus one if mk_secret is present.
+- * Once this goes to 0, the master key is removed from ->s_master_keys.
+- * The 'struct fscrypt_master_key' will continue to live as long as the
+- * 'struct key' whose payload it is, but we won't let this reference
+- * count rise again.
+- */
+- refcount_t mk_refcount;
+-
+ /*
+ * List of inodes that were unlocked using this key. This allows the
+ * inodes to be evicted efficiently if the key is removed.
+@@ -506,10 +533,10 @@ static inline bool
+ is_master_key_secret_present(const struct fscrypt_master_key_secret *secret)
+ {
+ /*
+- * The READ_ONCE() is only necessary for fscrypt_drop_inode() and
+- * fscrypt_key_describe(). These run in atomic context, so they can't
+- * take the key semaphore and thus 'secret' can change concurrently
+- * which would be a data race. But they only need to know whether the
++ * The READ_ONCE() is only necessary for fscrypt_drop_inode().
++ * fscrypt_drop_inode() runs in atomic context, so it can't take the key
++ * semaphore and thus 'secret' can change concurrently which would be a
++ * data race. But fscrypt_drop_inode() only need to know whether the
+ * secret *was* present at the time of check, so READ_ONCE() suffices.
+ */
+ return READ_ONCE(secret->size) != 0;
+@@ -538,7 +565,11 @@ static inline int master_key_spec_len(const struct fscrypt_key_specifier *spec)
+ return 0;
+ }
+
+-struct key *
++void fscrypt_put_master_key(struct fscrypt_master_key *mk);
++
++void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk);
++
++struct fscrypt_master_key *
+ fscrypt_find_master_key(struct super_block *sb,
+ const struct fscrypt_key_specifier *mk_spec);
+
+diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
+index 7c01025879b38..7b8c5a1104b58 100644
+--- a/fs/crypto/hooks.c
++++ b/fs/crypto/hooks.c
+@@ -5,8 +5,6 @@
+ * Encryption hooks for higher-level filesystem operations.
+ */
+
+-#include <linux/key.h>
+-
+ #include "fscrypt_private.h"
+
+ /**
+@@ -142,7 +140,6 @@ int fscrypt_prepare_setflags(struct inode *inode,
+ unsigned int oldflags, unsigned int flags)
+ {
+ struct fscrypt_info *ci;
+- struct key *key;
+ struct fscrypt_master_key *mk;
+ int err;
+
+@@ -158,14 +155,13 @@ int fscrypt_prepare_setflags(struct inode *inode,
+ ci = inode->i_crypt_info;
+ if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
+ return -EINVAL;
+- key = ci->ci_master_key;
+- mk = key->payload.data[0];
+- down_read(&key->sem);
++ mk = ci->ci_master_key;
++ down_read(&mk->mk_sem);
+ if (is_master_key_secret_present(&mk->mk_secret))
+ err = fscrypt_derive_dirhash_key(ci, mk);
+ else
+ err = -ENOKEY;
+- up_read(&key->sem);
++ up_read(&mk->mk_sem);
+ return err;
+ }
+ return 0;
+diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c
+index caee9f8620dd9..f10ace12c05f8 100644
+--- a/fs/crypto/keyring.c
++++ b/fs/crypto/keyring.c
+@@ -18,6 +18,7 @@
+ * information about these ioctls.
+ */
+
++#include <asm/unaligned.h>
+ #include <crypto/skcipher.h>
+ #include <linux/key-type.h>
+ #include <linux/random.h>
+@@ -25,6 +26,18 @@
+
+ #include "fscrypt_private.h"
+
++/* The master encryption keys for a filesystem (->s_master_keys) */
++struct fscrypt_keyring {
++ /*
++ * Lock that protects ->key_hashtable. It does *not* protect the
++ * fscrypt_master_key structs themselves.
++ */
++ spinlock_t lock;
++
++ /* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */
++ struct hlist_head key_hashtable[128];
++};
++
+ static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
+ {
+ fscrypt_destroy_hkdf(&secret->hkdf);
+@@ -38,20 +51,70 @@ static void move_master_key_secret(struct fscrypt_master_key_secret *dst,
+ memzero_explicit(src, sizeof(*src));
+ }
+
+-static void free_master_key(struct fscrypt_master_key *mk)
++static void fscrypt_free_master_key(struct rcu_head *head)
++{
++ struct fscrypt_master_key *mk =
++ container_of(head, struct fscrypt_master_key, mk_rcu_head);
++ /*
++ * The master key secret and any embedded subkeys should have already
++ * been wiped when the last active reference to the fscrypt_master_key
++ * struct was dropped; doing it here would be unnecessarily late.
++ * Nevertheless, use kfree_sensitive() in case anything was missed.
++ */
++ kfree_sensitive(mk);
++}
++
++void fscrypt_put_master_key(struct fscrypt_master_key *mk)
++{
++ if (!refcount_dec_and_test(&mk->mk_struct_refs))
++ return;
++ /*
++ * No structural references left, so free ->mk_users, and also free the
++ * fscrypt_master_key struct itself after an RCU grace period ensures
++ * that concurrent keyring lookups can no longer find it.
++ */
++ WARN_ON(refcount_read(&mk->mk_active_refs) != 0);
++ key_put(mk->mk_users);
++ mk->mk_users = NULL;
++ call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key);
++}
++
++void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk)
+ {
++ struct super_block *sb = mk->mk_sb;
++ struct fscrypt_keyring *keyring = sb->s_master_keys;
+ size_t i;
+
+- wipe_master_key_secret(&mk->mk_secret);
++ if (!refcount_dec_and_test(&mk->mk_active_refs))
++ return;
++ /*
++ * No active references left, so complete the full removal of this
++ * fscrypt_master_key struct by removing it from the keyring and
++ * destroying any subkeys embedded in it.
++ */
++
++ spin_lock(&keyring->lock);
++ hlist_del_rcu(&mk->mk_node);
++ spin_unlock(&keyring->lock);
++
++ /*
++ * ->mk_active_refs == 0 implies that ->mk_secret is not present and
++ * that ->mk_decrypted_inodes is empty.
++ */
++ WARN_ON(is_master_key_secret_present(&mk->mk_secret));
++ WARN_ON(!list_empty(&mk->mk_decrypted_inodes));
+
+ for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
+ fscrypt_destroy_prepared_key(&mk->mk_direct_keys[i]);
+ fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_64_keys[i]);
+ fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_32_keys[i]);
+ }
++ memzero_explicit(&mk->mk_ino_hash_key,
++ sizeof(mk->mk_ino_hash_key));
++ mk->mk_ino_hash_key_initialized = false;
+
+- key_put(mk->mk_users);
+- kfree_sensitive(mk);
++ /* Drop the structural ref associated with the active refs. */
++ fscrypt_put_master_key(mk);
+ }
+
+ static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
+@@ -61,44 +124,6 @@ static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
+ return master_key_spec_len(spec) != 0;
+ }
+
+-static int fscrypt_key_instantiate(struct key *key,
+- struct key_preparsed_payload *prep)
+-{
+- key->payload.data[0] = (struct fscrypt_master_key *)prep->data;
+- return 0;
+-}
+-
+-static void fscrypt_key_destroy(struct key *key)
+-{
+- free_master_key(key->payload.data[0]);
+-}
+-
+-static void fscrypt_key_describe(const struct key *key, struct seq_file *m)
+-{
+- seq_puts(m, key->description);
+-
+- if (key_is_positive(key)) {
+- const struct fscrypt_master_key *mk = key->payload.data[0];
+-
+- if (!is_master_key_secret_present(&mk->mk_secret))
+- seq_puts(m, ": secret removed");
+- }
+-}
+-
+-/*
+- * Type of key in ->s_master_keys. Each key of this type represents a master
+- * key which has been added to the filesystem. Its payload is a
+- * 'struct fscrypt_master_key'. The "." prefix in the key type name prevents
+- * users from adding keys of this type via the keyrings syscalls rather than via
+- * the intended method of FS_IOC_ADD_ENCRYPTION_KEY.
+- */
+-static struct key_type key_type_fscrypt = {
+- .name = "._fscrypt",
+- .instantiate = fscrypt_key_instantiate,
+- .destroy = fscrypt_key_destroy,
+- .describe = fscrypt_key_describe,
+-};
+-
+ static int fscrypt_user_key_instantiate(struct key *key,
+ struct key_preparsed_payload *prep)
+ {
+@@ -131,32 +156,6 @@ static struct key_type key_type_fscrypt_user = {
+ .describe = fscrypt_user_key_describe,
+ };
+
+-/* Search ->s_master_keys or ->mk_users */
+-static struct key *search_fscrypt_keyring(struct key *keyring,
+- struct key_type *type,
+- const char *description)
+-{
+- /*
+- * We need to mark the keyring reference as "possessed" so that we
+- * acquire permission to search it, via the KEY_POS_SEARCH permission.
+- */
+- key_ref_t keyref = make_key_ref(keyring, true /* possessed */);
+-
+- keyref = keyring_search(keyref, type, description, false);
+- if (IS_ERR(keyref)) {
+- if (PTR_ERR(keyref) == -EAGAIN || /* not found */
+- PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
+- keyref = ERR_PTR(-ENOKEY);
+- return ERR_CAST(keyref);
+- }
+- return key_ref_to_ptr(keyref);
+-}
+-
+-#define FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE \
+- (CONST_STRLEN("fscrypt-") + sizeof_field(struct super_block, s_id))
+-
+-#define FSCRYPT_MK_DESCRIPTION_SIZE (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1)
+-
+ #define FSCRYPT_MK_USERS_DESCRIPTION_SIZE \
+ (CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \
+ CONST_STRLEN("-users") + 1)
+@@ -164,21 +163,6 @@ static struct key *search_fscrypt_keyring(struct key *keyring,
+ #define FSCRYPT_MK_USER_DESCRIPTION_SIZE \
+ (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1)
+
+-static void format_fs_keyring_description(
+- char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE],
+- const struct super_block *sb)
+-{
+- sprintf(description, "fscrypt-%s", sb->s_id);
+-}
+-
+-static void format_mk_description(
+- char description[FSCRYPT_MK_DESCRIPTION_SIZE],
+- const struct fscrypt_key_specifier *mk_spec)
+-{
+- sprintf(description, "%*phN",
+- master_key_spec_len(mk_spec), (u8 *)&mk_spec->u);
+-}
+-
+ static void format_mk_users_keyring_description(
+ char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE],
+ const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
+@@ -199,20 +183,15 @@ static void format_mk_user_description(
+ /* Create ->s_master_keys if needed. Synchronized by fscrypt_add_key_mutex. */
+ static int allocate_filesystem_keyring(struct super_block *sb)
+ {
+- char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE];
+- struct key *keyring;
++ struct fscrypt_keyring *keyring;
+
+ if (sb->s_master_keys)
+ return 0;
+
+- format_fs_keyring_description(description, sb);
+- keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
+- current_cred(), KEY_POS_SEARCH |
+- KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW,
+- KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
+- if (IS_ERR(keyring))
+- return PTR_ERR(keyring);
+-
++ keyring = kzalloc(sizeof(*keyring), GFP_KERNEL);
++ if (!keyring)
++ return -ENOMEM;
++ spin_lock_init(&keyring->lock);
+ /*
+ * Pairs with the smp_load_acquire() in fscrypt_find_master_key().
+ * I.e., here we publish ->s_master_keys with a RELEASE barrier so that
+@@ -222,21 +201,80 @@ static int allocate_filesystem_keyring(struct super_block *sb)
+ return 0;
+ }
+
+-void fscrypt_sb_free(struct super_block *sb)
++/*
++ * Release all encryption keys that have been added to the filesystem, along
++ * with the keyring that contains them.
++ *
++ * This is called at unmount time. The filesystem's underlying block device(s)
++ * are still available at this time; this is important because after user file
++ * accesses have been allowed, this function may need to evict keys from the
++ * keyslots of an inline crypto engine, which requires the block device(s).
++ *
++ * This is also called when the super_block is being freed. This is needed to
++ * avoid a memory leak if mounting fails after the "test_dummy_encryption"
++ * option was processed, as in that case the unmount-time call isn't made.
++ */
++void fscrypt_destroy_keyring(struct super_block *sb)
+ {
+- key_put(sb->s_master_keys);
++ struct fscrypt_keyring *keyring = sb->s_master_keys;
++ size_t i;
++
++ if (!keyring)
++ return;
++
++ for (i = 0; i < ARRAY_SIZE(keyring->key_hashtable); i++) {
++ struct hlist_head *bucket = &keyring->key_hashtable[i];
++ struct fscrypt_master_key *mk;
++ struct hlist_node *tmp;
++
++ hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) {
++ /*
++ * Since all inodes were already evicted, every key
++ * remaining in the keyring should have an empty inode
++ * list, and should only still be in the keyring due to
++ * the single active ref associated with ->mk_secret.
++ * There should be no structural refs beyond the one
++ * associated with the active ref.
++ */
++ WARN_ON(refcount_read(&mk->mk_active_refs) != 1);
++ WARN_ON(refcount_read(&mk->mk_struct_refs) != 1);
++ WARN_ON(!is_master_key_secret_present(&mk->mk_secret));
++ wipe_master_key_secret(&mk->mk_secret);
++ fscrypt_put_master_key_activeref(mk);
++ }
++ }
++ kfree_sensitive(keyring);
+ sb->s_master_keys = NULL;
+ }
+
++static struct hlist_head *
++fscrypt_mk_hash_bucket(struct fscrypt_keyring *keyring,
++ const struct fscrypt_key_specifier *mk_spec)
++{
++ /*
++ * Since key specifiers should be "random" values, it is sufficient to
++ * use a trivial hash function that just takes the first several bits of
++ * the key specifier.
++ */
++ unsigned long i = get_unaligned((unsigned long *)&mk_spec->u);
++
++ return &keyring->key_hashtable[i % ARRAY_SIZE(keyring->key_hashtable)];
++}
++
+ /*
+- * Find the specified master key in ->s_master_keys.
+- * Returns ERR_PTR(-ENOKEY) if not found.
++ * Find the specified master key struct in ->s_master_keys and take a structural
++ * ref to it. The structural ref guarantees that the key struct continues to
++ * exist, but it does *not* guarantee that ->s_master_keys continues to contain
++ * the key struct. The structural ref needs to be dropped by
++ * fscrypt_put_master_key(). Returns NULL if the key struct is not found.
+ */
+-struct key *fscrypt_find_master_key(struct super_block *sb,
+- const struct fscrypt_key_specifier *mk_spec)
++struct fscrypt_master_key *
++fscrypt_find_master_key(struct super_block *sb,
++ const struct fscrypt_key_specifier *mk_spec)
+ {
+- struct key *keyring;
+- char description[FSCRYPT_MK_DESCRIPTION_SIZE];
++ struct fscrypt_keyring *keyring;
++ struct hlist_head *bucket;
++ struct fscrypt_master_key *mk;
+
+ /*
+ * Pairs with the smp_store_release() in allocate_filesystem_keyring().
+@@ -246,10 +284,38 @@ struct key *fscrypt_find_master_key(struct super_block *sb,
+ */
+ keyring = smp_load_acquire(&sb->s_master_keys);
+ if (keyring == NULL)
+- return ERR_PTR(-ENOKEY); /* No keyring yet, so no keys yet. */
+-
+- format_mk_description(description, mk_spec);
+- return search_fscrypt_keyring(keyring, &key_type_fscrypt, description);
++ return NULL; /* No keyring yet, so no keys yet. */
++
++ bucket = fscrypt_mk_hash_bucket(keyring, mk_spec);
++ rcu_read_lock();
++ switch (mk_spec->type) {
++ case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR:
++ hlist_for_each_entry_rcu(mk, bucket, mk_node) {
++ if (mk->mk_spec.type ==
++ FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
++ memcmp(mk->mk_spec.u.descriptor,
++ mk_spec->u.descriptor,
++ FSCRYPT_KEY_DESCRIPTOR_SIZE) == 0 &&
++ refcount_inc_not_zero(&mk->mk_struct_refs))
++ goto out;
++ }
++ break;
++ case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER:
++ hlist_for_each_entry_rcu(mk, bucket, mk_node) {
++ if (mk->mk_spec.type ==
++ FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER &&
++ memcmp(mk->mk_spec.u.identifier,
++ mk_spec->u.identifier,
++ FSCRYPT_KEY_IDENTIFIER_SIZE) == 0 &&
++ refcount_inc_not_zero(&mk->mk_struct_refs))
++ goto out;
++ }
++ break;
++ }
++ mk = NULL;
++out:
++ rcu_read_unlock();
++ return mk;
+ }
+
+ static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
+@@ -277,17 +343,30 @@ static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
+ static struct key *find_master_key_user(struct fscrypt_master_key *mk)
+ {
+ char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
++ key_ref_t keyref;
+
+ format_mk_user_description(description, mk->mk_spec.u.identifier);
+- return search_fscrypt_keyring(mk->mk_users, &key_type_fscrypt_user,
+- description);
++
++ /*
++ * We need to mark the keyring reference as "possessed" so that we
++ * acquire permission to search it, via the KEY_POS_SEARCH permission.
++ */
++ keyref = keyring_search(make_key_ref(mk->mk_users, true /*possessed*/),
++ &key_type_fscrypt_user, description, false);
++ if (IS_ERR(keyref)) {
++ if (PTR_ERR(keyref) == -EAGAIN || /* not found */
++ PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
++ keyref = ERR_PTR(-ENOKEY);
++ return ERR_CAST(keyref);
++ }
++ return key_ref_to_ptr(keyref);
+ }
+
+ /*
+ * Give the current user a "key" in ->mk_users. This charges the user's quota
+ * and marks the master key as added by the current user, so that it cannot be
+- * removed by another user with the key. Either the master key's key->sem must
+- * be held for write, or the master key must be still undergoing initialization.
++ * removed by another user with the key. Either ->mk_sem must be held for
++ * write, or the master key must be still undergoing initialization.
+ */
+ static int add_master_key_user(struct fscrypt_master_key *mk)
+ {
+@@ -309,7 +388,7 @@ static int add_master_key_user(struct fscrypt_master_key *mk)
+
+ /*
+ * Remove the current user's "key" from ->mk_users.
+- * The master key's key->sem must be held for write.
++ * ->mk_sem must be held for write.
+ *
+ * Returns 0 if removed, -ENOKEY if not found, or another -errno code.
+ */
+@@ -327,63 +406,49 @@ static int remove_master_key_user(struct fscrypt_master_key *mk)
+ }
+
+ /*
+- * Allocate a new fscrypt_master_key which contains the given secret, set it as
+- * the payload of a new 'struct key' of type fscrypt, and link the 'struct key'
+- * into the given keyring. Synchronized by fscrypt_add_key_mutex.
++ * Allocate a new fscrypt_master_key, transfer the given secret over to it, and
++ * insert it into sb->s_master_keys.
+ */
+-static int add_new_master_key(struct fscrypt_master_key_secret *secret,
+- const struct fscrypt_key_specifier *mk_spec,
+- struct key *keyring)
++static int add_new_master_key(struct super_block *sb,
++ struct fscrypt_master_key_secret *secret,
++ const struct fscrypt_key_specifier *mk_spec)
+ {
++ struct fscrypt_keyring *keyring = sb->s_master_keys;
+ struct fscrypt_master_key *mk;
+- char description[FSCRYPT_MK_DESCRIPTION_SIZE];
+- struct key *key;
+ int err;
+
+ mk = kzalloc(sizeof(*mk), GFP_KERNEL);
+ if (!mk)
+ return -ENOMEM;
+
++ mk->mk_sb = sb;
++ init_rwsem(&mk->mk_sem);
++ refcount_set(&mk->mk_struct_refs, 1);
+ mk->mk_spec = *mk_spec;
+
+- move_master_key_secret(&mk->mk_secret, secret);
+-
+- refcount_set(&mk->mk_refcount, 1); /* secret is present */
+ INIT_LIST_HEAD(&mk->mk_decrypted_inodes);
+ spin_lock_init(&mk->mk_decrypted_inodes_lock);
+
+ if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
+ err = allocate_master_key_users_keyring(mk);
+ if (err)
+- goto out_free_mk;
++ goto out_put;
+ err = add_master_key_user(mk);
+ if (err)
+- goto out_free_mk;
++ goto out_put;
+ }
+
+- /*
+- * Note that we don't charge this key to anyone's quota, since when
+- * ->mk_users is in use those keys are charged instead, and otherwise
+- * (when ->mk_users isn't in use) only root can add these keys.
+- */
+- format_mk_description(description, mk_spec);
+- key = key_alloc(&key_type_fscrypt, description,
+- GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
+- KEY_POS_SEARCH | KEY_USR_SEARCH | KEY_USR_VIEW,
+- KEY_ALLOC_NOT_IN_QUOTA, NULL);
+- if (IS_ERR(key)) {
+- err = PTR_ERR(key);
+- goto out_free_mk;
+- }
+- err = key_instantiate_and_link(key, mk, sizeof(*mk), keyring, NULL);
+- key_put(key);
+- if (err)
+- goto out_free_mk;
++ move_master_key_secret(&mk->mk_secret, secret);
++ refcount_set(&mk->mk_active_refs, 1); /* ->mk_secret is present */
+
++ spin_lock(&keyring->lock);
++ hlist_add_head_rcu(&mk->mk_node,
++ fscrypt_mk_hash_bucket(keyring, mk_spec));
++ spin_unlock(&keyring->lock);
+ return 0;
+
+-out_free_mk:
+- free_master_key(mk);
++out_put:
++ fscrypt_put_master_key(mk);
+ return err;
+ }
+
+@@ -392,42 +457,34 @@ out_free_mk:
+ static int add_existing_master_key(struct fscrypt_master_key *mk,
+ struct fscrypt_master_key_secret *secret)
+ {
+- struct key *mk_user;
+- bool rekey;
+ int err;
+
+ /*
+ * If the current user is already in ->mk_users, then there's nothing to
+- * do. (Not applicable for v1 policy keys, which have NULL ->mk_users.)
++ * do. Otherwise, we need to add the user to ->mk_users. (Neither is
++ * applicable for v1 policy keys, which have NULL ->mk_users.)
+ */
+ if (mk->mk_users) {
+- mk_user = find_master_key_user(mk);
++ struct key *mk_user = find_master_key_user(mk);
++
+ if (mk_user != ERR_PTR(-ENOKEY)) {
+ if (IS_ERR(mk_user))
+ return PTR_ERR(mk_user);
+ key_put(mk_user);
+ return 0;
+ }
+- }
+-
+- /* If we'll be re-adding ->mk_secret, try to take the reference. */
+- rekey = !is_master_key_secret_present(&mk->mk_secret);
+- if (rekey && !refcount_inc_not_zero(&mk->mk_refcount))
+- return KEY_DEAD;
+-
+- /* Add the current user to ->mk_users, if applicable. */
+- if (mk->mk_users) {
+ err = add_master_key_user(mk);
+- if (err) {
+- if (rekey && refcount_dec_and_test(&mk->mk_refcount))
+- return KEY_DEAD;
++ if (err)
+ return err;
+- }
+ }
+
+ /* Re-add the secret if needed. */
+- if (rekey)
++ if (!is_master_key_secret_present(&mk->mk_secret)) {
++ if (!refcount_inc_not_zero(&mk->mk_active_refs))
++ return KEY_DEAD;
+ move_master_key_secret(&mk->mk_secret, secret);
++ }
++
+ return 0;
+ }
+
+@@ -436,38 +493,36 @@ static int do_add_master_key(struct super_block *sb,
+ const struct fscrypt_key_specifier *mk_spec)
+ {
+ static DEFINE_MUTEX(fscrypt_add_key_mutex);
+- struct key *key;
++ struct fscrypt_master_key *mk;
+ int err;
+
+ mutex_lock(&fscrypt_add_key_mutex); /* serialize find + link */
+-retry:
+- key = fscrypt_find_master_key(sb, mk_spec);
+- if (IS_ERR(key)) {
+- err = PTR_ERR(key);
+- if (err != -ENOKEY)
+- goto out_unlock;
++
++ mk = fscrypt_find_master_key(sb, mk_spec);
++ if (!mk) {
+ /* Didn't find the key in ->s_master_keys. Add it. */
+ err = allocate_filesystem_keyring(sb);
+- if (err)
+- goto out_unlock;
+- err = add_new_master_key(secret, mk_spec, sb->s_master_keys);
++ if (!err)
++ err = add_new_master_key(sb, secret, mk_spec);
+ } else {
+ /*
+ * Found the key in ->s_master_keys. Re-add the secret if
+ * needed, and add the user to ->mk_users if needed.
+ */
+- down_write(&key->sem);
+- err = add_existing_master_key(key->payload.data[0], secret);
+- up_write(&key->sem);
++ down_write(&mk->mk_sem);
++ err = add_existing_master_key(mk, secret);
++ up_write(&mk->mk_sem);
+ if (err == KEY_DEAD) {
+- /* Key being removed or needs to be removed */
+- key_invalidate(key);
+- key_put(key);
+- goto retry;
++ /*
++ * We found a key struct, but it's already been fully
++ * removed. Ignore the old struct and add a new one.
++ * fscrypt_add_key_mutex means we don't need to worry
++ * about concurrent adds.
++ */
++ err = add_new_master_key(sb, secret, mk_spec);
+ }
+- key_put(key);
++ fscrypt_put_master_key(mk);
+ }
+-out_unlock:
+ mutex_unlock(&fscrypt_add_key_mutex);
+ return err;
+ }
+@@ -771,19 +826,19 @@ int fscrypt_verify_key_added(struct super_block *sb,
+ const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
+ {
+ struct fscrypt_key_specifier mk_spec;
+- struct key *key, *mk_user;
+ struct fscrypt_master_key *mk;
++ struct key *mk_user;
+ int err;
+
+ mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
+ memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
+
+- key = fscrypt_find_master_key(sb, &mk_spec);
+- if (IS_ERR(key)) {
+- err = PTR_ERR(key);
++ mk = fscrypt_find_master_key(sb, &mk_spec);
++ if (!mk) {
++ err = -ENOKEY;
+ goto out;
+ }
+- mk = key->payload.data[0];
++ down_read(&mk->mk_sem);
+ mk_user = find_master_key_user(mk);
+ if (IS_ERR(mk_user)) {
+ err = PTR_ERR(mk_user);
+@@ -791,7 +846,8 @@ int fscrypt_verify_key_added(struct super_block *sb,
+ key_put(mk_user);
+ err = 0;
+ }
+- key_put(key);
++ up_read(&mk->mk_sem);
++ fscrypt_put_master_key(mk);
+ out:
+ if (err == -ENOKEY && capable(CAP_FOWNER))
+ err = 0;
+@@ -953,11 +1009,10 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ struct super_block *sb = file_inode(filp)->i_sb;
+ struct fscrypt_remove_key_arg __user *uarg = _uarg;
+ struct fscrypt_remove_key_arg arg;
+- struct key *key;
+ struct fscrypt_master_key *mk;
+ u32 status_flags = 0;
+ int err;
+- bool dead;
++ bool inodes_remain;
+
+ if (copy_from_user(&arg, uarg, sizeof(arg)))
+ return -EFAULT;
+@@ -977,12 +1032,10 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ return -EACCES;
+
+ /* Find the key being removed. */
+- key = fscrypt_find_master_key(sb, &arg.key_spec);
+- if (IS_ERR(key))
+- return PTR_ERR(key);
+- mk = key->payload.data[0];
+-
+- down_write(&key->sem);
++ mk = fscrypt_find_master_key(sb, &arg.key_spec);
++ if (!mk)
++ return -ENOKEY;
++ down_write(&mk->mk_sem);
+
+ /* If relevant, remove current user's (or all users) claim to the key */
+ if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) {
+@@ -991,7 +1044,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ else
+ err = remove_master_key_user(mk);
+ if (err) {
+- up_write(&key->sem);
++ up_write(&mk->mk_sem);
+ goto out_put_key;
+ }
+ if (mk->mk_users->keys.nr_leaves_on_tree != 0) {
+@@ -1003,26 +1056,22 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ status_flags |=
+ FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS;
+ err = 0;
+- up_write(&key->sem);
++ up_write(&mk->mk_sem);
+ goto out_put_key;
+ }
+ }
+
+ /* No user claims remaining. Go ahead and wipe the secret. */
+- dead = false;
++ err = -ENOKEY;
+ if (is_master_key_secret_present(&mk->mk_secret)) {
+ wipe_master_key_secret(&mk->mk_secret);
+- dead = refcount_dec_and_test(&mk->mk_refcount);
+- }
+- up_write(&key->sem);
+- if (dead) {
+- /*
+- * No inodes reference the key, and we wiped the secret, so the
+- * key object is free to be removed from the keyring.
+- */
+- key_invalidate(key);
++ fscrypt_put_master_key_activeref(mk);
+ err = 0;
+- } else {
++ }
++ inodes_remain = refcount_read(&mk->mk_active_refs) > 0;
++ up_write(&mk->mk_sem);
++
++ if (inodes_remain) {
+ /* Some inodes still reference this key; try to evict them. */
+ err = try_to_lock_encrypted_files(sb, mk);
+ if (err == -EBUSY) {
+@@ -1038,7 +1087,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ * has been fully removed including all files locked.
+ */
+ out_put_key:
+- key_put(key);
++ fscrypt_put_master_key(mk);
+ if (err == 0)
+ err = put_user(status_flags, &uarg->removal_status_flags);
+ return err;
+@@ -1085,7 +1134,6 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ {
+ struct super_block *sb = file_inode(filp)->i_sb;
+ struct fscrypt_get_key_status_arg arg;
+- struct key *key;
+ struct fscrypt_master_key *mk;
+ int err;
+
+@@ -1102,19 +1150,18 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ arg.user_count = 0;
+ memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved));
+
+- key = fscrypt_find_master_key(sb, &arg.key_spec);
+- if (IS_ERR(key)) {
+- if (key != ERR_PTR(-ENOKEY))
+- return PTR_ERR(key);
++ mk = fscrypt_find_master_key(sb, &arg.key_spec);
++ if (!mk) {
+ arg.status = FSCRYPT_KEY_STATUS_ABSENT;
+ err = 0;
+ goto out;
+ }
+- mk = key->payload.data[0];
+- down_read(&key->sem);
++ down_read(&mk->mk_sem);
+
+ if (!is_master_key_secret_present(&mk->mk_secret)) {
+- arg.status = FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED;
++ arg.status = refcount_read(&mk->mk_active_refs) > 0 ?
++ FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED :
++ FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */;
+ err = 0;
+ goto out_release_key;
+ }
+@@ -1136,8 +1183,8 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ }
+ err = 0;
+ out_release_key:
+- up_read(&key->sem);
+- key_put(key);
++ up_read(&mk->mk_sem);
++ fscrypt_put_master_key(mk);
+ out:
+ if (!err && copy_to_user(uarg, &arg, sizeof(arg)))
+ err = -EFAULT;
+@@ -1149,13 +1196,9 @@ int __init fscrypt_init_keyring(void)
+ {
+ int err;
+
+- err = register_key_type(&key_type_fscrypt);
+- if (err)
+- return err;
+-
+ err = register_key_type(&key_type_fscrypt_user);
+ if (err)
+- goto err_unregister_fscrypt;
++ return err;
+
+ err = register_key_type(&key_type_fscrypt_provisioning);
+ if (err)
+@@ -1165,7 +1208,5 @@ int __init fscrypt_init_keyring(void)
+
+ err_unregister_fscrypt_user:
+ unregister_key_type(&key_type_fscrypt_user);
+-err_unregister_fscrypt:
+- unregister_key_type(&key_type_fscrypt);
+ return err;
+ }
+diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
+index fbc71abdabe32..e037a7b8e9e42 100644
+--- a/fs/crypto/keysetup.c
++++ b/fs/crypto/keysetup.c
+@@ -9,7 +9,6 @@
+ */
+
+ #include <crypto/skcipher.h>
+-#include <linux/key.h>
+ #include <linux/random.h>
+
+ #include "fscrypt_private.h"
+@@ -159,6 +158,7 @@ void fscrypt_destroy_prepared_key(struct fscrypt_prepared_key *prep_key)
+ {
+ crypto_free_skcipher(prep_key->tfm);
+ fscrypt_destroy_inline_crypt_key(prep_key);
++ memzero_explicit(prep_key, sizeof(*prep_key));
+ }
+
+ /* Given a per-file encryption key, set up the file's crypto transform object */
+@@ -412,20 +412,18 @@ static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk,
+ /*
+ * Find the master key, then set up the inode's actual encryption key.
+ *
+- * If the master key is found in the filesystem-level keyring, then the
+- * corresponding 'struct key' is returned in *master_key_ret with its semaphore
+- * read-locked. This is needed to ensure that only one task links the
+- * fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race to create
+- * an fscrypt_info for the same inode), and to synchronize the master key being
+- * removed with a new inode starting to use it.
++ * If the master key is found in the filesystem-level keyring, then it is
++ * returned in *mk_ret with its semaphore read-locked. This is needed to ensure
++ * that only one task links the fscrypt_info into ->mk_decrypted_inodes (as
++ * multiple tasks may race to create an fscrypt_info for the same inode), and to
++ * synchronize the master key being removed with a new inode starting to use it.
+ */
+ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ bool need_dirhash_key,
+- struct key **master_key_ret)
++ struct fscrypt_master_key **mk_ret)
+ {
+- struct key *key;
+- struct fscrypt_master_key *mk = NULL;
+ struct fscrypt_key_specifier mk_spec;
++ struct fscrypt_master_key *mk;
+ int err;
+
+ err = fscrypt_select_encryption_impl(ci);
+@@ -436,11 +434,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ if (err)
+ return err;
+
+- key = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
+- if (IS_ERR(key)) {
+- if (key != ERR_PTR(-ENOKEY) ||
+- ci->ci_policy.version != FSCRYPT_POLICY_V1)
+- return PTR_ERR(key);
++ mk = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
++ if (!mk) {
++ if (ci->ci_policy.version != FSCRYPT_POLICY_V1)
++ return -ENOKEY;
+
+ /*
+ * As a legacy fallback for v1 policies, search for the key in
+@@ -450,9 +447,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ */
+ return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci);
+ }
+-
+- mk = key->payload.data[0];
+- down_read(&key->sem);
++ down_read(&mk->mk_sem);
+
+ /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */
+ if (!is_master_key_secret_present(&mk->mk_secret)) {
+@@ -480,18 +475,18 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ if (err)
+ goto out_release_key;
+
+- *master_key_ret = key;
++ *mk_ret = mk;
+ return 0;
+
+ out_release_key:
+- up_read(&key->sem);
+- key_put(key);
++ up_read(&mk->mk_sem);
++ fscrypt_put_master_key(mk);
+ return err;
+ }
+
+ static void put_crypt_info(struct fscrypt_info *ci)
+ {
+- struct key *key;
++ struct fscrypt_master_key *mk;
+
+ if (!ci)
+ return;
+@@ -501,24 +496,18 @@ static void put_crypt_info(struct fscrypt_info *ci)
+ else if (ci->ci_owns_key)
+ fscrypt_destroy_prepared_key(&ci->ci_enc_key);
+
+- key = ci->ci_master_key;
+- if (key) {
+- struct fscrypt_master_key *mk = key->payload.data[0];
+-
++ mk = ci->ci_master_key;
++ if (mk) {
+ /*
+ * Remove this inode from the list of inodes that were unlocked
+- * with the master key.
+- *
+- * In addition, if we're removing the last inode from a key that
+- * already had its secret removed, invalidate the key so that it
+- * gets removed from ->s_master_keys.
++ * with the master key. In addition, if we're removing the last
++ * inode from a master key struct that already had its secret
++ * removed, then complete the full removal of the struct.
+ */
+ spin_lock(&mk->mk_decrypted_inodes_lock);
+ list_del(&ci->ci_master_key_link);
+ spin_unlock(&mk->mk_decrypted_inodes_lock);
+- if (refcount_dec_and_test(&mk->mk_refcount))
+- key_invalidate(key);
+- key_put(key);
++ fscrypt_put_master_key_activeref(mk);
+ }
+ memzero_explicit(ci, sizeof(*ci));
+ kmem_cache_free(fscrypt_info_cachep, ci);
+@@ -532,7 +521,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ {
+ struct fscrypt_info *crypt_info;
+ struct fscrypt_mode *mode;
+- struct key *master_key = NULL;
++ struct fscrypt_master_key *mk = NULL;
+ int res;
+
+ res = fscrypt_initialize(inode->i_sb->s_cop->flags);
+@@ -555,8 +544,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
+ crypt_info->ci_mode = mode;
+
+- res = setup_file_encryption_key(crypt_info, need_dirhash_key,
+- &master_key);
++ res = setup_file_encryption_key(crypt_info, need_dirhash_key, &mk);
+ if (res)
+ goto out;
+
+@@ -571,12 +559,9 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ * We won the race and set ->i_crypt_info to our crypt_info.
+ * Now link it into the master key's inode list.
+ */
+- if (master_key) {
+- struct fscrypt_master_key *mk =
+- master_key->payload.data[0];
+-
+- refcount_inc(&mk->mk_refcount);
+- crypt_info->ci_master_key = key_get(master_key);
++ if (mk) {
++ crypt_info->ci_master_key = mk;
++ refcount_inc(&mk->mk_active_refs);
+ spin_lock(&mk->mk_decrypted_inodes_lock);
+ list_add(&crypt_info->ci_master_key_link,
+ &mk->mk_decrypted_inodes);
+@@ -586,9 +571,9 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ }
+ res = 0;
+ out:
+- if (master_key) {
+- up_read(&master_key->sem);
+- key_put(master_key);
++ if (mk) {
++ up_read(&mk->mk_sem);
++ fscrypt_put_master_key(mk);
+ }
+ put_crypt_info(crypt_info);
+ return res;
+@@ -753,7 +738,6 @@ EXPORT_SYMBOL(fscrypt_free_inode);
+ int fscrypt_drop_inode(struct inode *inode)
+ {
+ const struct fscrypt_info *ci = fscrypt_get_info(inode);
+- const struct fscrypt_master_key *mk;
+
+ /*
+ * If ci is NULL, then the inode doesn't have an encryption key set up
+@@ -763,7 +747,6 @@ int fscrypt_drop_inode(struct inode *inode)
+ */
+ if (!ci || !ci->ci_master_key)
+ return 0;
+- mk = ci->ci_master_key->payload.data[0];
+
+ /*
+ * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes
+@@ -782,6 +765,6 @@ int fscrypt_drop_inode(struct inode *inode)
+ * then the thread removing the key will either evict the inode itself
+ * or will correctly detect that it wasn't evicted due to the race.
+ */
+- return !is_master_key_secret_present(&mk->mk_secret);
++ return !is_master_key_secret_present(&ci->ci_master_key->mk_secret);
+ }
+ EXPORT_SYMBOL_GPL(fscrypt_drop_inode);
+diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
+index 80b8ca0f340b2..8485e7eaee2b3 100644
+--- a/fs/crypto/policy.c
++++ b/fs/crypto/policy.c
+@@ -744,12 +744,8 @@ int fscrypt_set_context(struct inode *inode, void *fs_data)
+ * delayed key setup that requires the inode number.
+ */
+ if (ci->ci_policy.version == FSCRYPT_POLICY_V2 &&
+- (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) {
+- const struct fscrypt_master_key *mk =
+- ci->ci_master_key->payload.data[0];
+-
+- fscrypt_hash_inode_number(ci, mk);
+- }
++ (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
++ fscrypt_hash_inode_number(ci, ci->ci_master_key);
+
+ return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data);
+ }
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index ad3a294a88eb2..eed8bd7812d58 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -145,9 +145,8 @@ static int ext4_update_backup_sb(struct super_block *sb,
+ if (ext4_has_metadata_csum(sb) &&
+ es->s_checksum != ext4_superblock_csum(sb, es)) {
+ ext4_msg(sb, KERN_ERR, "Invalid checksum for backup "
+- "superblock %llu\n", sb_block);
++ "superblock %llu", sb_block);
+ unlock_buffer(bh);
+- err = -EFSBADCRC;
+ goto out_bh;
+ }
+ func(es, arg);
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 54e7d3c95fd71..35ca468109be9 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -425,7 +425,8 @@ int ext4_ext_migrate(struct inode *inode)
+ * already is extent-based, error out.
+ */
+ if (!ext4_has_feature_extents(inode->i_sb) ||
+- (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
++ ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) ||
++ ext4_has_inline_data(inode))
+ return -EINVAL;
+
+ if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 4183a4cb4a21e..be8136aafa22c 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2259,8 +2259,16 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
+ memset(de, 0, len); /* wipe old data */
+ de = (struct ext4_dir_entry_2 *) data2;
+ top = data2 + len;
+- while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top)
++ while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) {
++ if (ext4_check_dir_entry(dir, NULL, de, bh2, data2, len,
++ (data2 + (blocksize - csum_size) -
++ (char *) de))) {
++ brelse(bh2);
++ brelse(bh);
++ return -EFSCORRUPTED;
++ }
+ de = de2;
++ }
+ de->rec_len = ext4_rec_len_to_disk(data2 + (blocksize - csum_size) -
+ (char *) de, blocksize);
+
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 6dfe9ccae0c50..46b87ffeb3045 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1158,6 +1158,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ while (group < sbi->s_groups_count) {
+ struct buffer_head *bh;
+ ext4_fsblk_t backup_block;
++ struct ext4_super_block *es;
+
+ /* Out of journal space, and can't get more - abort - so sad */
+ err = ext4_resize_ensure_credits_batch(handle, 1);
+@@ -1186,6 +1187,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ memcpy(bh->b_data, data, size);
+ if (rest)
+ memset(bh->b_data + size, 0, rest);
++ es = (struct ext4_super_block *) bh->b_data;
++ es->s_block_group_nr = cpu_to_le16(group);
++ if (ext4_has_metadata_csum(sb))
++ es->s_checksum = ext4_superblock_csum(sb, es);
+ set_buffer_uptodate(bh);
+ unlock_buffer(bh);
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
+diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
+index b051d19b5c8a0..94442c690ca7d 100644
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -365,13 +365,14 @@ static struct page *ext4_read_merkle_tree_page(struct inode *inode,
+ pgoff_t index,
+ unsigned long num_ra_pages)
+ {
+- DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
+ struct page *page;
+
+ index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT;
+
+ page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED);
+ if (!page || !PageUptodate(page)) {
++ DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
++
+ if (page)
+ put_page(page);
+ else if (num_ra_pages > 1)
+diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
+index 7b8f2b41c29b1..c0733f8670746 100644
+--- a/fs/f2fs/verity.c
++++ b/fs/f2fs/verity.c
+@@ -262,13 +262,14 @@ static struct page *f2fs_read_merkle_tree_page(struct inode *inode,
+ pgoff_t index,
+ unsigned long num_ra_pages)
+ {
+- DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
+ struct page *page;
+
+ index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT;
+
+ page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED);
+ if (!page || !PageUptodate(page)) {
++ DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
++
+ if (page)
+ put_page(page);
+ else if (num_ra_pages > 1)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 1a3afd469e3a9..71bfb663aac58 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -3001,6 +3001,10 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ goto out;
+ }
+
++ err = file_modified(file);
++ if (err)
++ goto out;
++
+ if (!(mode & FALLOC_FL_KEEP_SIZE))
+ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+
+diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
+index b4e5657110457..e8deaacf1832a 100644
+--- a/fs/fuse/readdir.c
++++ b/fs/fuse/readdir.c
+@@ -77,8 +77,10 @@ static void fuse_add_dirent_to_cache(struct file *file,
+ goto unlock;
+
+ addr = kmap_local_page(page);
+- if (!offset)
++ if (!offset) {
+ clear_page(addr);
++ SetPageUptodate(page);
++ }
+ memcpy(addr + offset, dirent, reclen);
+ kunmap_local(addr);
+ fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen;
+@@ -516,6 +518,12 @@ retry_locked:
+
+ page = find_get_page_flags(file->f_mapping, index,
+ FGP_ACCESSED | FGP_LOCK);
++ /* Page gone missing, then re-added to cache, but not initialized? */
++ if (page && !PageUptodate(page)) {
++ unlock_page(page);
++ put_page(page);
++ page = NULL;
++ }
+ spin_lock(&fi->rdc.lock);
+ if (!page) {
+ /*
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 5c97cad741a73..ead8a0e06abf9 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -228,8 +228,7 @@ again:
+ *
+ */
+ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
+- fmode_t type,
+- const nfs4_stateid *stateid,
++ fmode_t type, const nfs4_stateid *stateid,
+ unsigned long pagemod_limit)
+ {
+ struct nfs_delegation *delegation;
+@@ -239,25 +238,24 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
+ delegation = rcu_dereference(NFS_I(inode)->delegation);
+ if (delegation != NULL) {
+ spin_lock(&delegation->lock);
+- if (nfs4_is_valid_delegation(delegation, 0)) {
+- nfs4_stateid_copy(&delegation->stateid, stateid);
+- delegation->type = type;
+- delegation->pagemod_limit = pagemod_limit;
+- oldcred = delegation->cred;
+- delegation->cred = get_cred(cred);
+- clear_bit(NFS_DELEGATION_NEED_RECLAIM,
+- &delegation->flags);
+- spin_unlock(&delegation->lock);
+- rcu_read_unlock();
+- put_cred(oldcred);
+- trace_nfs4_reclaim_delegation(inode, type);
+- return;
+- }
+- /* We appear to have raced with a delegation return. */
++ nfs4_stateid_copy(&delegation->stateid, stateid);
++ delegation->type = type;
++ delegation->pagemod_limit = pagemod_limit;
++ oldcred = delegation->cred;
++ delegation->cred = get_cred(cred);
++ clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
++ if (test_and_clear_bit(NFS_DELEGATION_REVOKED,
++ &delegation->flags))
++ atomic_long_inc(&nfs_active_delegations);
+ spin_unlock(&delegation->lock);
++ rcu_read_unlock();
++ put_cred(oldcred);
++ trace_nfs4_reclaim_delegation(inode, type);
++ } else {
++ rcu_read_unlock();
++ nfs_inode_set_delegation(inode, cred, type, stateid,
++ pagemod_limit);
+ }
+- rcu_read_unlock();
+- nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit);
+ }
+
+ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 6dab9e4083729..21c9e97c3ba30 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -1093,6 +1093,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
+ &args.seq_args, &res.seq_res, 0);
+ trace_nfs4_clone(src_inode, dst_inode, &args, status);
+ if (status == 0) {
++ /* a zero-length count means clone to EOF in src */
++ if (count == 0 && res.dst_fattr->valid & NFS_ATTR_FATTR_SIZE)
++ count = nfs_size_to_loff_t(res.dst_fattr->size) - dst_offset;
+ nfs42_copy_dest_done(dst_inode, dst_offset, count);
+ status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
+ }
+diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
+index 3c5678aec006f..8ae2827da28d8 100644
+--- a/fs/nfs/nfs4client.c
++++ b/fs/nfs/nfs4client.c
+@@ -346,6 +346,7 @@ int nfs40_init_client(struct nfs_client *clp)
+ ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
+ "NFSv4.0 transport Slot table");
+ if (ret) {
++ nfs4_shutdown_slot_table(tbl);
+ kfree(tbl);
+ return ret;
+ }
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index 9bab3e9c702a4..a629d7db9420a 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1787,6 +1787,7 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp,
+
+ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
+ {
++ set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
+ /* Mark all delegations for reclaim */
+ nfs_delegation_mark_reclaim(clp);
+ nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
+@@ -2671,6 +2672,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+ if (status < 0)
+ goto out_error;
+ nfs4_state_end_reclaim_reboot(clp);
++ continue;
+ }
+
+ /* Detect expired delegations... */
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index eeed4ae5b4ad9..173b38ffa4238 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -405,22 +405,15 @@ nfsd_file_unhash(struct nfsd_file *nf)
+ return false;
+ }
+
+-/*
+- * Return true if the file was unhashed.
+- */
+-static bool
++static void
+ nfsd_file_unhash_and_dispose(struct nfsd_file *nf, struct list_head *dispose)
+ {
+ trace_nfsd_file_unhash_and_dispose(nf);
+- if (!nfsd_file_unhash(nf))
+- return false;
+- /* keep final reference for nfsd_file_lru_dispose */
+- if (refcount_dec_not_one(&nf->nf_ref))
+- return true;
+-
+- nfsd_file_lru_remove(nf);
+- list_add(&nf->nf_lru, dispose);
+- return true;
++ if (nfsd_file_unhash(nf)) {
++ /* caller must call nfsd_file_dispose_list() later */
++ nfsd_file_lru_remove(nf);
++ list_add(&nf->nf_lru, dispose);
++ }
+ }
+
+ static void
+@@ -562,8 +555,6 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose)
+ * @lock: LRU list lock (unused)
+ * @arg: dispose list
+ *
+- * Note this can deadlock with nfsd_file_cache_purge.
+- *
+ * Return values:
+ * %LRU_REMOVED: @item was removed from the LRU
+ * %LRU_ROTATE: @item is to be moved to the LRU tail
+@@ -748,8 +739,6 @@ nfsd_file_close_inode(struct inode *inode)
+ *
+ * Walk the LRU list and close any entries that have not been used since
+ * the last scan.
+- *
+- * Note this can deadlock with nfsd_file_cache_purge.
+ */
+ static void
+ nfsd_file_delayed_close(struct work_struct *work)
+@@ -891,16 +880,12 @@ out_err:
+ goto out;
+ }
+
+-/*
+- * Note this can deadlock with nfsd_file_lru_cb.
+- */
+ static void
+ __nfsd_file_cache_purge(struct net *net)
+ {
+ struct rhashtable_iter iter;
+ struct nfsd_file *nf;
+ LIST_HEAD(dispose);
+- bool del;
+
+ rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter);
+ do {
+@@ -908,16 +893,8 @@ __nfsd_file_cache_purge(struct net *net)
+
+ nf = rhashtable_walk_next(&iter);
+ while (!IS_ERR_OR_NULL(nf)) {
+- if (net && nf->nf_net != net)
+- continue;
+- del = nfsd_file_unhash_and_dispose(nf, &dispose);
+-
+- /*
+- * Deadlock detected! Something marked this entry as
+- * unhased, but hasn't removed it from the hash list.
+- */
+- WARN_ON_ONCE(!del);
+-
++ if (!net || nf->nf_net == net)
++ nfsd_file_unhash_and_dispose(nf, &dispose);
+ nf = rhashtable_walk_next(&iter);
+ }
+
+diff --git a/fs/super.c b/fs/super.c
+index 734ed584a946e..8d39e4f11cfa3 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -291,7 +291,7 @@ static void __put_super(struct super_block *s)
+ WARN_ON(s->s_inode_lru.node);
+ WARN_ON(!list_empty(&s->s_mounts));
+ security_sb_free(s);
+- fscrypt_sb_free(s);
++ fscrypt_destroy_keyring(s);
+ put_user_ns(s->s_user_ns);
+ kfree(s->s_subtype);
+ call_rcu(&s->rcu, destroy_super_rcu);
+@@ -480,6 +480,7 @@ void generic_shutdown_super(struct super_block *sb)
+ evict_inodes(sb);
+ /* only nonzero refcount inodes can have marks */
+ fsnotify_sb_delete(sb);
++ fscrypt_destroy_keyring(sb);
+ security_sb_delete(sb);
+
+ if (sb->s_dio_done_wq) {
+diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
+index 34fb3431a8f36..292a5c40bd0c6 100644
+--- a/include/acpi/ghes.h
++++ b/include/acpi/ghes.h
+@@ -71,7 +71,7 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb);
+ void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
+ #endif
+
+-int ghes_estatus_pool_init(int num_ghes);
++int ghes_estatus_pool_init(unsigned int num_ghes);
+
+ /* From drivers/edac/ghes_edac.c */
+
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 4459794b65db0..f87b2f5db9f83 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1192,7 +1192,7 @@ efi_status_t efi_random_get_seed(void);
+ arch_efi_call_virt_teardown(); \
+ })
+
+-#define EFI_RANDOM_SEED_SIZE 64U
++#define EFI_RANDOM_SEED_SIZE 32U // BLAKE2S_HASH_SIZE
+
+ struct linux_efi_random_seed {
+ u32 size;
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 56a4b4b02477d..7203f5582fd44 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1472,7 +1472,7 @@ struct super_block {
+ const struct xattr_handler **s_xattr;
+ #ifdef CONFIG_FS_ENCRYPTION
+ const struct fscrypt_operations *s_cop;
+- struct key *s_master_keys; /* master crypto keys in use */
++ struct fscrypt_keyring *s_master_keys; /* master crypto keys in use */
+ #endif
+ #ifdef CONFIG_FS_VERITY
+ const struct fsverity_operations *s_vop;
+diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
+index 7d2f1e0f23b1f..d0e40a20ff810 100644
+--- a/include/linux/fscrypt.h
++++ b/include/linux/fscrypt.h
+@@ -312,7 +312,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
+ }
+
+ /* keyring.c */
+-void fscrypt_sb_free(struct super_block *sb);
++void fscrypt_destroy_keyring(struct super_block *sb);
+ int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);
+ int fscrypt_add_test_dummy_key(struct super_block *sb,
+ const struct fscrypt_dummy_policy *dummy_policy);
+@@ -526,7 +526,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
+ }
+
+ /* keyring.c */
+-static inline void fscrypt_sb_free(struct super_block *sb)
++static inline void fscrypt_destroy_keyring(struct super_block *sb)
+ {
+ }
+
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index 7a40f9bdc173e..dd8f994b8052b 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -1241,8 +1241,18 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data,
+ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
+
+ /**
+- * kvm_gfn_to_pfn_cache_init - prepare a cached kernel mapping and HPA for a
+- * given guest physical address.
++ * kvm_gpc_init - initialize gfn_to_pfn_cache.
++ *
++ * @gpc: struct gfn_to_pfn_cache object.
++ *
++ * This sets up a gfn_to_pfn_cache by initializing locks. Note, the cache must
++ * be zero-allocated (or zeroed by the caller before init).
++ */
++void kvm_gpc_init(struct gfn_to_pfn_cache *gpc);
++
++/**
++ * kvm_gpc_activate - prepare a cached kernel mapping and HPA for a given guest
++ * physical address.
+ *
+ * @kvm: pointer to kvm instance.
+ * @gpc: struct gfn_to_pfn_cache object.
+@@ -1266,9 +1276,9 @@ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
+ * kvm_gfn_to_pfn_cache_check() to ensure that the cache is valid before
+ * accessing the target page.
+ */
+-int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+- struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
+- gpa_t gpa, unsigned long len);
++int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
++ struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
++ gpa_t gpa, unsigned long len);
+
+ /**
+ * kvm_gfn_to_pfn_cache_check - check validity of a gfn_to_pfn_cache.
+@@ -1325,7 +1335,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+
+ /**
+- * kvm_gfn_to_pfn_cache_destroy - destroy and unlink a gfn_to_pfn_cache.
++ * kvm_gpc_deactivate - deactivate and unlink a gfn_to_pfn_cache.
+ *
+ * @kvm: pointer to kvm instance.
+ * @gpc: struct gfn_to_pfn_cache object.
+@@ -1333,7 +1343,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+ * This removes a cache from the @kvm's list to be processed on MMU notifier
+ * invocation.
+ */
+-void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
++void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+
+ void kvm_sigset_activate(struct kvm_vcpu *vcpu);
+ void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index 9689f38a0af1f..ec1896886dbd6 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -1046,6 +1046,8 @@ v4l2_subdev_get_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ unsigned int pad)
+ {
++ if (WARN_ON(!state))
++ return NULL;
+ if (WARN_ON(pad >= sd->entity.num_pads))
+ pad = 0;
+ return &state->pads[pad].try_fmt;
+@@ -1064,6 +1066,8 @@ v4l2_subdev_get_pad_crop(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ unsigned int pad)
+ {
++ if (WARN_ON(!state))
++ return NULL;
+ if (WARN_ON(pad >= sd->entity.num_pads))
+ pad = 0;
+ return &state->pads[pad].try_crop;
+@@ -1082,6 +1086,8 @@ v4l2_subdev_get_pad_compose(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ unsigned int pad)
+ {
++ if (WARN_ON(!state))
++ return NULL;
+ if (WARN_ON(pad >= sd->entity.num_pads))
+ pad = 0;
+ return &state->pads[pad].try_compose;
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 8a98ea9360fb7..f6e6838c82dfa 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1871,6 +1871,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size);
+ void sock_kzfree_s(struct sock *sk, void *mem, int size);
+ void sk_send_sigurg(struct sock *sk);
+
++static inline void sock_replace_proto(struct sock *sk, struct proto *proto)
++{
++ if (sk->sk_socket)
++ clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
++ WRITE_ONCE(sk->sk_prot, proto);
++}
++
+ struct sockcm_cookie {
+ u64 transmit_time;
+ u32 mark;
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index c5dd483a7de2f..d29f397f095ee 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2653,15 +2653,12 @@ static __cold void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx)
+ io_poll_remove_all(ctx, NULL, true);
+ mutex_unlock(&ctx->uring_lock);
+
+- /* failed during ring init, it couldn't have issued any requests */
+- if (ctx->rings) {
++ /*
++ * If we failed setting up the ctx, we might not have any rings
++ * and therefore did not submit any requests
++ */
++ if (ctx->rings)
+ io_kill_timeouts(ctx, NULL, true);
+- /* if we failed setting up the ctx, we might not have any rings */
+- io_iopoll_try_reap_events(ctx);
+- /* drop cached put refs after potentially doing completions */
+- if (current->io_uring)
+- io_uring_drop_tctx_refs(current);
+- }
+
+ INIT_WORK(&ctx->exit_work, io_ring_exit_work);
+ /*
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index ca9d834d0b843..917b92ae23821 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2425,8 +2425,11 @@ int enable_kprobe(struct kprobe *kp)
+ if (!kprobes_all_disarmed && kprobe_disabled(p)) {
+ p->flags &= ~KPROBE_FLAG_DISABLED;
+ ret = arm_kprobe(p);
+- if (ret)
++ if (ret) {
+ p->flags |= KPROBE_FLAG_DISABLED;
++ if (p != kp)
++ kp->flags |= KPROBE_FLAG_DISABLED;
++ }
+ }
+ out:
+ mutex_unlock(&kprobe_mutex);
+diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
+index aac63ca9c3d1e..e8143e3680744 100644
+--- a/kernel/trace/fprobe.c
++++ b/kernel/trace/fprobe.c
+@@ -141,6 +141,8 @@ static int fprobe_init_rethook(struct fprobe *fp, int num)
+ return -E2BIG;
+
+ fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler);
++ if (!fp->rethook)
++ return -ENOMEM;
+ for (i = 0; i < size; i++) {
+ struct fprobe_rethook_node *node;
+
+@@ -301,7 +303,8 @@ int unregister_fprobe(struct fprobe *fp)
+ {
+ int ret;
+
+- if (!fp || fp->ops.func != fprobe_handler)
++ if (!fp || (fp->ops.saved_func != fprobe_handler &&
++ fp->ops.saved_func != fprobe_kprobe_handler))
+ return -EINVAL;
+
+ /*
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 83362a1557916..8cc9eb60c3c2a 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -3031,18 +3031,8 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ command |= FTRACE_UPDATE_TRACE_FUNC;
+ }
+
+- if (!command || !ftrace_enabled) {
+- /*
+- * If these are dynamic or per_cpu ops, they still
+- * need their data freed. Since, function tracing is
+- * not currently active, we can just free them
+- * without synchronizing all CPUs.
+- */
+- if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
+- goto free_ops;
+-
+- return 0;
+- }
++ if (!command || !ftrace_enabled)
++ goto out;
+
+ /*
+ * If the ops uses a trampoline, then it needs to be
+@@ -3079,6 +3069,7 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ removed_ops = NULL;
+ ops->flags &= ~FTRACE_OPS_FL_REMOVING;
+
++out:
+ /*
+ * Dynamic ops may be freed, we must make sure that all
+ * callers are done before leaving this function.
+@@ -3106,7 +3097,6 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ if (IS_ENABLED(CONFIG_PREEMPTION))
+ synchronize_rcu_tasks();
+
+- free_ops:
+ ftrace_trampoline_free(ops);
+ }
+
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index 80e04a1e19772..d81f7c51025c7 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -100,20 +100,20 @@ static int __init test_gen_kprobe_cmd(void)
+ KPROBE_GEN_TEST_FUNC,
+ KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
+ if (ret)
+- goto free;
++ goto out;
+
+ /* Use kprobe_event_add_fields to add the rest of the fields */
+
+ ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
+ if (ret)
+- goto free;
++ goto out;
+
+ /*
+ * This actually creates the event.
+ */
+ ret = kprobe_event_gen_cmd_end(&cmd);
+ if (ret)
+- goto free;
++ goto out;
+
+ /*
+ * Now get the gen_kprobe_test event file. We need to prevent
+@@ -136,13 +136,11 @@ static int __init test_gen_kprobe_cmd(void)
+ goto delete;
+ }
+ out:
++ kfree(buf);
+ return ret;
+ delete:
+ /* We got an error after creating the event, delete it */
+ ret = kprobe_event_delete("gen_kprobe_test");
+- free:
+- kfree(buf);
+-
+ goto out;
+ }
+
+@@ -170,14 +168,14 @@ static int __init test_gen_kretprobe_cmd(void)
+ KPROBE_GEN_TEST_FUNC,
+ "$retval");
+ if (ret)
+- goto free;
++ goto out;
+
+ /*
+ * This actually creates the event.
+ */
+ ret = kretprobe_event_gen_cmd_end(&cmd);
+ if (ret)
+- goto free;
++ goto out;
+
+ /*
+ * Now get the gen_kretprobe_test event file. We need to
+@@ -201,13 +199,11 @@ static int __init test_gen_kretprobe_cmd(void)
+ goto delete;
+ }
+ out:
++ kfree(buf);
+ return ret;
+ delete:
+ /* We got an error after creating the event, delete it */
+ ret = kprobe_event_delete("gen_kretprobe_test");
+- free:
+- kfree(buf);
+-
+ goto out;
+ }
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index c3f354cfc5ba1..9c72571ffb0bf 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -937,6 +937,9 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct rb_irq_work *rbwork;
+
++ if (!buffer)
++ return;
++
+ if (cpu == RING_BUFFER_ALL_CPUS) {
+
+ /* Wake up individual ones too. One level recursion */
+@@ -945,7 +948,15 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+
+ rbwork = &buffer->irq_work;
+ } else {
++ if (WARN_ON_ONCE(!buffer->buffers))
++ return;
++ if (WARN_ON_ONCE(cpu >= nr_cpu_ids))
++ return;
++
+ cpu_buffer = buffer->buffers[cpu];
++ /* The CPU buffer may not have been initialized yet */
++ if (!cpu_buffer)
++ return;
+ rbwork = &cpu_buffer->irq_work;
+ }
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 9777e7b109eee..f26ed278d9e3c 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1003,10 +1003,21 @@ int hci_conn_del(struct hci_conn *conn)
+ hdev->acl_cnt += conn->sent;
+ } else {
+ struct hci_conn *acl = conn->link;
++
+ if (acl) {
+ acl->link = NULL;
+ hci_conn_drop(acl);
+ }
++
++ /* Unacked ISO frames */
++ if (conn->type == ISO_LINK) {
++ if (hdev->iso_pkts)
++ hdev->iso_cnt += conn->sent;
++ else if (hdev->le_pkts)
++ hdev->le_cnt += conn->sent;
++ else
++ hdev->acl_cnt += conn->sent;
++ }
+ }
+
+ if (conn->amp_mgr)
+@@ -1697,6 +1708,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ if (!cis)
+ return ERR_PTR(-ENOMEM);
+ cis->cleanup = cis_cleanup;
++ cis->dst_type = dst_type;
+ }
+
+ if (cis->state == BT_CONNECTED)
+@@ -2076,12 +2088,6 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ struct hci_conn *le;
+ struct hci_conn *cis;
+
+- /* Convert from ISO socket address type to HCI address type */
+- if (dst_type == BDADDR_LE_PUBLIC)
+- dst_type = ADDR_LE_DEV_PUBLIC;
+- else
+- dst_type = ADDR_LE_DEV_RANDOM;
+-
+ if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
+ le = hci_connect_le(hdev, dst, dst_type, false,
+ BT_SECURITY_LOW,
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 613039ba5dbf5..f825857db6d0b 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -235,6 +235,14 @@ static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
+ return err;
+ }
+
++static inline u8 le_addr_type(u8 bdaddr_type)
++{
++ if (bdaddr_type == BDADDR_LE_PUBLIC)
++ return ADDR_LE_DEV_PUBLIC;
++ else
++ return ADDR_LE_DEV_RANDOM;
++}
++
+ static int iso_connect_bis(struct sock *sk)
+ {
+ struct iso_conn *conn;
+@@ -328,14 +336,16 @@ static int iso_connect_cis(struct sock *sk)
+ /* Just bind if DEFER_SETUP has been set */
+ if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
+ hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
+- iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
++ le_addr_type(iso_pi(sk)->dst_type),
++ &iso_pi(sk)->qos);
+ if (IS_ERR(hcon)) {
+ err = PTR_ERR(hcon);
+ goto done;
+ }
+ } else {
+ hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
+- iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
++ le_addr_type(iso_pi(sk)->dst_type),
++ &iso_pi(sk)->qos);
+ if (IS_ERR(hcon)) {
+ err = PTR_ERR(hcon);
+ goto done;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 1f34b82ca0ec9..4df3d0ed6c80d 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -3764,7 +3764,8 @@ done:
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
+
+- if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
++ if (remote_efs &&
++ test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ chan->remote_id = efs.id;
+ chan->remote_stype = efs.stype;
+ chan->remote_msdu = le16_to_cpu(efs.msdu);
+@@ -5813,6 +5814,19 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
+ BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
+ scid, mtu, mps);
+
++ /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
++ * page 1059:
++ *
++ * Valid range: 0x0001-0x00ff
++ *
++ * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
++ */
++ if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
++ result = L2CAP_CR_LE_BAD_PSM;
++ chan = NULL;
++ goto response;
++ }
++
+ /* Check if we have socket listening on psm */
+ pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
+ &conn->hcon->dst, LE_LINK);
+@@ -6001,6 +6015,18 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
+
+ psm = req->psm;
+
++ /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
++ * page 1059:
++ *
++ * Valid range: 0x0001-0x00ff
++ *
++ * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
++ */
++ if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
++ result = L2CAP_CR_LE_BAD_PSM;
++ goto response;
++ }
++
+ BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
+
+ memset(&pdu, 0, sizeof(pdu));
+@@ -6885,6 +6911,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+ struct l2cap_ctrl *control,
+ struct sk_buff *skb, u8 event)
+ {
++ struct l2cap_ctrl local_control;
+ int err = 0;
+ bool skb_in_use = false;
+
+@@ -6909,15 +6936,32 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+ chan->buffer_seq = chan->expected_tx_seq;
+ skb_in_use = true;
+
++ /* l2cap_reassemble_sdu may free skb, hence invalidate
++ * control, so make a copy in advance to use it after
++ * l2cap_reassemble_sdu returns and to avoid the race
++ * condition, for example:
++ *
++ * The current thread calls:
++ * l2cap_reassemble_sdu
++ * chan->ops->recv == l2cap_sock_recv_cb
++ * __sock_queue_rcv_skb
++ * Another thread calls:
++ * bt_sock_recvmsg
++ * skb_recv_datagram
++ * skb_free_datagram
++ * Then the current thread tries to access control, but
++ * it was freed by skb_free_datagram.
++ */
++ local_control = *control;
+ err = l2cap_reassemble_sdu(chan, skb, control);
+ if (err)
+ break;
+
+- if (control->final) {
++ if (local_control.final) {
+ if (!test_and_clear_bit(CONN_REJ_ACT,
+ &chan->conn_state)) {
+- control->final = 0;
+- l2cap_retransmit_all(chan, control);
++ local_control.final = 0;
++ l2cap_retransmit_all(chan, &local_control);
+ l2cap_ertm_send(chan);
+ }
+ }
+@@ -7297,11 +7341,27 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ struct sk_buff *skb)
+ {
++ /* l2cap_reassemble_sdu may free skb, hence invalidate control, so store
++ * the txseq field in advance to use it after l2cap_reassemble_sdu
++ * returns and to avoid the race condition, for example:
++ *
++ * The current thread calls:
++ * l2cap_reassemble_sdu
++ * chan->ops->recv == l2cap_sock_recv_cb
++ * __sock_queue_rcv_skb
++ * Another thread calls:
++ * bt_sock_recvmsg
++ * skb_recv_datagram
++ * skb_free_datagram
++ * Then the current thread tries to access control, but it was freed by
++ * skb_free_datagram.
++ */
++ u16 txseq = control->txseq;
++
+ BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
+ chan->rx_state);
+
+- if (l2cap_classify_txseq(chan, control->txseq) ==
+- L2CAP_TXSEQ_EXPECTED) {
++ if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) {
+ l2cap_pass_to_tx(chan, control);
+
+ BT_DBG("buffer_seq %u->%u", chan->buffer_seq,
+@@ -7324,8 +7384,8 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ }
+ }
+
+- chan->last_acked_seq = control->txseq;
+- chan->expected_tx_seq = __next_seq(chan, control->txseq);
++ chan->last_acked_seq = txseq;
++ chan->expected_tx_seq = __next_seq(chan, txseq);
+
+ return 0;
+ }
+@@ -7581,6 +7641,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
+ return;
+ }
+
++ l2cap_chan_hold(chan);
+ l2cap_chan_lock(chan);
+ } else {
+ BT_DBG("unknown cid 0x%4.4x", cid);
+@@ -8426,9 +8487,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+ * expected length.
+ */
+ if (skb->len < L2CAP_LEN_SIZE) {
+- if (l2cap_recv_frag(conn, skb, conn->mtu) < 0)
+- goto drop;
+- return;
++ l2cap_recv_frag(conn, skb, conn->mtu);
++ break;
+ }
+
+ len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE;
+@@ -8472,7 +8532,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+
+ /* Header still could not be read just continue */
+ if (conn->rx_skb->len < L2CAP_LEN_SIZE)
+- return;
++ break;
+ }
+
+ if (skb->len > conn->rx_len) {
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 5aeb3646e74c7..d087fd4c784ac 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -1332,7 +1332,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
+
+ if (data[IFLA_BR_FDB_FLUSH]) {
+ struct net_bridge_fdb_flush_desc desc = {
+- .flags_mask = BR_FDB_STATIC
++ .flags_mask = BIT(BR_FDB_STATIC)
+ };
+
+ br_fdb_flush(br, &desc);
+diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
+index 612e367fff20d..ea733542244c7 100644
+--- a/net/bridge/br_sysfs_br.c
++++ b/net/bridge/br_sysfs_br.c
+@@ -345,7 +345,7 @@ static int set_flush(struct net_bridge *br, unsigned long val,
+ struct netlink_ext_ack *extack)
+ {
+ struct net_bridge_fdb_flush_desc desc = {
+- .flags_mask = BR_FDB_STATIC
++ .flags_mask = BIT(BR_FDB_STATIC)
+ };
+
+ br_fdb_flush(br, &desc);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 78cc8fb688140..84755db81e9d9 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -409,7 +409,7 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
+ write_lock_bh(&tbl->lock);
+ neigh_flush_dev(tbl, dev, skip_perm);
+ pneigh_ifdown_and_unlock(tbl, dev);
+- pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev));
++ pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
+ if (skb_queue_empty_lockless(&tbl->proxy_queue))
+ del_timer_sync(&tbl->proxy_timer);
+ return 0;
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index cac48a741f27c..e537655e442b8 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -1407,9 +1407,9 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,
+ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
+ const char *user_protocol)
+ {
++ const struct dsa_device_ops *tag_ops = NULL;
+ struct dsa_switch *ds = dp->ds;
+ struct dsa_switch_tree *dst = ds->dst;
+- const struct dsa_device_ops *tag_ops;
+ enum dsa_tag_protocol default_proto;
+
+ /* Find out which protocol the switch would prefer. */
+@@ -1432,10 +1432,17 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
+ }
+
+ tag_ops = dsa_find_tagger_by_name(user_protocol);
+- } else {
+- tag_ops = dsa_tag_driver_get(default_proto);
++ if (IS_ERR(tag_ops)) {
++ dev_warn(ds->dev,
++ "Failed to find a tagging driver for protocol %s, using default\n",
++ user_protocol);
++ tag_ops = NULL;
++ }
+ }
+
++ if (!tag_ops)
++ tag_ops = dsa_tag_driver_get(default_proto);
++
+ if (IS_ERR(tag_ops)) {
+ if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
+ return -EPROBE_DEFER;
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 3ca0cc4678862..7f6d7c355e38e 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -748,6 +748,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags,
+ (TCPF_ESTABLISHED | TCPF_SYN_RECV |
+ TCPF_CLOSE_WAIT | TCPF_CLOSE)));
+
++ if (test_bit(SOCK_SUPPORT_ZC, &sock->flags))
++ set_bit(SOCK_SUPPORT_ZC, &newsock->flags);
+ sock_graft(sk2, newsock);
+
+ newsock->state = SS_CONNECTED;
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index a1626afe87a10..c501c329b1dbe 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -607,7 +607,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+ } else {
+ sk->sk_write_space = psock->saved_write_space;
+ /* Pairs with lockless read in sk_clone_lock() */
+- WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++ sock_replace_proto(sk, psock->sk_proto);
+ }
+ return 0;
+ }
+@@ -620,7 +620,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+ }
+
+ /* Pairs with lockless read in sk_clone_lock() */
+- WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]);
++ sock_replace_proto(sk, &tcp_bpf_prots[family][config]);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(tcp_bpf_update_proto);
+diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
+index 7c27aa629af19..9ae50b1bd8444 100644
+--- a/net/ipv4/tcp_ulp.c
++++ b/net/ipv4/tcp_ulp.c
+@@ -136,6 +136,9 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
+ if (icsk->icsk_ulp_ops)
+ goto out_err;
+
++ if (sk->sk_socket)
++ clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
++
+ err = ulp_ops->init(sk);
+ if (err)
+ goto out_err;
+diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
+index ff15918b7bdc7..e5dc91d0e0793 100644
+--- a/net/ipv4/udp_bpf.c
++++ b/net/ipv4/udp_bpf.c
+@@ -141,14 +141,14 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+
+ if (restore) {
+ sk->sk_write_space = psock->saved_write_space;
+- WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++ sock_replace_proto(sk, psock->sk_proto);
+ return 0;
+ }
+
+ if (sk->sk_family == AF_INET6)
+ udp_bpf_check_v6_needs_rebuild(psock->sk_proto);
+
+- WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]);
++ sock_replace_proto(sk, &udp_bpf_prots[family]);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(udp_bpf_update_proto);
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 69252eb462b2d..2f355f0ec32ac 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -6555,10 +6555,16 @@ static void __net_exit ip6_route_net_exit(struct net *net)
+ static int __net_init ip6_route_net_init_late(struct net *net)
+ {
+ #ifdef CONFIG_PROC_FS
+- proc_create_net("ipv6_route", 0, net->proc_net, &ipv6_route_seq_ops,
+- sizeof(struct ipv6_route_iter));
+- proc_create_net_single("rt6_stats", 0444, net->proc_net,
+- rt6_stats_seq_show, NULL);
++ if (!proc_create_net("ipv6_route", 0, net->proc_net,
++ &ipv6_route_seq_ops,
++ sizeof(struct ipv6_route_iter)))
++ return -ENOMEM;
++
++ if (!proc_create_net_single("rt6_stats", 0444, net->proc_net,
++ rt6_stats_seq_show, NULL)) {
++ remove_proc_entry("ipv6_route", net->proc_net);
++ return -ENOMEM;
++ }
+ #endif
+ return 0;
+ }
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 6e391308431da..3adc291d9ce18 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -42,31 +42,8 @@
+ #define AHASH_MAX_SIZE (6 * AHASH_INIT_SIZE)
+ /* Max muber of elements in the array block when tuned */
+ #define AHASH_MAX_TUNED 64
+-
+ #define AHASH_MAX(h) ((h)->bucketsize)
+
+-/* Max number of elements can be tuned */
+-#ifdef IP_SET_HASH_WITH_MULTI
+-static u8
+-tune_bucketsize(u8 curr, u32 multi)
+-{
+- u32 n;
+-
+- if (multi < curr)
+- return curr;
+-
+- n = curr + AHASH_INIT_SIZE;
+- /* Currently, at listing one hash bucket must fit into a message.
+- * Therefore we have a hard limit here.
+- */
+- return n > curr && n <= AHASH_MAX_TUNED ? n : curr;
+-}
+-#define TUNE_BUCKETSIZE(h, multi) \
+- ((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi))
+-#else
+-#define TUNE_BUCKETSIZE(h, multi)
+-#endif
+-
+ /* A hash bucket */
+ struct hbucket {
+ struct rcu_head rcu; /* for call_rcu */
+@@ -936,7 +913,12 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ goto set_full;
+ /* Create a new slot */
+ if (n->pos >= n->size) {
+- TUNE_BUCKETSIZE(h, multi);
++#ifdef IP_SET_HASH_WITH_MULTI
++ if (h->bucketsize >= AHASH_MAX_TUNED)
++ goto set_full;
++ else if (h->bucketsize < multi)
++ h->bucketsize += AHASH_INIT_SIZE;
++#endif
+ if (n->size >= AHASH_MAX(h)) {
+ /* Trigger rehashing */
+ mtype_data_next(&h->next, d);
+diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
+index f9b16f2b22191..fdacbc3c15bef 100644
+--- a/net/netfilter/ipvs/ip_vs_app.c
++++ b/net/netfilter/ipvs/ip_vs_app.c
+@@ -599,13 +599,19 @@ static const struct seq_operations ip_vs_app_seq_ops = {
+ int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs)
+ {
+ INIT_LIST_HEAD(&ipvs->app_list);
+- proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops,
+- sizeof(struct seq_net_private));
++#ifdef CONFIG_PROC_FS
++ if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net,
++ &ip_vs_app_seq_ops,
++ sizeof(struct seq_net_private)))
++ return -ENOMEM;
++#endif
+ return 0;
+ }
+
+ void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs)
+ {
+ unregister_ip_vs_app(ipvs, NULL /* all */);
++#ifdef CONFIG_PROC_FS
+ remove_proc_entry("ip_vs_app", ipvs->net->proc_net);
++#endif
+ }
+diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
+index fb67f1ca2495b..cb6d68220c265 100644
+--- a/net/netfilter/ipvs/ip_vs_conn.c
++++ b/net/netfilter/ipvs/ip_vs_conn.c
+@@ -1265,8 +1265,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
+ * The drop rate array needs tuning for real environments.
+ * Called from timer bh only => no locking
+ */
+- static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+- static char todrop_counter[9] = {0};
++ static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
++ static signed char todrop_counter[9] = {0};
+ int i;
+
+ /* if the conn entry hasn't lasted for 60 seconds, don't drop it.
+@@ -1447,20 +1447,36 @@ int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
+ {
+ atomic_set(&ipvs->conn_count, 0);
+
+- proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
+- &ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state));
+- proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
+- &ip_vs_conn_sync_seq_ops,
+- sizeof(struct ip_vs_iter_state));
++#ifdef CONFIG_PROC_FS
++ if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
++ &ip_vs_conn_seq_ops,
++ sizeof(struct ip_vs_iter_state)))
++ goto err_conn;
++
++ if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
++ &ip_vs_conn_sync_seq_ops,
++ sizeof(struct ip_vs_iter_state)))
++ goto err_conn_sync;
++#endif
++
+ return 0;
++
++#ifdef CONFIG_PROC_FS
++err_conn_sync:
++ remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
++err_conn:
++ return -ENOMEM;
++#endif
+ }
+
+ void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
+ {
+ /* flush all the connection entries first */
+ ip_vs_conn_flush(ipvs);
++#ifdef CONFIG_PROC_FS
+ remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
+ remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
++#endif
+ }
+
+ int __init ip_vs_conn_init(void)
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 5897afd124668..879f4a1a27d54 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -8465,9 +8465,6 @@ static void nft_commit_release(struct nft_trans *trans)
+ nf_tables_chain_destroy(&trans->ctx);
+ break;
+ case NFT_MSG_DELRULE:
+- if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
+- nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+-
+ nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
+ break;
+ case NFT_MSG_DELSET:
+@@ -8973,6 +8970,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_rule_expr_deactivate(&trans->ctx,
+ nft_trans_rule(trans),
+ NFT_TRANS_COMMIT);
++
++ if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
++ nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ break;
+ case NFT_MSG_NEWSET:
+ nft_clear(net, nft_trans_set(trans));
+@@ -10030,6 +10030,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
+ nft_net = nft_pernet(net);
+ deleted = 0;
+ mutex_lock(&nft_net->commit_mutex);
++ if (!list_empty(&nf_tables_destroy_list))
++ rcu_barrier();
+ again:
+ list_for_each_entry(table, &nft_net->tables, list) {
+ if (nft_table_has_owner(table) &&
+diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
+index 8b96a56d3a49b..0f77ae8ef944a 100644
+--- a/net/rose/rose_link.c
++++ b/net/rose/rose_link.c
+@@ -236,6 +236,9 @@ void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, uns
+ unsigned char *dptr;
+ int len;
+
++ if (!neigh->dev)
++ return;
++
+ len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
+
+ if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
+diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
+index f1e013e3f04a9..935d90874b1b7 100644
+--- a/net/sched/sch_red.c
++++ b/net/sched/sch_red.c
+@@ -72,6 +72,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ {
+ struct red_sched_data *q = qdisc_priv(sch);
+ struct Qdisc *child = q->qdisc;
++ unsigned int len;
+ int ret;
+
+ q->vars.qavg = red_calc_qavg(&q->parms,
+@@ -126,9 +127,10 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ break;
+ }
+
++ len = qdisc_pkt_len(skb);
+ ret = qdisc_enqueue(skb, child, to_free);
+ if (likely(ret == NET_XMIT_SUCCESS)) {
+- qdisc_qstats_backlog_inc(sch, skb);
++ sch->qstats.backlog += len;
+ sch->q.qlen++;
+ } else if (net_xmit_drop_count(ret)) {
+ q->stats.pdrop++;
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 0939cc3b915af..58ff5f33b3700 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -3380,14 +3380,14 @@ static int __init smc_init(void)
+
+ rc = register_pernet_subsys(&smc_net_stat_ops);
+ if (rc)
+- return rc;
++ goto out_pernet_subsys;
+
+ smc_ism_init();
+ smc_clc_init();
+
+ rc = smc_nl_init();
+ if (rc)
+- goto out_pernet_subsys;
++ goto out_pernet_subsys_stat;
+
+ rc = smc_pnet_init();
+ if (rc)
+@@ -3480,6 +3480,8 @@ out_pnet:
+ smc_pnet_exit();
+ out_nl:
+ smc_nl_exit();
++out_pernet_subsys_stat:
++ unregister_pernet_subsys(&smc_net_stat_ops);
+ out_pernet_subsys:
+ unregister_pernet_subsys(&smc_net_ops);
+
+diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
+index c65c90ad626ad..c1f559892ae8a 100644
+--- a/net/sunrpc/sysfs.c
++++ b/net/sunrpc/sysfs.c
+@@ -518,13 +518,16 @@ void rpc_sysfs_client_setup(struct rpc_clnt *clnt,
+ struct net *net)
+ {
+ struct rpc_sysfs_client *rpc_client;
++ struct rpc_sysfs_xprt_switch *xswitch =
++ (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
++
++ if (!xswitch)
++ return;
+
+ rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj,
+ net, clnt->cl_clid);
+ if (rpc_client) {
+ char name[] = "switch";
+- struct rpc_sysfs_xprt_switch *xswitch =
+- (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
+ int ret;
+
+ clnt->cl_sysfs = rpc_client;
+@@ -558,6 +561,8 @@ void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch *xprt_switch,
+ rpc_xprt_switch->xprt_switch = xprt_switch;
+ rpc_xprt_switch->xprt = xprt;
+ kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD);
++ } else {
++ xprt_switch->xps_sysfs = NULL;
+ }
+ }
+
+@@ -569,6 +574,9 @@ void rpc_sysfs_xprt_setup(struct rpc_xprt_switch *xprt_switch,
+ struct rpc_sysfs_xprt_switch *switch_obj =
+ (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
+
++ if (!switch_obj)
++ return;
++
+ rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags);
+ if (rpc_xprt) {
+ xprt->xprt_sysfs = rpc_xprt;
+diff --git a/net/unix/unix_bpf.c b/net/unix/unix_bpf.c
+index 7cf14c6b17254..e9bf155139612 100644
+--- a/net/unix/unix_bpf.c
++++ b/net/unix/unix_bpf.c
+@@ -145,12 +145,12 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool re
+
+ if (restore) {
+ sk->sk_write_space = psock->saved_write_space;
+- WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++ sock_replace_proto(sk, psock->sk_proto);
+ return 0;
+ }
+
+ unix_dgram_bpf_check_needs_rebuild(psock->sk_proto);
+- WRITE_ONCE(sk->sk_prot, &unix_dgram_bpf_prot);
++ sock_replace_proto(sk, &unix_dgram_bpf_prot);
+ return 0;
+ }
+
+@@ -158,12 +158,12 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r
+ {
+ if (restore) {
+ sk->sk_write_space = psock->saved_write_space;
+- WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++ sock_replace_proto(sk, psock->sk_proto);
+ return 0;
+ }
+
+ unix_stream_bpf_check_needs_rebuild(psock->sk_proto);
+- WRITE_ONCE(sk->sk_prot, &unix_stream_bpf_prot);
++ sock_replace_proto(sk, &unix_stream_bpf_prot);
+ return 0;
+ }
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index b4ee163154a68..e5ab2418f9d6b 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1894,8 +1894,11 @@ static int vsock_connectible_wait_data(struct sock *sk,
+ err = 0;
+ transport = vsk->transport;
+
+- while ((data = vsock_connectible_has_data(vsk)) == 0) {
++ while (1) {
+ prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE);
++ data = vsock_connectible_has_data(vsk);
++ if (data != 0)
++ break;
+
+ if (sk->sk_err != 0 ||
+ (sk->sk_shutdown & RCV_SHUTDOWN) ||
+diff --git a/security/commoncap.c b/security/commoncap.c
+index 5fc8986c3c77c..bc751fa5adad7 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -401,8 +401,10 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+ &tmpbuf, size, GFP_NOFS);
+ dput(dentry);
+
+- if (ret < 0 || !tmpbuf)
+- return ret;
++ if (ret < 0 || !tmpbuf) {
++ size = ret;
++ goto out_free;
++ }
+
+ fs_ns = inode->i_sb->s_user_ns;
+ cap = (struct vfs_cap_data *) tmpbuf;
+diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
+index bef35bee9c44c..ad97c0d522b8e 100644
+--- a/tools/include/nolibc/string.h
++++ b/tools/include/nolibc/string.h
+@@ -19,9 +19,9 @@ static __attribute__((unused))
+ int memcmp(const void *s1, const void *s2, size_t n)
+ {
+ size_t ofs = 0;
+- char c1 = 0;
++ int c1 = 0;
+
+- while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) {
++ while (ofs < n && !(c1 = ((unsigned char *)s1)[ofs] - ((unsigned char *)s2)[ofs])) {
+ ofs++;
+ }
+ return c1;
+@@ -125,14 +125,18 @@ char *strcpy(char *dst, const char *src)
+ }
+
+ /* this function is only used with arguments that are not constants or when
+- * it's not known because optimizations are disabled.
++ * it's not known because optimizations are disabled. Note that gcc 12
++ * recognizes an strlen() pattern and replaces it with a jump to strlen(),
++ * thus itself, hence the asm() statement below that's meant to disable this
++ * confusing practice.
+ */
+ static __attribute__((unused))
+-size_t nolibc_strlen(const char *str)
++size_t strlen(const char *str)
+ {
+ size_t len;
+
+- for (len = 0; str[len]; len++);
++ for (len = 0; str[len]; len++)
++ asm("");
+ return len;
+ }
+
+@@ -140,13 +144,12 @@ size_t nolibc_strlen(const char *str)
+ * the two branches, then will rely on an external definition of strlen().
+ */
+ #if defined(__OPTIMIZE__)
++#define nolibc_strlen(x) strlen(x)
+ #define strlen(str) ({ \
+ __builtin_constant_p((str)) ? \
+ __builtin_strlen((str)) : \
+ nolibc_strlen((str)); \
+ })
+-#else
+-#define strlen(str) nolibc_strlen((str))
+ #endif
+
+ static __attribute__((unused))
+diff --git a/tools/testing/selftests/landlock/Makefile b/tools/testing/selftests/landlock/Makefile
+index 6632bfff486b8..348e2dbdb4e0b 100644
+--- a/tools/testing/selftests/landlock/Makefile
++++ b/tools/testing/selftests/landlock/Makefile
+@@ -3,7 +3,6 @@
+ # First run: make -C ../../../.. headers_install
+
+ CFLAGS += -Wall -O2 $(KHDR_INCLUDES)
+-LDLIBS += -lcap
+
+ LOCAL_HDRS += common.h
+
+@@ -13,10 +12,12 @@ TEST_GEN_PROGS := $(src_test:.c=)
+
+ TEST_GEN_PROGS_EXTENDED := true
+
+-# Static linking for short targets:
++# Short targets:
++$(TEST_GEN_PROGS): LDLIBS += -lcap
+ $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static
+
+ include ../lib.mk
+
+-# Static linking for targets with $(OUTPUT)/ prefix:
++# Targets with $(OUTPUT)/ prefix:
++$(TEST_GEN_PROGS): LDLIBS += -lcap
+ $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static
+diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
+index 68ff41d395452..346e47f155724 100644
+--- a/virt/kvm/pfncache.c
++++ b/virt/kvm/pfncache.c
+@@ -81,6 +81,9 @@ bool kvm_gfn_to_pfn_cache_check(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ {
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+
++ if (!gpc->active)
++ return false;
++
+ if ((gpa & ~PAGE_MASK) + len > PAGE_SIZE)
+ return false;
+
+@@ -240,10 +243,11 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ {
+ struct kvm_memslots *slots = kvm_memslots(kvm);
+ unsigned long page_offset = gpa & ~PAGE_MASK;
+- kvm_pfn_t old_pfn, new_pfn;
++ bool unmap_old = false;
+ unsigned long old_uhva;
++ kvm_pfn_t old_pfn;
+ void *old_khva;
+- int ret = 0;
++ int ret;
+
+ /*
+ * If must fit within a single page. The 'len' argument is
+@@ -261,6 +265,11 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+
+ write_lock_irq(&gpc->lock);
+
++ if (!gpc->active) {
++ ret = -EINVAL;
++ goto out_unlock;
++ }
++
+ old_pfn = gpc->pfn;
+ old_khva = gpc->khva - offset_in_page(gpc->khva);
+ old_uhva = gpc->uhva;
+@@ -291,6 +300,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ /* If the HVA→PFN mapping was already valid, don't unmap it. */
+ old_pfn = KVM_PFN_ERR_FAULT;
+ old_khva = NULL;
++ ret = 0;
+ }
+
+ out:
+@@ -305,14 +315,15 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ gpc->khva = NULL;
+ }
+
+- /* Snapshot the new pfn before dropping the lock! */
+- new_pfn = gpc->pfn;
++ /* Detect a pfn change before dropping the lock! */
++ unmap_old = (old_pfn != gpc->pfn);
+
++out_unlock:
+ write_unlock_irq(&gpc->lock);
+
+ mutex_unlock(&gpc->refresh_lock);
+
+- if (old_pfn != new_pfn)
++ if (unmap_old)
+ gpc_unmap_khva(kvm, old_pfn, old_khva);
+
+ return ret;
+@@ -346,42 +357,61 @@ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
+ }
+ EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap);
+
++void kvm_gpc_init(struct gfn_to_pfn_cache *gpc)
++{
++ rwlock_init(&gpc->lock);
++ mutex_init(&gpc->refresh_lock);
++}
++EXPORT_SYMBOL_GPL(kvm_gpc_init);
+
+-int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+- struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
+- gpa_t gpa, unsigned long len)
++int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
++ struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
++ gpa_t gpa, unsigned long len)
+ {
+ WARN_ON_ONCE(!usage || (usage & KVM_GUEST_AND_HOST_USE_PFN) != usage);
+
+ if (!gpc->active) {
+- rwlock_init(&gpc->lock);
+- mutex_init(&gpc->refresh_lock);
+-
+ gpc->khva = NULL;
+ gpc->pfn = KVM_PFN_ERR_FAULT;
+ gpc->uhva = KVM_HVA_ERR_BAD;
+ gpc->vcpu = vcpu;
+ gpc->usage = usage;
+ gpc->valid = false;
+- gpc->active = true;
+
+ spin_lock(&kvm->gpc_lock);
+ list_add(&gpc->list, &kvm->gpc_list);
+ spin_unlock(&kvm->gpc_lock);
++
++ /*
++ * Activate the cache after adding it to the list, a concurrent
++ * refresh must not establish a mapping until the cache is
++ * reachable by mmu_notifier events.
++ */
++ write_lock_irq(&gpc->lock);
++ gpc->active = true;
++ write_unlock_irq(&gpc->lock);
+ }
+ return kvm_gfn_to_pfn_cache_refresh(kvm, gpc, gpa, len);
+ }
+-EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_init);
++EXPORT_SYMBOL_GPL(kvm_gpc_activate);
+
+-void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
++void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
+ {
+ if (gpc->active) {
++ /*
++ * Deactivate the cache before removing it from the list, KVM
++ * must stall mmu_notifier events until all users go away, i.e.
++ * until gpc->lock is dropped and refresh is guaranteed to fail.
++ */
++ write_lock_irq(&gpc->lock);
++ gpc->active = false;
++ write_unlock_irq(&gpc->lock);
++
+ spin_lock(&kvm->gpc_lock);
+ list_del(&gpc->list);
+ spin_unlock(&kvm->gpc_lock);
+
+ kvm_gfn_to_pfn_cache_unmap(kvm, gpc);
+- gpc->active = false;
+ }
+ }
+-EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_destroy);
++EXPORT_SYMBOL_GPL(kvm_gpc_deactivate);
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-10 18:18 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-10 18:18 UTC (permalink / raw
To: gentoo-commits
commit: e9f10a9f82f0947e4dbab972345827bf6ddcd393
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 18:18:04 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 18:18:04 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e9f10a9f
Remove redundant patch
Removed:
btrfs: Don't use btrfs_chunk::sub_stripes from disk
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 --
1900_btrfs-chunk-sub_stripes-fix.patch | 92 ----------------------------------
2 files changed, 96 deletions(-)
diff --git a/0000_README b/0000_README
index 52ac8549..04880a09 100644
--- a/0000_README
+++ b/0000_README
@@ -87,10 +87,6 @@ Patch: 1700_sparc-address-warray-bound-warnings.patch
From: https://github.com/KSPP/linux/issues/109
Desc: Address -Warray-bounds warnings
-Patch: 1900_btrfs-chunk-sub_stripes-fix.patch
-From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-Desc: btrfs: Don't use btrfs_chunk::sub_stripes from disk
-
Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch
deleted file mode 100644
index 2ffe02fe..00000000
--- a/1900_btrfs-chunk-sub_stripes-fix.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001
-From: Qu Wenruo <wqu@suse.com>
-Date: Fri, 21 Oct 2022 08:43:45 +0800
-Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk
-
-[BUG]
-There are two reports (the earliest one from LKP, a more recent one from
-kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
-
-This will cause divide-by-zero errors at btrfs_rmap_block, which is
-introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
-calculations for simple striped profiles in btrfs_rmap_block"):
-
- if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
- BTRFS_BLOCK_GROUP_RAID10)) {
- stripe_nr = stripe_nr * map->num_stripes + i;
- stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
- }
-
-[CAUSE]
-From the more recent report, it has been proven that we have some chunks
-with 0 as sub_stripes, mostly caused by older mkfs.
-
-It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
-("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
-which is included in v5.4 btrfs-progs release.
-
-So there would be quite some old filesystems with such 0 sub_stripes.
-
-[FIX]
-Just don't trust the sub_stripes values from disk.
-
-We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
-numbers for each profile and that are fixed.
-
-By this, we can keep the compatibility with older filesystems while
-still avoid divide-by-zero bugs.
-
-Reported-by: kernel test robot <oliver.sang@intel.com>
-Reported-by: Viktor Kuzmin <kvaster@gmail.com>
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559
-Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
-CC: stable@vger.kernel.org # 6.0
-Reviewed-by: Su Yue <glass@fydeos.io>
-Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
-Signed-off-by: Qu Wenruo <wqu@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
----
- fs/btrfs/volumes.c | 12 +++++++++++-
- 1 file changed, 11 insertions(+), 1 deletion(-)
-
-(limited to 'fs/btrfs/volumes.c')
-
-diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
-index 94ba46d579205..a8d4bc6a19379 100644
---- a/fs/btrfs/volumes.c
-+++ b/fs/btrfs/volumes.c
-@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- u64 devid;
- u64 type;
- u8 uuid[BTRFS_UUID_SIZE];
-+ int index;
- int num_stripes;
- int ret;
- int i;
-@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- logical = key->offset;
- length = btrfs_chunk_length(leaf, chunk);
- type = btrfs_chunk_type(leaf, chunk);
-+ index = btrfs_bg_flags_to_raid_index(type);
- num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
-
- #if BITS_PER_LONG == 32
-@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- map->io_align = btrfs_chunk_io_align(leaf, chunk);
- map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
- map->type = type;
-- map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
-+ /*
-+ * We can't use the sub_stripes value, as for profiles other than
-+ * RAID10, they may have 0 as sub_stripes for filesystems created by
-+ * older mkfs (<v5.4).
-+ * In that case, it can cause divide-by-zero errors later.
-+ * Since currently sub_stripes is fixed for each profile, let's
-+ * use the trusted value instead.
-+ */
-+ map->sub_stripes = btrfs_raid_array[index].sub_stripes;
- map->verified_stripes = 0;
- em->orig_block_len = btrfs_calc_stripe_length(em);
- for (i = 0; i < num_stripes; i++) {
---
-cgit
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-16 11:16 Alice Ferrazzi
0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-11-16 11:16 UTC (permalink / raw
To: gentoo-commits
commit: 167e638e734a78f986f9cb92a872a2e5ed7b2a1f
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 16 11:11:17 2022 +0000
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Nov 16 11:11:17 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=167e638e
Linux patch 6.0.9
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>
0000_README | 4 +
1008_linux-6.0.9.patch | 6943 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 6947 insertions(+)
diff --git a/0000_README b/0000_README
index 04880a09..bda6a465 100644
--- a/0000_README
+++ b/0000_README
@@ -75,6 +75,10 @@ Patch: 1007_linux-6.0.8.patch
From: http://www.kernel.org
Desc: Linux 6.0.8
+Patch: 1008_linux-6.0.9.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.9
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1008_linux-6.0.9.patch b/1008_linux-6.0.9.patch
new file mode 100644
index 00000000..efa04169
--- /dev/null
+++ b/1008_linux-6.0.9.patch
@@ -0,0 +1,6943 @@
+diff --git a/Documentation/devicetree/bindings/net/engleder,tsnep.yaml b/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
+index d0e1476e15b50..ccc42cb470dac 100644
+--- a/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
++++ b/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
+@@ -28,7 +28,7 @@ properties:
+
+ nvmem-cells: true
+
+- nvmem-cells-names: true
++ nvmem-cell-names: true
+
+ phy-connection-type:
+ enum:
+diff --git a/Documentation/virt/kvm/devices/vm.rst b/Documentation/virt/kvm/devices/vm.rst
+index 0aa5b1cfd700c..60acc39e0e937 100644
+--- a/Documentation/virt/kvm/devices/vm.rst
++++ b/Documentation/virt/kvm/devices/vm.rst
+@@ -215,6 +215,7 @@ KVM_S390_VM_TOD_EXT).
+ :Parameters: address of a buffer in user space to store the data (u8) to
+ :Returns: -EFAULT if the given address is not accessible from kernel space;
+ -EINVAL if setting the TOD clock extension to != 0 is not supported
++ -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+
+ 3.2. ATTRIBUTE: KVM_S390_VM_TOD_LOW
+ -----------------------------------
+@@ -224,6 +225,7 @@ the POP (u64).
+
+ :Parameters: address of a buffer in user space to store the data (u64) to
+ :Returns: -EFAULT if the given address is not accessible from kernel space
++ -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+
+ 3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT
+ -----------------------------------
+@@ -237,6 +239,7 @@ it, it is stored as 0 and not allowed to be set to a value != 0.
+ (kvm_s390_vm_tod_clock) to
+ :Returns: -EFAULT if the given address is not accessible from kernel space;
+ -EINVAL if setting the TOD clock extension to != 0 is not supported
++ -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+
+ 4. GROUP: KVM_S390_VM_CRYPTO
+ ============================
+diff --git a/Makefile b/Makefile
+index bcb76d4fdbc11..a234f16783ede 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 8
++SUBLEVEL = 9
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
+index e1be6c429810d..a908a37f03678 100644
+--- a/arch/arm64/kernel/efi.c
++++ b/arch/arm64/kernel/efi.c
+@@ -12,6 +12,14 @@
+
+ #include <asm/efi.h>
+
++static bool region_is_misaligned(const efi_memory_desc_t *md)
++{
++ if (PAGE_SIZE == EFI_PAGE_SIZE)
++ return false;
++ return !PAGE_ALIGNED(md->phys_addr) ||
++ !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT);
++}
++
+ /*
+ * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
+ * executable, everything else can be mapped with the XN bits
+@@ -25,14 +33,22 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md)
+ if (type == EFI_MEMORY_MAPPED_IO)
+ return PROT_DEVICE_nGnRE;
+
+- if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr),
+- "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?"))
++ if (region_is_misaligned(md)) {
++ static bool __initdata code_is_misaligned;
++
+ /*
+- * If the region is not aligned to the page size of the OS, we
+- * can not use strict permissions, since that would also affect
+- * the mapping attributes of the adjacent regions.
++ * Regions that are not aligned to the OS page size cannot be
++ * mapped with strict permissions, as those might interfere
++ * with the permissions that are needed by the adjacent
++ * region's mapping. However, if we haven't encountered any
++ * misaligned runtime code regions so far, we can safely use
++ * non-executable permissions for non-code regions.
+ */
+- return pgprot_val(PAGE_KERNEL_EXEC);
++ code_is_misaligned |= (type == EFI_RUNTIME_SERVICES_CODE);
++
++ return code_is_misaligned ? pgprot_val(PAGE_KERNEL_EXEC)
++ : pgprot_val(PAGE_KERNEL);
++ }
+
+ /* R-- */
+ if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) ==
+@@ -63,19 +79,16 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
+ bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE ||
+ md->type == EFI_RUNTIME_SERVICES_DATA);
+
+- if (!PAGE_ALIGNED(md->phys_addr) ||
+- !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) {
+- /*
+- * If the end address of this region is not aligned to page
+- * size, the mapping is rounded up, and may end up sharing a
+- * page frame with the next UEFI memory region. If we create
+- * a block entry now, we may need to split it again when mapping
+- * the next region, and support for that is going to be removed
+- * from the MMU routines. So avoid block mappings altogether in
+- * that case.
+- */
++ /*
++ * If this region is not aligned to the page size used by the OS, the
++ * mapping will be rounded outwards, and may end up sharing a page
++ * frame with an adjacent runtime memory region. Given that the page
++ * table descriptor covering the shared page will be rewritten when the
++ * adjacent region gets mapped, we must avoid block mappings here so we
++ * don't have to worry about splitting them when that happens.
++ */
++ if (region_is_misaligned(md))
+ page_mappings_only = true;
+- }
+
+ create_pgd_mapping(mm, md->phys_addr, md->virt_addr,
+ md->num_pages << EFI_PAGE_SHIFT,
+@@ -102,6 +115,9 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm,
+ BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
+ md->type != EFI_RUNTIME_SERVICES_DATA);
+
++ if (region_is_misaligned(md))
++ return 0;
++
+ /*
+ * Calling apply_to_page_range() is only safe on regions that are
+ * guaranteed to be mapped down to pages. Since we are only called
+diff --git a/arch/m68k/include/uapi/asm/bootinfo-virt.h b/arch/m68k/include/uapi/asm/bootinfo-virt.h
+index b091ee9b06e05..7dbcd7bec1034 100644
+--- a/arch/m68k/include/uapi/asm/bootinfo-virt.h
++++ b/arch/m68k/include/uapi/asm/bootinfo-virt.h
+@@ -13,13 +13,8 @@
+ #define BI_VIRT_VIRTIO_BASE 0x8004
+ #define BI_VIRT_CTRL_BASE 0x8005
+
+-/*
+- * A random seed used to initialize the RNG. Record format:
+- *
+- * - length [ 2 bytes, 16-bit big endian ]
+- * - seed data [ `length` bytes, padded to preserve 2-byte alignment ]
+- */
+-#define BI_VIRT_RNG_SEED 0x8006
++/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index:
++ * #define BI_VIRT_RNG_SEED 0x8006 */
+
+ #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
+
+diff --git a/arch/m68k/include/uapi/asm/bootinfo.h b/arch/m68k/include/uapi/asm/bootinfo.h
+index 95ecf3ae4c49f..024e87d7095f8 100644
+--- a/arch/m68k/include/uapi/asm/bootinfo.h
++++ b/arch/m68k/include/uapi/asm/bootinfo.h
+@@ -64,6 +64,13 @@ struct mem_info {
+ /* (struct mem_info) */
+ #define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
+ /* (string) */
++/*
++ * A random seed used to initialize the RNG. Record format:
++ *
++ * - length [ 2 bytes, 16-bit big endian ]
++ * - seed data [ `length` bytes, padded to preserve 4-byte struct alignment ]
++ */
++#define BI_RNG_SEED 0x0008
+
+
+ /*
+diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
+index 7e7ef67cff8b2..e45cc99237030 100644
+--- a/arch/m68k/kernel/setup_mm.c
++++ b/arch/m68k/kernel/setup_mm.c
+@@ -25,6 +25,7 @@
+ #include <linux/module.h>
+ #include <linux/nvram.h>
+ #include <linux/initrd.h>
++#include <linux/random.h>
+
+ #include <asm/bootinfo.h>
+ #include <asm/byteorder.h>
+@@ -151,6 +152,17 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ sizeof(m68k_command_line));
+ break;
+
++ case BI_RNG_SEED: {
++ u16 len = be16_to_cpup(data);
++ add_bootloader_randomness(data + 2, len);
++ /*
++ * Zero the data to preserve forward secrecy, and zero the
++ * length to prevent kexec from using it.
++ */
++ memzero_explicit((void *)data, len + 2);
++ break;
++ }
++
+ default:
+ if (MACH_IS_AMIGA)
+ unknown = amiga_parse_bootinfo(record);
+diff --git a/arch/m68k/virt/config.c b/arch/m68k/virt/config.c
+index 4ab22946ff68f..632ba200ad425 100644
+--- a/arch/m68k/virt/config.c
++++ b/arch/m68k/virt/config.c
+@@ -2,7 +2,6 @@
+
+ #include <linux/reboot.h>
+ #include <linux/serial_core.h>
+-#include <linux/random.h>
+ #include <clocksource/timer-goldfish.h>
+
+ #include <asm/bootinfo.h>
+@@ -93,16 +92,6 @@ int __init virt_parse_bootinfo(const struct bi_record *record)
+ data += 4;
+ virt_bi_data.virtio.irq = be32_to_cpup(data);
+ break;
+- case BI_VIRT_RNG_SEED: {
+- u16 len = be16_to_cpup(data);
+- add_bootloader_randomness(data + 2, len);
+- /*
+- * Zero the data to preserve forward secrecy, and zero the
+- * length to prevent kexec from using it.
+- */
+- memzero_explicit((void *)data, len + 2);
+- break;
+- }
+ default:
+ unknown = 1;
+ break;
+diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
+index 71a882c8c6eb1..f7978d50a2ba5 100644
+--- a/arch/mips/kernel/jump_label.c
++++ b/arch/mips/kernel/jump_label.c
+@@ -56,7 +56,7 @@ void arch_jump_label_transform(struct jump_entry *e,
+ * The branch offset must fit in the instruction's 26
+ * bit field.
+ */
+- WARN_ON((offset >= BIT(25)) ||
++ WARN_ON((offset >= (long)BIT(25)) ||
+ (offset < -(long)BIT(25)));
+
+ insn.j_format.opcode = bc6_op;
+diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
+index ceb9ebab6558c..52002d54b1637 100644
+--- a/arch/riscv/kernel/process.c
++++ b/arch/riscv/kernel/process.c
+@@ -164,6 +164,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ unsigned long tls = args->tls;
+ struct pt_regs *childregs = task_pt_regs(p);
+
++ memset(&p->thread.s, 0, sizeof(p->thread.s));
++
+ /* p->thread holds context to be restored by __switch_to() */
+ if (unlikely(args->fn)) {
+ /* Kernel thread */
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index ad76bb59b0590..67ec1fadcfe24 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -283,6 +283,7 @@ void __init setup_arch(char **cmdline_p)
+ else
+ pr_err("No DTB found in kernel mappings\n");
+ #endif
++ early_init_fdt_scan_reserved_mem();
+ misc_mem_init();
+
+ init_resources();
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index f2e065671e4d5..84ac0fe612e79 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -30,7 +30,7 @@ obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+ # Disable -pg to prevent insert call site
+-CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
++CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+
+ # Disable profiling and instrumentation for VDSO code
+ GCOV_PROFILE := n
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index b56a0a75533fe..50a1b6edd4918 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -262,7 +262,6 @@ static void __init setup_bootmem(void)
+ memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
+ }
+
+- early_init_fdt_scan_reserved_mem();
+ dma_contiguous_reserve(dma32_phys_limit);
+ if (IS_ENABLED(CONFIG_64BIT))
+ hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index b7ef0b71014df..2486281027c02 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -1207,6 +1207,8 @@ static int kvm_s390_vm_get_migration(struct kvm *kvm,
+ return 0;
+ }
+
++static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
++
+ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr)
+ {
+ struct kvm_s390_vm_tod_clock gtod;
+@@ -1216,7 +1218,7 @@ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr)
+
+ if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx)
+ return -EINVAL;
+- kvm_s390_set_tod_clock(kvm, >od);
++ __kvm_s390_set_tod_clock(kvm, >od);
+
+ VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx",
+ gtod.epoch_idx, gtod.tod);
+@@ -1247,7 +1249,7 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
+ sizeof(gtod.tod)))
+ return -EFAULT;
+
+- kvm_s390_set_tod_clock(kvm, >od);
++ __kvm_s390_set_tod_clock(kvm, >od);
+ VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod);
+ return 0;
+ }
+@@ -1259,6 +1261,16 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr)
+ if (attr->flags)
+ return -EINVAL;
+
++ mutex_lock(&kvm->lock);
++ /*
++ * For protected guests, the TOD is managed by the ultravisor, so trying
++ * to change it will never bring the expected results.
++ */
++ if (kvm_s390_pv_is_protected(kvm)) {
++ ret = -EOPNOTSUPP;
++ goto out_unlock;
++ }
++
+ switch (attr->attr) {
+ case KVM_S390_VM_TOD_EXT:
+ ret = kvm_s390_set_tod_ext(kvm, attr);
+@@ -1273,6 +1285,9 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr)
+ ret = -ENXIO;
+ break;
+ }
++
++out_unlock:
++ mutex_unlock(&kvm->lock);
+ return ret;
+ }
+
+@@ -4379,13 +4394,6 @@ static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_t
+ preempt_enable();
+ }
+
+-void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+-{
+- mutex_lock(&kvm->lock);
+- __kvm_s390_set_tod_clock(kvm, gtod);
+- mutex_unlock(&kvm->lock);
+-}
+-
+ int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+ {
+ if (!mutex_trylock(&kvm->lock))
+diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
+index f6fd668f887e8..4755492dfabc6 100644
+--- a/arch/s390/kvm/kvm-s390.h
++++ b/arch/s390/kvm/kvm-s390.h
+@@ -363,7 +363,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
+ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
+
+ /* implemented in kvm-s390.c */
+-void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
+ int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
+ long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
+ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
+diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c
+index c50c1645c0aec..ded1af2ddae99 100644
+--- a/arch/s390/kvm/pci.c
++++ b/arch/s390/kvm/pci.c
+@@ -126,7 +126,7 @@ int kvm_s390_pci_aen_init(u8 nisc)
+ return -EPERM;
+
+ mutex_lock(&aift->aift_lock);
+- aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev),
++ aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev *),
+ GFP_KERNEL);
+ if (!aift->kzdev) {
+ rc = -ENOMEM;
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 1e086b37a3071..28e8e678c8357 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -535,6 +535,11 @@
+ #define MSR_AMD64_CPUID_FN_1 0xc0011004
+ #define MSR_AMD64_LS_CFG 0xc0011020
+ #define MSR_AMD64_DC_CFG 0xc0011022
++
++#define MSR_AMD64_DE_CFG 0xc0011029
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT)
++
+ #define MSR_AMD64_BU_CFG2 0xc001102a
+ #define MSR_AMD64_IBSFETCHCTL 0xc0011030
+ #define MSR_AMD64_IBSFETCHLINAD 0xc0011031
+@@ -637,9 +642,6 @@
+ #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL
+ #define FAM10H_MMIO_CONF_BASE_SHIFT 20
+ #define MSR_FAM10H_NODE_ID 0xc001100c
+-#define MSR_F10H_DECFG 0xc0011029
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
+
+ /* K8 MSRs */
+ #define MSR_K8_TOP_MEM1 0xc001001a
+diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
+index cb50589a7102f..437308004ef2e 100644
+--- a/arch/x86/kernel/asm-offsets.c
++++ b/arch/x86/kernel/asm-offsets.c
+@@ -19,7 +19,6 @@
+ #include <asm/suspend.h>
+ #include <asm/tlbflush.h>
+ #include <asm/tdx.h>
+-#include "../kvm/vmx/vmx.h"
+
+ #ifdef CONFIG_XEN
+ #include <xen/interface/xen.h>
+@@ -108,9 +107,4 @@ static void __used common(void)
+ OFFSET(TSS_sp0, tss_struct, x86_tss.sp0);
+ OFFSET(TSS_sp1, tss_struct, x86_tss.sp1);
+ OFFSET(TSS_sp2, tss_struct, x86_tss.sp2);
+-
+- if (IS_ENABLED(CONFIG_KVM_INTEL)) {
+- BLANK();
+- OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl);
+- }
+ }
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 48276c0e479d8..500b1f9862b13 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -770,8 +770,6 @@ static void init_amd_gh(struct cpuinfo_x86 *c)
+ set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
+ }
+
+-#define MSR_AMD64_DE_CFG 0xC0011029
+-
+ static void init_amd_ln(struct cpuinfo_x86 *c)
+ {
+ /*
+@@ -965,8 +963,8 @@ static void init_amd(struct cpuinfo_x86 *c)
+ * msr_set_bit() uses the safe accessors, too, even if the MSR
+ * is not present.
+ */
+- msr_set_bit(MSR_F10H_DECFG,
+- MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
++ msr_set_bit(MSR_AMD64_DE_CFG,
++ MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
+
+ /* A serializing LFENCE stops RDTSC speculation */
+ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
+index 21fd425088fe5..c393b8773ace6 100644
+--- a/arch/x86/kernel/cpu/hygon.c
++++ b/arch/x86/kernel/cpu/hygon.c
+@@ -326,8 +326,8 @@ static void init_hygon(struct cpuinfo_x86 *c)
+ * msr_set_bit() uses the safe accessors, too, even if the MSR
+ * is not present.
+ */
+- msr_set_bit(MSR_F10H_DECFG,
+- MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
++ msr_set_bit(MSR_AMD64_DE_CFG,
++ MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
+
+ /* A serializing LFENCE stops RDTSC speculation */
+ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+diff --git a/arch/x86/kvm/.gitignore b/arch/x86/kvm/.gitignore
+new file mode 100644
+index 0000000000000..615d6ff35c009
+--- /dev/null
++++ b/arch/x86/kvm/.gitignore
+@@ -0,0 +1,2 @@
++/kvm-asm-offsets.s
++/kvm-asm-offsets.h
+diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
+index 30f244b645234..f453a0f96e243 100644
+--- a/arch/x86/kvm/Makefile
++++ b/arch/x86/kvm/Makefile
+@@ -34,3 +34,15 @@ endif
+ obj-$(CONFIG_KVM) += kvm.o
+ obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
+ obj-$(CONFIG_KVM_AMD) += kvm-amd.o
++
++AFLAGS_svm/vmenter.o := -iquote $(obj)
++$(obj)/svm/vmenter.o: $(obj)/kvm-asm-offsets.h
++
++AFLAGS_vmx/vmenter.o := -iquote $(obj)
++$(obj)/vmx/vmenter.o: $(obj)/kvm-asm-offsets.h
++
++$(obj)/kvm-asm-offsets.h: $(obj)/kvm-asm-offsets.s FORCE
++ $(call filechk,offsets,__KVM_ASM_OFFSETS_H__)
++
++targets += kvm-asm-offsets.s
++clean-files += kvm-asm-offsets.h
+diff --git a/arch/x86/kvm/kvm-asm-offsets.c b/arch/x86/kvm/kvm-asm-offsets.c
+new file mode 100644
+index 0000000000000..f83e88b85bf21
+--- /dev/null
++++ b/arch/x86/kvm/kvm-asm-offsets.c
+@@ -0,0 +1,27 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Generate definitions needed by assembly language modules.
++ * This code generates raw asm output which is post-processed to extract
++ * and format the required data.
++ */
++#define COMPILE_OFFSETS
++
++#include <linux/kbuild.h>
++#include "vmx/vmx.h"
++#include "svm/svm.h"
++
++static void __used common(void)
++{
++ if (IS_ENABLED(CONFIG_KVM_AMD)) {
++ BLANK();
++ OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs);
++ OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb);
++ OFFSET(SVM_vmcb01, vcpu_svm, vmcb01);
++ OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa);
++ }
++
++ if (IS_ENABLED(CONFIG_KVM_INTEL)) {
++ BLANK();
++ OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl);
++ }
++}
+diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
+index 3552e6af36844..83e30e4db2ae0 100644
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -6044,7 +6044,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
+
+ write_lock(&kvm->mmu_lock);
+
+- kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end);
++ kvm_mmu_invalidate_begin(kvm, 0, -1ul);
+
+ flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
+
+@@ -6058,7 +6058,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
+ kvm_flush_remote_tlbs_with_address(kvm, gfn_start,
+ gfn_end - gfn_start);
+
+- kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end);
++ kvm_mmu_invalidate_end(kvm, 0, -1ul);
+
+ write_unlock(&kvm->mmu_lock);
+ }
+diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
+index 28064060413ac..c9c9bd453a97d 100644
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -605,7 +605,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
+ save->dr6 = svm->vcpu.arch.dr6;
+
+ pr_debug("Virtual Machine Save Area (VMSA):\n");
+- print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false);
++ print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false);
+
+ return 0;
+ }
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index f3813dbacb9f1..454746641a483 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -2711,9 +2711,9 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr)
+ msr->data = 0;
+
+ switch (msr->index) {
+- case MSR_F10H_DECFG:
+- if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
+- msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
++ case MSR_AMD64_DE_CFG:
++ if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC))
++ msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE;
+ break;
+ case MSR_IA32_PERF_CAPABILITIES:
+ return 0;
+@@ -2814,7 +2814,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ msr_info->data = 0x1E;
+ }
+ break;
+- case MSR_F10H_DECFG:
++ case MSR_AMD64_DE_CFG:
+ msr_info->data = svm->msr_decfg;
+ break;
+ default:
+@@ -3043,7 +3043,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ case MSR_VM_IGNNE:
+ vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
+ break;
+- case MSR_F10H_DECFG: {
++ case MSR_AMD64_DE_CFG: {
+ struct kvm_msr_entry msr_entry;
+
+ msr_entry.index = msr->index;
+@@ -3915,25 +3915,15 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
+ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+- unsigned long vmcb_pa = svm->current_vmcb->pa;
+
+ guest_state_enter_irqoff();
+
+ if (sev_es_guest(vcpu->kvm)) {
+- __svm_sev_es_vcpu_run(vmcb_pa);
++ __svm_sev_es_vcpu_run(svm);
+ } else {
+ struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+
+- /*
+- * Use a single vmcb (vmcb01 because it's always valid) for
+- * context switching guest state via VMLOAD/VMSAVE, that way
+- * the state doesn't need to be copied between vmcb01 and
+- * vmcb02 when switching vmcbs for nested virtualization.
+- */
+- vmload(svm->vmcb01.pa);
+- __svm_vcpu_run(vmcb_pa, (unsigned long *)&vcpu->arch.regs);
+- vmsave(svm->vmcb01.pa);
+-
++ __svm_vcpu_run(svm);
+ vmload(__sme_page_pa(sd->save_area));
+ }
+
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index 6a7686bf69000..7ff1879e73c56 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -683,7 +683,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm);
+
+ /* vmenter.S */
+
+-void __svm_sev_es_vcpu_run(unsigned long vmcb_pa);
+-void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs);
++void __svm_sev_es_vcpu_run(struct vcpu_svm *svm);
++void __svm_vcpu_run(struct vcpu_svm *svm);
+
+ #endif
+diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
+index 723f8534986c3..5bc2ed7d79c07 100644
+--- a/arch/x86/kvm/svm/vmenter.S
++++ b/arch/x86/kvm/svm/vmenter.S
+@@ -4,35 +4,37 @@
+ #include <asm/bitsperlong.h>
+ #include <asm/kvm_vcpu_regs.h>
+ #include <asm/nospec-branch.h>
++#include "kvm-asm-offsets.h"
+
+ #define WORD_SIZE (BITS_PER_LONG / 8)
+
+ /* Intentionally omit RAX as it's context switched by hardware */
+-#define VCPU_RCX __VCPU_REGS_RCX * WORD_SIZE
+-#define VCPU_RDX __VCPU_REGS_RDX * WORD_SIZE
+-#define VCPU_RBX __VCPU_REGS_RBX * WORD_SIZE
++#define VCPU_RCX (SVM_vcpu_arch_regs + __VCPU_REGS_RCX * WORD_SIZE)
++#define VCPU_RDX (SVM_vcpu_arch_regs + __VCPU_REGS_RDX * WORD_SIZE)
++#define VCPU_RBX (SVM_vcpu_arch_regs + __VCPU_REGS_RBX * WORD_SIZE)
+ /* Intentionally omit RSP as it's context switched by hardware */
+-#define VCPU_RBP __VCPU_REGS_RBP * WORD_SIZE
+-#define VCPU_RSI __VCPU_REGS_RSI * WORD_SIZE
+-#define VCPU_RDI __VCPU_REGS_RDI * WORD_SIZE
++#define VCPU_RBP (SVM_vcpu_arch_regs + __VCPU_REGS_RBP * WORD_SIZE)
++#define VCPU_RSI (SVM_vcpu_arch_regs + __VCPU_REGS_RSI * WORD_SIZE)
++#define VCPU_RDI (SVM_vcpu_arch_regs + __VCPU_REGS_RDI * WORD_SIZE)
+
+ #ifdef CONFIG_X86_64
+-#define VCPU_R8 __VCPU_REGS_R8 * WORD_SIZE
+-#define VCPU_R9 __VCPU_REGS_R9 * WORD_SIZE
+-#define VCPU_R10 __VCPU_REGS_R10 * WORD_SIZE
+-#define VCPU_R11 __VCPU_REGS_R11 * WORD_SIZE
+-#define VCPU_R12 __VCPU_REGS_R12 * WORD_SIZE
+-#define VCPU_R13 __VCPU_REGS_R13 * WORD_SIZE
+-#define VCPU_R14 __VCPU_REGS_R14 * WORD_SIZE
+-#define VCPU_R15 __VCPU_REGS_R15 * WORD_SIZE
++#define VCPU_R8 (SVM_vcpu_arch_regs + __VCPU_REGS_R8 * WORD_SIZE)
++#define VCPU_R9 (SVM_vcpu_arch_regs + __VCPU_REGS_R9 * WORD_SIZE)
++#define VCPU_R10 (SVM_vcpu_arch_regs + __VCPU_REGS_R10 * WORD_SIZE)
++#define VCPU_R11 (SVM_vcpu_arch_regs + __VCPU_REGS_R11 * WORD_SIZE)
++#define VCPU_R12 (SVM_vcpu_arch_regs + __VCPU_REGS_R12 * WORD_SIZE)
++#define VCPU_R13 (SVM_vcpu_arch_regs + __VCPU_REGS_R13 * WORD_SIZE)
++#define VCPU_R14 (SVM_vcpu_arch_regs + __VCPU_REGS_R14 * WORD_SIZE)
++#define VCPU_R15 (SVM_vcpu_arch_regs + __VCPU_REGS_R15 * WORD_SIZE)
+ #endif
+
++#define SVM_vmcb01_pa (SVM_vmcb01 + KVM_VMCB_pa)
++
+ .section .noinstr.text, "ax"
+
+ /**
+ * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
+- * @vmcb_pa: unsigned long
+- * @regs: unsigned long * (to guest registers)
++ * @svm: struct vcpu_svm *
+ */
+ SYM_FUNC_START(__svm_vcpu_run)
+ push %_ASM_BP
+@@ -47,49 +49,54 @@ SYM_FUNC_START(__svm_vcpu_run)
+ #endif
+ push %_ASM_BX
+
+- /* Save @regs. */
+- push %_ASM_ARG2
+-
+- /* Save @vmcb. */
++ /* Save @svm. */
+ push %_ASM_ARG1
+
+- /* Move @regs to RAX. */
+- mov %_ASM_ARG2, %_ASM_AX
++.ifnc _ASM_ARG1, _ASM_DI
++ /* Move @svm to RDI. */
++ mov %_ASM_ARG1, %_ASM_DI
++.endif
++
++ /*
++ * Use a single vmcb (vmcb01 because it's always valid) for
++ * context switching guest state via VMLOAD/VMSAVE, that way
++ * the state doesn't need to be copied between vmcb01 and
++ * vmcb02 when switching vmcbs for nested virtualization.
++ */
++ mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
++1: vmload %_ASM_AX
++2:
++
++ /* Get svm->current_vmcb->pa into RAX. */
++ mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX
++ mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+
+ /* Load guest registers. */
+- mov VCPU_RCX(%_ASM_AX), %_ASM_CX
+- mov VCPU_RDX(%_ASM_AX), %_ASM_DX
+- mov VCPU_RBX(%_ASM_AX), %_ASM_BX
+- mov VCPU_RBP(%_ASM_AX), %_ASM_BP
+- mov VCPU_RSI(%_ASM_AX), %_ASM_SI
+- mov VCPU_RDI(%_ASM_AX), %_ASM_DI
++ mov VCPU_RCX(%_ASM_DI), %_ASM_CX
++ mov VCPU_RDX(%_ASM_DI), %_ASM_DX
++ mov VCPU_RBX(%_ASM_DI), %_ASM_BX
++ mov VCPU_RBP(%_ASM_DI), %_ASM_BP
++ mov VCPU_RSI(%_ASM_DI), %_ASM_SI
+ #ifdef CONFIG_X86_64
+- mov VCPU_R8 (%_ASM_AX), %r8
+- mov VCPU_R9 (%_ASM_AX), %r9
+- mov VCPU_R10(%_ASM_AX), %r10
+- mov VCPU_R11(%_ASM_AX), %r11
+- mov VCPU_R12(%_ASM_AX), %r12
+- mov VCPU_R13(%_ASM_AX), %r13
+- mov VCPU_R14(%_ASM_AX), %r14
+- mov VCPU_R15(%_ASM_AX), %r15
++ mov VCPU_R8 (%_ASM_DI), %r8
++ mov VCPU_R9 (%_ASM_DI), %r9
++ mov VCPU_R10(%_ASM_DI), %r10
++ mov VCPU_R11(%_ASM_DI), %r11
++ mov VCPU_R12(%_ASM_DI), %r12
++ mov VCPU_R13(%_ASM_DI), %r13
++ mov VCPU_R14(%_ASM_DI), %r14
++ mov VCPU_R15(%_ASM_DI), %r15
+ #endif
+-
+- /* "POP" @vmcb to RAX. */
+- pop %_ASM_AX
++ mov VCPU_RDI(%_ASM_DI), %_ASM_DI
+
+ /* Enter guest mode */
+ sti
+
+-1: vmrun %_ASM_AX
+-
+-2: cli
++3: vmrun %_ASM_AX
++4:
++ cli
+
+-#ifdef CONFIG_RETPOLINE
+- /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+- FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+-#endif
+-
+- /* "POP" @regs to RAX. */
++ /* Pop @svm to RAX while it's the only available register. */
+ pop %_ASM_AX
+
+ /* Save all guest registers. */
+@@ -110,6 +117,18 @@ SYM_FUNC_START(__svm_vcpu_run)
+ mov %r15, VCPU_R15(%_ASM_AX)
+ #endif
+
++ /* @svm can stay in RDI from now on. */
++ mov %_ASM_AX, %_ASM_DI
++
++ mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
++5: vmsave %_ASM_AX
++6:
++
++#ifdef CONFIG_RETPOLINE
++ /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
++ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
++#endif
++
+ /*
+ * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ * untrained as soon as we exit the VM and are back to the
+@@ -159,17 +178,25 @@ SYM_FUNC_START(__svm_vcpu_run)
+ pop %_ASM_BP
+ RET
+
+-3: cmpb $0, kvm_rebooting
++10: cmpb $0, kvm_rebooting
+ jne 2b
+ ud2
++30: cmpb $0, kvm_rebooting
++ jne 4b
++ ud2
++50: cmpb $0, kvm_rebooting
++ jne 6b
++ ud2
+
+- _ASM_EXTABLE(1b, 3b)
++ _ASM_EXTABLE(1b, 10b)
++ _ASM_EXTABLE(3b, 30b)
++ _ASM_EXTABLE(5b, 50b)
+
+ SYM_FUNC_END(__svm_vcpu_run)
+
+ /**
+ * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
+- * @vmcb_pa: unsigned long
++ * @svm: struct vcpu_svm *
+ */
+ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ push %_ASM_BP
+@@ -184,8 +211,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ #endif
+ push %_ASM_BX
+
+- /* Move @vmcb to RAX. */
+- mov %_ASM_ARG1, %_ASM_AX
++ /* Get svm->current_vmcb->pa into RAX. */
++ mov SVM_current_vmcb(%_ASM_ARG1), %_ASM_AX
++ mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+
+ /* Enter guest mode */
+ sti
+diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S
+index 6de96b9438044..660165065dfe8 100644
+--- a/arch/x86/kvm/vmx/vmenter.S
++++ b/arch/x86/kvm/vmx/vmenter.S
+@@ -1,12 +1,12 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ #include <linux/linkage.h>
+ #include <asm/asm.h>
+-#include <asm/asm-offsets.h>
+ #include <asm/bitsperlong.h>
+ #include <asm/kvm_vcpu_regs.h>
+ #include <asm/nospec-branch.h>
+ #include <asm/percpu.h>
+ #include <asm/segment.h>
++#include "kvm-asm-offsets.h"
+ #include "run_flags.h"
+
+ #define WORD_SIZE (BITS_PER_LONG / 8)
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 05f4424eb0c52..71cbafd67319b 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1431,20 +1431,10 @@ static const u32 msrs_to_save_all[] = {
+ MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3,
+ MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5,
+ MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7,
+- MSR_ARCH_PERFMON_PERFCTR0 + 8, MSR_ARCH_PERFMON_PERFCTR0 + 9,
+- MSR_ARCH_PERFMON_PERFCTR0 + 10, MSR_ARCH_PERFMON_PERFCTR0 + 11,
+- MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13,
+- MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15,
+- MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17,
+ MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1,
+ MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
+ MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
+ MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7,
+- MSR_ARCH_PERFMON_EVENTSEL0 + 8, MSR_ARCH_PERFMON_EVENTSEL0 + 9,
+- MSR_ARCH_PERFMON_EVENTSEL0 + 10, MSR_ARCH_PERFMON_EVENTSEL0 + 11,
+- MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13,
+- MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15,
+- MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17,
+ MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
+
+ MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3,
+@@ -1551,7 +1541,7 @@ static const u32 msr_based_features_all[] = {
+ MSR_IA32_VMX_EPT_VPID_CAP,
+ MSR_IA32_VMX_VMFUNC,
+
+- MSR_F10H_DECFG,
++ MSR_AMD64_DE_CFG,
+ MSR_IA32_UCODE_REV,
+ MSR_IA32_ARCH_CAPABILITIES,
+ MSR_IA32_PERF_CAPABILITIES,
+@@ -7005,12 +6995,12 @@ static void kvm_init_msr_list(void)
+ intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
+ continue;
+ break;
+- case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17:
++ case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 7:
+ if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
+ min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
+ continue;
+ break;
+- case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17:
++ case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 7:
+ if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
+ min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
+ continue;
+diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
+index 6b3033845c6d3..5804bbae4f012 100644
+--- a/arch/x86/mm/hugetlbpage.c
++++ b/arch/x86/mm/hugetlbpage.c
+@@ -37,8 +37,12 @@ int pmd_huge(pmd_t pmd)
+ */
+ int pud_huge(pud_t pud)
+ {
++#if CONFIG_PGTABLE_LEVELS > 2
+ return !pud_none(pud) &&
+ (pud_val(pud) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
++#else
++ return 0;
++#endif
+ }
+
+ #ifdef CONFIG_HUGETLB_PAGE
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index bb176c72891c9..4cd39f304e206 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -519,6 +519,7 @@ static void pm_save_spec_msr(void)
+ MSR_TSX_FORCE_ABORT,
+ MSR_IA32_MCU_OPT_CTRL,
+ MSR_AMD64_LS_CFG,
++ MSR_AMD64_DE_CFG,
+ };
+
+ msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index ff9602a0e54ef..b0e442a75690a 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -3266,6 +3266,7 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
+ case REPORT_LUNS:
+ case REQUEST_SENSE:
+ case SYNCHRONIZE_CACHE:
++ case SYNCHRONIZE_CACHE_16:
+ case REZERO_UNIT:
+ case SEEK_6:
+ case SEEK_10:
+@@ -3924,6 +3925,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
+ return ata_scsi_write_same_xlat;
+
+ case SYNCHRONIZE_CACHE:
++ case SYNCHRONIZE_CACHE_16:
+ if (ata_try_flush_cache(dev))
+ return ata_scsi_flush_xlat;
+ break;
+@@ -4147,6 +4149,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
+ * turning this into a no-op.
+ */
+ case SYNCHRONIZE_CACHE:
++ case SYNCHRONIZE_CACHE_16:
+ fallthrough;
+
+ /* no-op's, complete with success */
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 6b7fb955a05ac..78344e4d4215b 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1533,9 +1533,24 @@ static const struct attribute_group *region_groups[] = {
+
+ static void cxl_region_release(struct device *dev)
+ {
++ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
+ struct cxl_region *cxlr = to_cxl_region(dev);
++ int id = atomic_read(&cxlrd->region_id);
++
++ /*
++ * Try to reuse the recently idled id rather than the cached
++ * next id to prevent the region id space from increasing
++ * unnecessarily.
++ */
++ if (cxlr->id < id)
++ if (atomic_try_cmpxchg(&cxlrd->region_id, &id, cxlr->id)) {
++ memregion_free(id);
++ goto out;
++ }
+
+ memregion_free(cxlr->id);
++out:
++ put_device(dev->parent);
+ kfree(cxlr);
+ }
+
+@@ -1597,6 +1612,11 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i
+ device_initialize(dev);
+ lockdep_set_class(&dev->mutex, &cxl_region_key);
+ dev->parent = &cxlrd->cxlsd.cxld.dev;
++ /*
++ * Keep root decoder pinned through cxl_region_release to fixup
++ * region id allocations
++ */
++ get_device(dev->parent);
+ device_set_pm_not_required(dev);
+ dev->bus = &cxl_bus_type;
+ dev->type = &cxl_region_type;
+diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
+index d1f74a3aa999d..6780761a16403 100644
+--- a/drivers/dma/apple-admac.c
++++ b/drivers/dma/apple-admac.c
+@@ -490,7 +490,7 @@ static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec,
+ return NULL;
+ }
+
+- return &ad->channels[index].chan;
++ return dma_get_slave_channel(&ad->channels[index].chan);
+ }
+
+ static int admac_drain_reports(struct admac_data *ad, int channo)
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+index 5a50423b7378e..858bd64f13135 100644
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -256,6 +256,8 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
+ ATC_SPIP_BOUNDARY(first->boundary));
+ channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) |
+ ATC_DPIP_BOUNDARY(first->boundary));
++ /* Don't allow CPU to reorder channel enable. */
++ wmb();
+ dma_writel(atdma, CHER, atchan->mask);
+
+ vdbg_dump_regs(atchan);
+@@ -316,7 +318,8 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ struct at_desc *desc_first = atc_first_active(atchan);
+ struct at_desc *desc;
+ int ret;
+- u32 ctrla, dscr, trials;
++ u32 ctrla, dscr;
++ unsigned int i;
+
+ /*
+ * If the cookie doesn't match to the currently running transfer then
+@@ -386,7 +389,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ dscr = channel_readl(atchan, DSCR);
+ rmb(); /* ensure DSCR is read before CTRLA */
+ ctrla = channel_readl(atchan, CTRLA);
+- for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) {
++ for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) {
+ u32 new_dscr;
+
+ rmb(); /* ensure DSCR is read after CTRLA */
+@@ -412,7 +415,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ rmb(); /* ensure DSCR is read before CTRLA */
+ ctrla = channel_readl(atchan, CTRLA);
+ }
+- if (unlikely(trials >= ATC_MAX_DSCR_TRIALS))
++ if (unlikely(i == ATC_MAX_DSCR_TRIALS))
+ return -ETIMEDOUT;
+
+ /* for the first descriptor we can be more accurate */
+@@ -462,18 +465,6 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
+ if (!atc_chan_is_cyclic(atchan))
+ dma_cookie_complete(txd);
+
+- /* If the transfer was a memset, free our temporary buffer */
+- if (desc->memset_buffer) {
+- dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
+- desc->memset_paddr);
+- desc->memset_buffer = false;
+- }
+-
+- /* move children to free_list */
+- list_splice_init(&desc->tx_list, &atchan->free_list);
+- /* move myself to free_list */
+- list_move(&desc->desc_node, &atchan->free_list);
+-
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
+ dma_descriptor_unmap(txd);
+@@ -483,42 +474,20 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
+ dmaengine_desc_get_callback_invoke(txd, NULL);
+
+ dma_run_dependencies(txd);
+-}
+-
+-/**
+- * atc_complete_all - finish work for all transactions
+- * @atchan: channel to complete transactions for
+- *
+- * Eventually submit queued descriptors if any
+- *
+- * Assume channel is idle while calling this function
+- * Called with atchan->lock held and bh disabled
+- */
+-static void atc_complete_all(struct at_dma_chan *atchan)
+-{
+- struct at_desc *desc, *_desc;
+- LIST_HEAD(list);
+- unsigned long flags;
+-
+- dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
+
+ spin_lock_irqsave(&atchan->lock, flags);
+-
+- /*
+- * Submit queued descriptors ASAP, i.e. before we go through
+- * the completed ones.
+- */
+- if (!list_empty(&atchan->queue))
+- atc_dostart(atchan, atc_first_queued(atchan));
+- /* empty active_list now it is completed */
+- list_splice_init(&atchan->active_list, &list);
+- /* empty queue list by moving descriptors (if any) to active_list */
+- list_splice_init(&atchan->queue, &atchan->active_list);
+-
++ /* move children to free_list */
++ list_splice_init(&desc->tx_list, &atchan->free_list);
++ /* add myself to free_list */
++ list_add(&desc->desc_node, &atchan->free_list);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
+- list_for_each_entry_safe(desc, _desc, &list, desc_node)
+- atc_chain_complete(atchan, desc);
++ /* If the transfer was a memset, free our temporary buffer */
++ if (desc->memset_buffer) {
++ dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
++ desc->memset_paddr);
++ desc->memset_buffer = false;
++ }
+ }
+
+ /**
+@@ -527,26 +496,28 @@ static void atc_complete_all(struct at_dma_chan *atchan)
+ */
+ static void atc_advance_work(struct at_dma_chan *atchan)
+ {
++ struct at_desc *desc;
+ unsigned long flags;
+- int ret;
+
+ dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
+
+ spin_lock_irqsave(&atchan->lock, flags);
+- ret = atc_chan_is_enabled(atchan);
+- spin_unlock_irqrestore(&atchan->lock, flags);
+- if (ret)
+- return;
+-
+- if (list_empty(&atchan->active_list) ||
+- list_is_singular(&atchan->active_list))
+- return atc_complete_all(atchan);
++ if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list))
++ return spin_unlock_irqrestore(&atchan->lock, flags);
+
+- atc_chain_complete(atchan, atc_first_active(atchan));
++ desc = atc_first_active(atchan);
++ /* Remove the transfer node from the active list. */
++ list_del_init(&desc->desc_node);
++ spin_unlock_irqrestore(&atchan->lock, flags);
++ atc_chain_complete(atchan, desc);
+
+ /* advance work */
+ spin_lock_irqsave(&atchan->lock, flags);
+- atc_dostart(atchan, atc_first_active(atchan));
++ if (!list_empty(&atchan->active_list)) {
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ }
+ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
+@@ -558,6 +529,7 @@ static void atc_advance_work(struct at_dma_chan *atchan)
+ static void atc_handle_error(struct at_dma_chan *atchan)
+ {
+ struct at_desc *bad_desc;
++ struct at_desc *desc;
+ struct at_desc *child;
+ unsigned long flags;
+
+@@ -570,13 +542,12 @@ static void atc_handle_error(struct at_dma_chan *atchan)
+ bad_desc = atc_first_active(atchan);
+ list_del_init(&bad_desc->desc_node);
+
+- /* As we are stopped, take advantage to push queued descriptors
+- * in active_list */
+- list_splice_init(&atchan->queue, atchan->active_list.prev);
+-
+ /* Try to restart the controller */
+- if (!list_empty(&atchan->active_list))
+- atc_dostart(atchan, atc_first_active(atchan));
++ if (!list_empty(&atchan->active_list)) {
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ }
+
+ /*
+ * KERN_CRITICAL may seem harsh, but since this only happens
+@@ -691,19 +662,11 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
+ spin_lock_irqsave(&atchan->lock, flags);
+ cookie = dma_cookie_assign(tx);
+
+- if (list_empty(&atchan->active_list)) {
+- dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
+- desc->txd.cookie);
+- atc_dostart(atchan, desc);
+- list_add_tail(&desc->desc_node, &atchan->active_list);
+- } else {
+- dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
+- desc->txd.cookie);
+- list_add_tail(&desc->desc_node, &atchan->queue);
+- }
+-
++ list_add_tail(&desc->desc_node, &atchan->queue);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
++ dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
++ desc->txd.cookie);
+ return cookie;
+ }
+
+@@ -1445,11 +1408,8 @@ static int atc_terminate_all(struct dma_chan *chan)
+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
+ struct at_dma *atdma = to_at_dma(chan->device);
+ int chan_id = atchan->chan_common.chan_id;
+- struct at_desc *desc, *_desc;
+ unsigned long flags;
+
+- LIST_HEAD(list);
+-
+ dev_vdbg(chan2dev(chan), "%s\n", __func__);
+
+ /*
+@@ -1468,19 +1428,15 @@ static int atc_terminate_all(struct dma_chan *chan)
+ cpu_relax();
+
+ /* active_list entries will end up before queued entries */
+- list_splice_init(&atchan->queue, &list);
+- list_splice_init(&atchan->active_list, &list);
+-
+- spin_unlock_irqrestore(&atchan->lock, flags);
+-
+- /* Flush all pending and queued descriptors */
+- list_for_each_entry_safe(desc, _desc, &list, desc_node)
+- atc_chain_complete(atchan, desc);
++ list_splice_tail_init(&atchan->queue, &atchan->free_list);
++ list_splice_tail_init(&atchan->active_list, &atchan->free_list);
+
+ clear_bit(ATC_IS_PAUSED, &atchan->status);
+ /* if channel dedicated to cyclic operations, free it */
+ clear_bit(ATC_IS_CYCLIC, &atchan->status);
+
++ spin_unlock_irqrestore(&atchan->lock, flags);
++
+ return 0;
+ }
+
+@@ -1535,20 +1491,26 @@ atc_tx_status(struct dma_chan *chan,
+ }
+
+ /**
+- * atc_issue_pending - try to finish work
++ * atc_issue_pending - takes the first transaction descriptor in the pending
++ * queue and starts the transfer.
+ * @chan: target DMA channel
+ */
+ static void atc_issue_pending(struct dma_chan *chan)
+ {
+- struct at_dma_chan *atchan = to_at_dma_chan(chan);
++ struct at_dma_chan *atchan = to_at_dma_chan(chan);
++ struct at_desc *desc;
++ unsigned long flags;
+
+ dev_vdbg(chan2dev(chan), "issue_pending\n");
+
+- /* Not needed for cyclic transfers */
+- if (atc_chan_is_cyclic(atchan))
+- return;
++ spin_lock_irqsave(&atchan->lock, flags);
++ if (atc_chan_is_enabled(atchan) || list_empty(&atchan->queue))
++ return spin_unlock_irqrestore(&atchan->lock, flags);
+
+- atc_advance_work(atchan);
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
+ /**
+@@ -1966,7 +1928,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
+ dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
+ plat_dat->nr_channels);
+
+- dma_async_device_register(&atdma->dma_common);
++ err = dma_async_device_register(&atdma->dma_common);
++ if (err) {
++ dev_err(&pdev->dev, "Unable to register: %d.\n", err);
++ goto err_dma_async_device_register;
++ }
+
+ /*
+ * Do not return an error if the dmac node is not present in order to
+@@ -1986,6 +1952,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
+
+ err_of_dma_controller_register:
+ dma_async_device_unregister(&atdma->dma_common);
++err_dma_async_device_register:
+ dma_pool_destroy(atdma->memset_pool);
+ err_memset_pool_create:
+ dma_pool_destroy(atdma->dma_desc_pool);
+diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
+index 4d1ebc040031c..d4d382d746078 100644
+--- a/drivers/dma/at_hdmac_regs.h
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -186,13 +186,13 @@
+ /* LLI == Linked List Item; aka DMA buffer descriptor */
+ struct at_lli {
+ /* values that are not changed by hardware */
+- dma_addr_t saddr;
+- dma_addr_t daddr;
++ u32 saddr;
++ u32 daddr;
+ /* value that may get written back: */
+- u32 ctrla;
++ u32 ctrla;
+ /* more values that are not changed by hardware */
+- u32 ctrlb;
+- dma_addr_t dscr; /* chain to next lli */
++ u32 ctrlb;
++ u32 dscr; /* chain to next lli */
+ };
+
+ /**
+diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
+index c2808fd081d65..a9b96b18772f3 100644
+--- a/drivers/dma/idxd/cdev.c
++++ b/drivers/dma/idxd/cdev.c
+@@ -312,6 +312,24 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
+ if (idxd->state != IDXD_DEV_ENABLED)
+ return -ENXIO;
+
++ /*
++ * User type WQ is enabled only when SVA is enabled for two reasons:
++ * - If no IOMMU or IOMMU Passthrough without SVA, userspace
++ * can directly access physical address through the WQ.
++ * - The IDXD cdev driver does not provide any ways to pin
++ * user pages and translate the address from user VA to IOVA or
++ * PA without IOMMU SVA. Therefore the application has no way
++ * to instruct the device to perform DMA function. This makes
++ * the cdev not usable for normal application usage.
++ */
++ if (!device_user_pasid_enabled(idxd)) {
++ idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU;
++ dev_dbg(&idxd->pdev->dev,
++ "User type WQ cannot be enabled without SVA.\n");
++
++ return -EOPNOTSUPP;
++ }
++
+ mutex_lock(&wq->wq_lock);
+ wq->type = IDXD_WQT_USER;
+ rc = drv_enable_wq(wq);
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 5a8cc52c1abfd..bd6e50f795beb 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -388,7 +388,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq)
+ clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
+ memset(wq->name, 0, WQ_NAME_SIZE);
+ wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
+- wq->max_batch_size = WQ_DEFAULT_MAX_BATCH;
++ idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ }
+
+ static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq)
+@@ -724,13 +724,21 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
+
+ void idxd_device_clear_state(struct idxd_device *idxd)
+ {
+- if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
+- return;
++ /* IDXD is always disabled. Other states are cleared only when IDXD is configurable. */
++ if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) {
++ /*
++ * Clearing wq state is protected by wq lock.
++ * So no need to be protected by device lock.
++ */
++ idxd_device_wqs_clear_state(idxd);
++
++ spin_lock(&idxd->dev_lock);
++ idxd_groups_clear_state(idxd);
++ idxd_engines_clear_state(idxd);
++ } else {
++ spin_lock(&idxd->dev_lock);
++ }
+
+- idxd_device_wqs_clear_state(idxd);
+- spin_lock(&idxd->dev_lock);
+- idxd_groups_clear_state(idxd);
+- idxd_engines_clear_state(idxd);
+ idxd->state = IDXD_DEV_DISABLED;
+ spin_unlock(&idxd->dev_lock);
+ }
+@@ -863,7 +871,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
+
+ /* bytes 12-15 */
+ wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes);
+- wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size);
++ idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size));
+
+ dev_dbg(dev, "WQ %d CFGs\n", wq->id);
+ for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
+@@ -1031,7 +1039,7 @@ static int idxd_wq_load_config(struct idxd_wq *wq)
+ wq->priority = wq->wqcfg->priority;
+
+ wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift;
+- wq->max_batch_size = 1ULL << wq->wqcfg->max_batch_shift;
++ idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift);
+
+ for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
+ wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i);
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index fed0dfc1eaa83..05c3f86944783 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -308,6 +308,8 @@ struct idxd_device {
+ struct work_struct work;
+
+ struct idxd_pmu *idxd_pmu;
++
++ unsigned long *opcap_bmap;
+ };
+
+ /* IDXD software descriptor */
+@@ -540,6 +542,38 @@ static inline int idxd_wq_refcount(struct idxd_wq *wq)
+ return wq->client_count;
+ };
+
++/*
++ * Intel IAA does not support batch processing.
++ * The max batch size of device, max batch size of wq and
++ * max batch shift of wqcfg should be always 0 on IAA.
++ */
++static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd,
++ u32 max_batch_size)
++{
++ if (idxd_type == IDXD_TYPE_IAX)
++ idxd->max_batch_size = 0;
++ else
++ idxd->max_batch_size = max_batch_size;
++}
++
++static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
++ u32 max_batch_size)
++{
++ if (idxd_type == IDXD_TYPE_IAX)
++ wq->max_batch_size = 0;
++ else
++ wq->max_batch_size = max_batch_size;
++}
++
++static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
++ u32 max_batch_shift)
++{
++ if (idxd_type == IDXD_TYPE_IAX)
++ wqcfg->max_batch_shift = 0;
++ else
++ wqcfg->max_batch_shift = max_batch_shift;
++}
++
+ int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
+ struct module *module, const char *mod_name);
+ #define idxd_driver_register(driver) \
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index aa3478257ddb5..cf94795ca1afa 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -177,7 +177,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
+ init_completion(&wq->wq_dead);
+ init_completion(&wq->wq_resurrect);
+ wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
+- wq->max_batch_size = WQ_DEFAULT_MAX_BATCH;
++ idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
+ wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
+ if (!wq->wqcfg) {
+@@ -369,6 +369,19 @@ static void idxd_read_table_offsets(struct idxd_device *idxd)
+ dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset);
+ }
+
++static void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count)
++{
++ int i, j, nr;
++
++ for (i = 0, nr = 0; i < count; i++) {
++ for (j = 0; j < BITS_PER_LONG_LONG; j++) {
++ if (val[i] & BIT(j))
++ set_bit(nr, bmap);
++ nr++;
++ }
++ }
++}
++
+ static void idxd_read_caps(struct idxd_device *idxd)
+ {
+ struct device *dev = &idxd->pdev->dev;
+@@ -389,7 +402,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
+
+ idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift;
+ dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes);
+- idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift;
++ idxd_set_max_batch_size(idxd->data->type, idxd, 1U << idxd->hw.gen_cap.max_batch_shift);
+ dev_dbg(dev, "max batch size: %u\n", idxd->max_batch_size);
+ if (idxd->hw.gen_cap.config_en)
+ set_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags);
+@@ -427,6 +440,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
+ IDXD_OPCAP_OFFSET + i * sizeof(u64));
+ dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]);
+ }
++ multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4);
+ }
+
+ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
+@@ -448,6 +462,12 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
+ if (idxd->id < 0)
+ return NULL;
+
++ idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
++ if (!idxd->opcap_bmap) {
++ ida_free(&idxd_ida, idxd->id);
++ return NULL;
++ }
++
+ device_initialize(conf_dev);
+ conf_dev->parent = dev;
+ conf_dev->bus = &dsa_bus_type;
+diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
+index 02449aa9c454f..4c96ea85f8435 100644
+--- a/drivers/dma/idxd/registers.h
++++ b/drivers/dma/idxd/registers.h
+@@ -90,6 +90,8 @@ struct opcap {
+ u64 bits[4];
+ };
+
++#define IDXD_MAX_OPCAP_BITS 256U
++
+ #define IDXD_OPCAP_OFFSET 0x40
+
+ #define IDXD_TABLE_OFFSET 0x60
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 3f262a57441b4..82538622320a8 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -961,7 +961,7 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu
+ if (batch_size > idxd->max_batch_size)
+ return -EINVAL;
+
+- wq->max_batch_size = (u32)batch_size;
++ idxd_wq_set_max_batch_size(idxd->data->type, wq, (u32)batch_size);
+
+ return count;
+ }
+@@ -1177,14 +1177,8 @@ static ssize_t op_cap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct idxd_device *idxd = confdev_to_idxd(dev);
+- int i, rc = 0;
+-
+- for (i = 0; i < 4; i++)
+- rc += sysfs_emit_at(buf, rc, "%#llx ", idxd->hw.opcap.bits[i]);
+
+- rc--;
+- rc += sysfs_emit_at(buf, rc, "\n");
+- return rc;
++ return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
+ }
+ static DEVICE_ATTR_RO(op_cap);
+
+@@ -1408,6 +1402,7 @@ static void idxd_conf_device_release(struct device *dev)
+ kfree(idxd->wqs);
+ kfree(idxd->engines);
+ ida_free(&idxd_ida, idxd->id);
++ bitmap_free(idxd->opcap_bmap);
+ kfree(idxd);
+ }
+
+diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
+index f629ef6fd3c2a..113834e1167b6 100644
+--- a/drivers/dma/mv_xor_v2.c
++++ b/drivers/dma/mv_xor_v2.c
+@@ -893,6 +893,7 @@ static int mv_xor_v2_remove(struct platform_device *pdev)
+ tasklet_kill(&xor_dev->irq_tasklet);
+
+ clk_disable_unprepare(xor_dev->clk);
++ clk_disable_unprepare(xor_dev->reg_clk);
+
+ return 0;
+ }
+diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
+index e7034f6f3994a..22a392fe6d32b 100644
+--- a/drivers/dma/pxa_dma.c
++++ b/drivers/dma/pxa_dma.c
+@@ -1247,14 +1247,14 @@ static int pxad_init_phys(struct platform_device *op,
+ return -ENOMEM;
+
+ for (i = 0; i < nb_phy_chans; i++)
+- if (platform_get_irq(op, i) > 0)
++ if (platform_get_irq_optional(op, i) > 0)
+ nr_irq++;
+
+ for (i = 0; i < nb_phy_chans; i++) {
+ phy = &pdev->phys[i];
+ phy->base = pdev->base;
+ phy->idx = i;
+- irq = platform_get_irq(op, i);
++ irq = platform_get_irq_optional(op, i);
+ if ((nr_irq > 1) && (irq > 0))
+ ret = devm_request_irq(&op->dev, irq,
+ pxad_chan_handler,
+diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
+index adb25a11c70fe..5aeaaac846dfd 100644
+--- a/drivers/dma/stm32-dma.c
++++ b/drivers/dma/stm32-dma.c
+@@ -663,6 +663,8 @@ static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan)
+
+ chan->chan_reg.dma_sndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id));
+
++ chan->status = DMA_PAUSED;
++
+ dev_dbg(chan2dev(chan), "vchan %pK: paused\n", &chan->vchan);
+ }
+
+@@ -775,9 +777,7 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
+ if (status & STM32_DMA_TCI) {
+ stm32_dma_irq_clear(chan, STM32_DMA_TCI);
+ if (scr & STM32_DMA_SCR_TCIE) {
+- if (chan->status == DMA_PAUSED && !(scr & STM32_DMA_SCR_EN))
+- stm32_dma_handle_chan_paused(chan);
+- else
++ if (chan->status != DMA_PAUSED)
+ stm32_dma_handle_chan_done(chan, scr);
+ }
+ status &= ~STM32_DMA_TCI;
+@@ -824,13 +824,11 @@ static int stm32_dma_pause(struct dma_chan *c)
+ return -EPERM;
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
++
+ ret = stm32_dma_disable_chan(chan);
+- /*
+- * A transfer complete flag is set to indicate the end of transfer due to the stream
+- * interruption, so wait for interrupt
+- */
+ if (!ret)
+- chan->status = DMA_PAUSED;
++ stm32_dma_handle_chan_paused(chan);
++
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+
+ return ret;
+diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
+index 4fdd9f06b7235..4f1aeb81e9c7f 100644
+--- a/drivers/dma/ti/k3-udma-glue.c
++++ b/drivers/dma/ti/k3-udma-glue.c
+@@ -299,6 +299,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
+ ret = device_register(&tx_chn->common.chan_dev);
+ if (ret) {
+ dev_err(dev, "Channel Device registration failed %d\n", ret);
++ put_device(&tx_chn->common.chan_dev);
+ tx_chn->common.chan_dev.parent = NULL;
+ goto err;
+ }
+@@ -917,6 +918,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
+ ret = device_register(&rx_chn->common.chan_dev);
+ if (ret) {
+ dev_err(dev, "Channel Device registration failed %d\n", ret);
++ put_device(&rx_chn->common.chan_dev);
+ rx_chn->common.chan_dev.parent = NULL;
+ goto err;
+ }
+@@ -1048,6 +1050,7 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
+ ret = device_register(&rx_chn->common.chan_dev);
+ if (ret) {
+ dev_err(dev, "Channel Device registration failed %d\n", ret);
++ put_device(&rx_chn->common.chan_dev);
+ rx_chn->common.chan_dev.parent = NULL;
+ goto err;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+index 9ecb7f663e196..278512535b518 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -485,6 +485,21 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
+ */
+ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
+ {
++ unsigned long flags;
++ spinlock_t *lock;
++
++ /*
++ * Workaround to stop racing between the fence signaling and handling
++ * the cb. The lock is static after initially setting it up, just make
++ * sure that the dma_fence structure isn't freed up.
++ */
++ rcu_read_lock();
++ lock = vm->last_tlb_flush->lock;
++ rcu_read_unlock();
++
++ spin_lock_irqsave(lock, flags);
++ spin_unlock_irqrestore(lock, flags);
++
+ return atomic64_read(&vm->tlb_seq);
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+index 28ec5f8ac1c11..27159f1d112ec 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+@@ -435,7 +435,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
+ if (place->flags & TTM_PL_FLAG_TOPDOWN)
+ vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
+
+- if (fpfn || lpfn != man->size)
++ if (fpfn || lpfn != mgr->mm.size)
+ /* Allocate blocks in desired range */
+ vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+index dc774ddf34456..033fcd594edcb 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1928,7 +1928,7 @@ static int criu_checkpoint(struct file *filep,
+ {
+ int ret;
+ uint32_t num_devices, num_bos, num_objects;
+- uint64_t priv_size, priv_offset = 0;
++ uint64_t priv_size, priv_offset = 0, bo_priv_offset;
+
+ if (!args->devices || !args->bos || !args->priv_data)
+ return -EINVAL;
+@@ -1972,38 +1972,34 @@ static int criu_checkpoint(struct file *filep,
+ if (ret)
+ goto exit_unlock;
+
+- ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos,
+- (uint8_t __user *)args->priv_data, &priv_offset);
+- if (ret)
+- goto exit_unlock;
++ /* Leave room for BOs in the private data. They need to be restored
++ * before events, but we checkpoint them last to simplify the error
++ * handling.
++ */
++ bo_priv_offset = priv_offset;
++ priv_offset += num_bos * sizeof(struct kfd_criu_bo_priv_data);
+
+ if (num_objects) {
+ ret = kfd_criu_checkpoint_queues(p, (uint8_t __user *)args->priv_data,
+ &priv_offset);
+ if (ret)
+- goto close_bo_fds;
++ goto exit_unlock;
+
+ ret = kfd_criu_checkpoint_events(p, (uint8_t __user *)args->priv_data,
+ &priv_offset);
+ if (ret)
+- goto close_bo_fds;
++ goto exit_unlock;
+
+ ret = kfd_criu_checkpoint_svm(p, (uint8_t __user *)args->priv_data, &priv_offset);
+ if (ret)
+- goto close_bo_fds;
++ goto exit_unlock;
+ }
+
+-close_bo_fds:
+- if (ret) {
+- /* If IOCTL returns err, user assumes all FDs opened in criu_dump_bos are closed */
+- uint32_t i;
+- struct kfd_criu_bo_bucket *bo_buckets = (struct kfd_criu_bo_bucket *) args->bos;
+-
+- for (i = 0; i < num_bos; i++) {
+- if (bo_buckets[i].alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM)
+- close_fd(bo_buckets[i].dmabuf_fd);
+- }
+- }
++ /* This must be the last thing in this function that can fail.
++ * Otherwise we leak dmabuf file descriptors.
++ */
++ ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos,
++ (uint8_t __user *)args->priv_data, &bo_priv_offset);
+
+ exit_unlock:
+ mutex_unlock(&p->mutex);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+index 83e3ce9f60491..729d26d648af3 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+@@ -506,6 +506,7 @@ int kfd_criu_restore_event(struct file *devkfd,
+ ret = create_other_event(p, ev, &ev_priv->event_id);
+ break;
+ }
++ mutex_unlock(&p->event_mutex);
+
+ exit:
+ if (ret)
+@@ -513,8 +514,6 @@ exit:
+
+ kfree(ev_priv);
+
+- mutex_unlock(&p->event_mutex);
+-
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+index b059a77b6081d..058dbb6782df6 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+@@ -886,7 +886,7 @@ svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
+ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ {
+ unsigned long addr = vmf->address;
+- struct vm_area_struct *vma;
++ struct svm_range_bo *svm_bo;
+ enum svm_work_list_ops op;
+ struct svm_range *parent;
+ struct svm_range *prange;
+@@ -894,29 +894,42 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ struct mm_struct *mm;
+ int r = 0;
+
+- vma = vmf->vma;
+- mm = vma->vm_mm;
++ svm_bo = vmf->page->zone_device_data;
++ if (!svm_bo) {
++ pr_debug("failed get device page at addr 0x%lx\n", addr);
++ return VM_FAULT_SIGBUS;
++ }
++ if (!mmget_not_zero(svm_bo->eviction_fence->mm)) {
++ pr_debug("addr 0x%lx of process mm is detroyed\n", addr);
++ return VM_FAULT_SIGBUS;
++ }
+
+- p = kfd_lookup_process_by_mm(vma->vm_mm);
++ mm = svm_bo->eviction_fence->mm;
++ if (mm != vmf->vma->vm_mm)
++ pr_debug("addr 0x%lx is COW mapping in child process\n", addr);
++
++ p = kfd_lookup_process_by_mm(mm);
+ if (!p) {
+ pr_debug("failed find process at fault address 0x%lx\n", addr);
+- return VM_FAULT_SIGBUS;
++ r = VM_FAULT_SIGBUS;
++ goto out_mmput;
+ }
+ if (READ_ONCE(p->svms.faulting_task) == current) {
+ pr_debug("skipping ram migration\n");
+- kfd_unref_process(p);
+- return 0;
++ r = 0;
++ goto out_unref_process;
+ }
+- addr >>= PAGE_SHIFT;
++
+ pr_debug("CPU page fault svms 0x%p address 0x%lx\n", &p->svms, addr);
++ addr >>= PAGE_SHIFT;
+
+ mutex_lock(&p->svms.lock);
+
+ prange = svm_range_from_addr(&p->svms, addr, &parent);
+ if (!prange) {
+- pr_debug("cannot find svm range at 0x%lx\n", addr);
++ pr_debug("failed get range svms 0x%p addr 0x%lx\n", &p->svms, addr);
+ r = -EFAULT;
+- goto out;
++ goto out_unlock_svms;
+ }
+
+ mutex_lock(&parent->migrate_mutex);
+@@ -938,10 +951,11 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ goto out_unlock_prange;
+ }
+
+- r = svm_migrate_vram_to_ram(prange, mm, KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU);
++ r = svm_migrate_vram_to_ram(prange, vmf->vma->vm_mm,
++ KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU);
+ if (r)
+- pr_debug("failed %d migrate 0x%p [0x%lx 0x%lx] to ram\n", r,
+- prange, prange->start, prange->last);
++ pr_debug("failed %d migrate svms 0x%p range 0x%p [0x%lx 0x%lx]\n",
++ r, prange->svms, prange, prange->start, prange->last);
+
+ /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */
+ if (p->xnack_enabled && parent == prange)
+@@ -955,12 +969,13 @@ out_unlock_prange:
+ if (prange != parent)
+ mutex_unlock(&prange->migrate_mutex);
+ mutex_unlock(&parent->migrate_mutex);
+-out:
++out_unlock_svms:
+ mutex_unlock(&p->svms.lock);
+- kfd_unref_process(p);
+-
++out_unref_process:
+ pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr);
+-
++ kfd_unref_process(p);
++out_mmput:
++ mmput(mm);
+ return r ? VM_FAULT_SIGBUS : 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+index 4a15aa7a375fe..2680eecb3369d 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+@@ -356,32 +356,32 @@ static struct wm_table ddr5_wm_table = {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+- .sr_exit_time_us = 9,
+- .sr_enter_plus_exit_time_us = 11,
++ .sr_exit_time_us = 12.5,
++ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+- .sr_exit_time_us = 9,
+- .sr_enter_plus_exit_time_us = 11,
++ .sr_exit_time_us = 12.5,
++ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+- .sr_exit_time_us = 9,
+- .sr_enter_plus_exit_time_us = 11,
++ .sr_exit_time_us = 12.5,
++ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+- .sr_exit_time_us = 9,
+- .sr_enter_plus_exit_time_us = 11,
++ .sr_exit_time_us = 12.5,
++ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ }
+@@ -393,32 +393,32 @@ static struct wm_table lpddr5_wm_table = {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+- .sr_exit_time_us = 11.5,
+- .sr_enter_plus_exit_time_us = 14.5,
++ .sr_exit_time_us = 16.5,
++ .sr_enter_plus_exit_time_us = 18.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+- .sr_exit_time_us = 11.5,
+- .sr_enter_plus_exit_time_us = 14.5,
++ .sr_exit_time_us = 16.5,
++ .sr_enter_plus_exit_time_us = 18.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+- .sr_exit_time_us = 11.5,
+- .sr_enter_plus_exit_time_us = 14.5,
++ .sr_exit_time_us = 16.5,
++ .sr_enter_plus_exit_time_us = 18.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+- .sr_exit_time_us = 11.5,
+- .sr_enter_plus_exit_time_us = 14.5,
++ .sr_exit_time_us = 16.5,
++ .sr_enter_plus_exit_time_us = 18.5,
+ .valid = true,
+ },
+ }
+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 f0f3f66629cc0..e7f1d5f8166f9 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
+@@ -156,7 +156,8 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
+ {
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ unsigned int num_levels;
+- unsigned int num_dcfclk_levels, num_dtbclk_levels, num_dispclk_levels;
++ struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
++ unsigned int i;
+
+ memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
+ clk_mgr_base->clks.p_state_change_support = true;
+@@ -180,42 +181,42 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
+ /* DCFCLK */
+ dcn32_init_single_clock(clk_mgr, PPCLK_DCFCLK,
+ &clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
+- &num_levels);
+- num_dcfclk_levels = num_levels;
++ &num_entries_per_clk->num_dcfclk_levels);
+
+ /* SOCCLK */
+ dcn32_init_single_clock(clk_mgr, PPCLK_SOCCLK,
+ &clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,
+- &num_levels);
++ &num_entries_per_clk->num_socclk_levels);
++
+ /* DTBCLK */
+ if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch)
+ dcn32_init_single_clock(clk_mgr, PPCLK_DTBCLK,
+ &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
+- &num_levels);
+- num_dtbclk_levels = num_levels;
++ &num_entries_per_clk->num_dtbclk_levels);
+
+ /* DISPCLK */
+ dcn32_init_single_clock(clk_mgr, PPCLK_DISPCLK,
+ &clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
+- &num_levels);
+- num_dispclk_levels = num_levels;
++ &num_entries_per_clk->num_dispclk_levels);
++ num_levels = num_entries_per_clk->num_dispclk_levels;
+
+- if (num_dcfclk_levels && num_dtbclk_levels && num_dispclk_levels)
++ if (num_entries_per_clk->num_dcfclk_levels &&
++ num_entries_per_clk->num_dtbclk_levels &&
++ num_entries_per_clk->num_dispclk_levels)
+ clk_mgr->dpm_present = true;
+
+ if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) {
+- unsigned int i;
+-
+ for (i = 0; i < num_levels; i++)
+ if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
+ < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz))
+ clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
+ = khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz);
+ }
++ for (i = 0; i < num_levels; i++)
++ if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz > 1950)
++ clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = 1950;
+
+ if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) {
+- unsigned int i;
+-
+ for (i = 0; i < num_levels; i++)
+ if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz
+ < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz))
+@@ -370,7 +371,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
+ /* to disable P-State switching, set UCLK min = max */
+ if (!clk_mgr_base->clks.p_state_change_support)
+ dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+- clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++ clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ }
+
+ if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support) &&
+@@ -632,7 +633,7 @@ static void dcn32_set_hard_min_memclk(struct clk_mgr *clk_mgr_base, bool current
+ khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
+ else
+ dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+- clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++ clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ } else {
+ dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+ clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz);
+@@ -648,22 +649,37 @@ static void dcn32_set_hard_max_memclk(struct clk_mgr *clk_mgr_base)
+ return;
+
+ dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
+- clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++ clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ }
+
+ /* Get current memclk states, update bounding box */
+ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
+ {
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
++ struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+ unsigned int num_levels;
+
+ if (!clk_mgr->smu_present)
+ return;
+
+- /* Refresh memclk states */
++ /* Refresh memclk and fclk states */
+ dcn32_init_single_clock(clk_mgr, PPCLK_UCLK,
+ &clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz,
+- &num_levels);
++ &num_entries_per_clk->num_memclk_levels);
++
++ /* memclk must have at least one level */
++ num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1;
++
++ dcn32_init_single_clock(clk_mgr, PPCLK_FCLK,
++ &clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
++ &num_entries_per_clk->num_fclk_levels);
++
++ if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) {
++ num_levels = num_entries_per_clk->num_memclk_levels;
++ } else {
++ num_levels = num_entries_per_clk->num_fclk_levels;
++ }
++
+ clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1;
+
+ if (clk_mgr->dpm_present && !num_levels)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
+index 8c0ab013764e3..e7f1bf0b04c57 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
+@@ -49,18 +49,30 @@
+ #define CTX \
+ enc1->base.ctx
+
++static void enc314_reset_fifo(struct stream_encoder *enc, bool reset)
++{
++ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
++ uint32_t reset_val = reset ? 1 : 0;
++ uint32_t is_symclk_on;
++
++ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val);
++ REG_GET(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, &is_symclk_on);
++
++ if (is_symclk_on)
++ REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000);
++ else
++ udelay(10);
++}
+
+ static void enc314_enable_fifo(struct stream_encoder *enc)
+ {
+ struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+- /* TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON */
+- REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7);
+- REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+- REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
+- REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+- REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
++
++ enc314_reset_fifo(enc, true);
++ enc314_reset_fifo(enc, false);
++
+ REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+index 4bb3b31ea7e0c..60f43473d6d88 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+@@ -146,8 +146,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
+ },
+ },
+ .num_states = 5,
+- .sr_exit_time_us = 9.0,
+- .sr_enter_plus_exit_time_us = 11.0,
++ .sr_exit_time_us = 16.5,
++ .sr_enter_plus_exit_time_us = 18.5,
+ .sr_exit_z8_time_us = 442.0,
+ .sr_enter_plus_exit_z8_time_us = 560.0,
+ .writeback_latency_us = 12.0,
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+index d9f1b0a4fbd4a..591ab1389e3b3 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+@@ -95,10 +95,23 @@ struct clk_limit_table_entry {
+ unsigned int wck_ratio;
+ };
+
++struct clk_limit_num_entries {
++ unsigned int num_dcfclk_levels;
++ unsigned int num_fclk_levels;
++ unsigned int num_memclk_levels;
++ unsigned int num_socclk_levels;
++ unsigned int num_dtbclk_levels;
++ unsigned int num_dispclk_levels;
++ unsigned int num_dppclk_levels;
++ unsigned int num_phyclk_levels;
++ unsigned int num_phyclk_d18_levels;
++};
++
+ /* This table is contiguous */
+ struct clk_limit_table {
+ struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];
+- unsigned int num_entries;
++ struct clk_limit_num_entries num_entries_per_clk;
++ unsigned int num_entries; /* highest populated dpm level for back compatibility */
+ };
+
+ struct wm_range_table_entry {
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
+index d9b0cd7522006..f4d6c07b56ea7 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
+@@ -54,14 +54,14 @@
+ #define PPSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team
+ #define PPSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version
+ #define PPSMC_MSG_GetDriverIfVersion 0x03 ///< Get PMFW_DRIVER_IF version
+-#define PPSMC_MSG_EnableGfxOff 0x04 ///< Enable GFXOFF
+-#define PPSMC_MSG_DisableGfxOff 0x05 ///< Disable GFXOFF
++#define PPSMC_MSG_SPARE0 0x04 ///< SPARE
++#define PPSMC_MSG_SPARE1 0x05 ///< SPARE
+ #define PPSMC_MSG_PowerDownVcn 0x06 ///< Power down VCN
+ #define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default
+ #define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display
+ #define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz
+-#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Needs update
+-#define PPSMC_MSG_ForcePowerDownGfx 0x0B ///< Force power down GFX, i.e. enter GFXOFF
++#define PPSMC_MSG_SPARE2 0x0A ///< SPARE
++#define PPSMC_MSG_SPARE3 0x0B ///< SPARE
+ #define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload
+ #define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer
+ #define PPSMC_MSG_SetDriverDramAddrLow 0x0E ///< Set low 32 bits of DRAM address for Driver table transfer
+@@ -73,8 +73,7 @@
+ #define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK
+ #define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK)
+
+-
+-#define PPSMC_MSG_EnableGfxImu 0x16 ///< Needs update
++#define PPSMC_MSG_EnableGfxImu 0x16 ///< Enable GFX IMU
+
+ #define PPSMC_MSG_GetGfxclkFrequency 0x17 ///< Get GFX clock frequency
+ #define PPSMC_MSG_GetFclkFrequency 0x18 ///< Get FCLK frequency
+@@ -102,8 +101,8 @@
+ #define PPSMC_MSG_SetHardMinIspxclkByFreq 0x2C ///< Set HardMin by frequency for ISPXCLK
+ #define PPSMC_MSG_PowerDownUmsch 0x2D ///< Power down VCN.UMSCH (aka VSCH) scheduler
+ #define PPSMC_MSG_PowerUpUmsch 0x2E ///< Power up VCN.UMSCH (aka VSCH) scheduler
+-#define PPSMC_Message_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis
+-#define PPSMC_Message_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn
++#define PPSMC_MSG_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis
++#define PPSMC_MSG_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn
+
+ #define PPSMC_Message_Count 0x31 ///< Total number of PPSMC messages
+ /** @}*/
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index 644ea150e0751..8292839bc42a9 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -376,7 +376,9 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
+ if (((adev->pdev->device == 0x73A1) &&
+ (adev->pdev->revision == 0x00)) ||
+ ((adev->pdev->device == 0x73BF) &&
+- (adev->pdev->revision == 0xCF)))
++ (adev->pdev->revision == 0xCF)) ||
++ ((adev->pdev->device == 0x7422) &&
++ (adev->pdev->revision == 0x00)))
+ smu_baco->platform_support = false;
+
+ }
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index d4492b6d23d25..21ba510716b6c 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -5233,7 +5233,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
+ encoder->devdata, IS_ERR(edid) ? NULL : edid);
+
+ intel_panel_add_edid_fixed_modes(intel_connector,
+- intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
++ intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE ||
+ intel_vrr_is_capable(intel_connector));
+
+ /* MSO requires information from the EDID */
+diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
+index 730480ac3300d..c0bec3e0f0ae9 100644
+--- a/drivers/gpu/drm/i915/display/intel_lvds.c
++++ b/drivers/gpu/drm/i915/display/intel_lvds.c
+@@ -972,8 +972,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
+
+ /* Try EDID first */
+ intel_panel_add_edid_fixed_modes(intel_connector,
+- intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
+- false);
++ intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
+
+ /* Failed to get EDID, what about VBT? */
+ if (!intel_panel_preferred_fixed_mode(intel_connector))
+diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
+index 237a40623dd7b..1e008922b95d3 100644
+--- a/drivers/gpu/drm/i915/display/intel_panel.c
++++ b/drivers/gpu/drm/i915/display/intel_panel.c
+@@ -81,15 +81,14 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
+ mode->clock != preferred_mode->clock;
+ }
+
+-static bool is_alt_vrr_mode(const struct drm_display_mode *mode,
+- const struct drm_display_mode *preferred_mode)
++static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
++ const struct drm_display_mode *preferred_mode)
+ {
+ return drm_mode_match(mode, preferred_mode,
+ DRM_MODE_MATCH_FLAGS |
+ DRM_MODE_MATCH_3D_FLAGS) &&
+ mode->hdisplay == preferred_mode->hdisplay &&
+- mode->vdisplay == preferred_mode->vdisplay &&
+- mode->clock != preferred_mode->clock;
++ mode->vdisplay == preferred_mode->vdisplay;
+ }
+
+ const struct drm_display_mode *
+@@ -172,19 +171,7 @@ int intel_panel_compute_config(struct intel_connector *connector,
+ return 0;
+ }
+
+-static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
+- const struct drm_display_mode *preferred_mode,
+- bool has_vrr)
+-{
+- /* is_alt_drrs_mode() is a subset of is_alt_vrr_mode() */
+- if (has_vrr)
+- return is_alt_vrr_mode(mode, preferred_mode);
+- else
+- return is_alt_drrs_mode(mode, preferred_mode);
+-}
+-
+-static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector,
+- bool has_vrr)
++static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
+ {
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ const struct drm_display_mode *preferred_mode =
+@@ -192,7 +179,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
+ struct drm_display_mode *mode, *next;
+
+ list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
+- if (!is_alt_fixed_mode(mode, preferred_mode, has_vrr))
++ if (!is_alt_fixed_mode(mode, preferred_mode))
+ continue;
+
+ drm_dbg_kms(&dev_priv->drm,
+@@ -251,11 +238,11 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
+ }
+
+ void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
+- bool has_drrs, bool has_vrr)
++ bool use_alt_fixed_modes)
+ {
+ intel_panel_add_edid_preferred_mode(connector);
+- if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
+- intel_panel_add_edid_alt_fixed_modes(connector, has_vrr);
++ if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes)
++ intel_panel_add_edid_alt_fixed_modes(connector);
+ intel_panel_destroy_probed_modes(connector);
+ }
+
+diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
+index b087c0c3cc6db..4a94bd0eae3bf 100644
+--- a/drivers/gpu/drm/i915/display/intel_panel.h
++++ b/drivers/gpu/drm/i915/display/intel_panel.h
+@@ -41,7 +41,7 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state,
+ int intel_panel_compute_config(struct intel_connector *connector,
+ struct drm_display_mode *adjusted_mode);
+ void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
+- bool has_drrs, bool has_vrr);
++ bool use_alt_fixed_modes);
+ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector);
+ void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector);
+ void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
+diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
+index e6a870641cd25..fbe777e02ea7f 100644
+--- a/drivers/gpu/drm/i915/display/intel_psr.c
++++ b/drivers/gpu/drm/i915/display/intel_psr.c
+@@ -2188,8 +2188,11 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp)
+ if (intel_dp->psr.psr2_sel_fetch_enabled) {
+ u32 val;
+
+- if (intel_dp->psr.psr2_sel_fetch_cff_enabled)
++ if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
++ /* Send one update otherwise lag is observed in screen */
++ intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ return;
++ }
+
+ val = man_trk_ctl_enable_bit_get(dev_priv) |
+ man_trk_ctl_partial_frame_bit_get(dev_priv) |
+diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
+index b5f65b093c106..6b471fc297bd6 100644
+--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
+@@ -2900,8 +2900,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+ intel_panel_add_vbt_sdvo_fixed_mode(intel_connector);
+
+ if (!intel_panel_preferred_fixed_mode(intel_connector)) {
++ mutex_lock(&i915->drm.mode_config.mutex);
++
+ intel_ddc_get_modes(connector, &intel_sdvo->ddc);
+- intel_panel_add_edid_fixed_modes(intel_connector, false, false);
++ intel_panel_add_edid_fixed_modes(intel_connector, false);
++
++ mutex_unlock(&i915->drm.mode_config.mutex);
+ }
+
+ intel_panel_init(intel_connector);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+index f5062d0c63336..824971a1ceece 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+@@ -40,13 +40,13 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
+ goto err;
+ }
+
+- ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
++ ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
+ if (ret)
+ goto err_free;
+
+ src = obj->mm.pages->sgl;
+ dst = st->sgl;
+- for (i = 0; i < obj->mm.pages->nents; i++) {
++ for (i = 0; i < obj->mm.pages->orig_nents; i++) {
+ sg_set_page(dst, sg_page(src), src->length, 0);
+ dst = sg_next(dst);
+ src = sg_next(src);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+index 34b9c76cd8e66..b5eb279a5c2c7 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+@@ -369,14 +369,14 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
+
+ __start_cpu_write(obj);
+ /*
+- * On non-LLC platforms, force the flush-on-acquire if this is ever
++ * On non-LLC igfx platforms, force the flush-on-acquire if this is ever
+ * swapped-in. Our async flush path is not trust worthy enough yet(and
+ * happens in the wrong order), and with some tricks it's conceivable
+ * for userspace to change the cache-level to I915_CACHE_NONE after the
+ * pages are swapped-in, and since execbuf binds the object before doing
+ * the async flush, we have a race window.
+ */
+- if (!HAS_LLC(i915))
++ if (!HAS_LLC(i915) && !IS_DGFX(i915))
+ obj->cache_dirty = true;
+ }
+
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index e3cd589464777..de89946c4817f 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -1595,6 +1595,9 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
+
+ if (WARN_ON_ONCE(vgpu->attached))
+ return;
++
++ vfio_unregister_group_dev(&vgpu->vfio_device);
++ vfio_uninit_group_dev(&vgpu->vfio_device);
+ intel_gvt_destroy_vgpu(vgpu);
+ }
+
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index c186ace7f83b9..2064863a0fd32 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -476,7 +476,12 @@ static int __init vc4_drm_register(void)
+ if (ret)
+ return ret;
+
+- return platform_driver_register(&vc4_platform_driver);
++ ret = platform_driver_register(&vc4_platform_driver);
++ if (ret)
++ platform_unregister_drivers(component_drivers,
++ ARRAY_SIZE(component_drivers));
++
++ return ret;
+ }
+
+ static void __exit vc4_drm_unregister(void)
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 874c6bd787c56..4e5bba0822a5d 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2712,9 +2712,16 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ DRM_ERROR("Failed to get HDMI state machine clock\n");
+ return PTR_ERR(vc4_hdmi->hsm_clock);
+ }
++
+ vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
+ vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock;
+
++ vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
++ if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
++ DRM_ERROR("Failed to get HDMI state machine clock\n");
++ return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
++ }
++
+ return 0;
+ }
+
+@@ -2796,6 +2803,12 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ return PTR_ERR(vc4_hdmi->hsm_clock);
+ }
+
++ vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
++ if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
++ DRM_ERROR("Failed to get HDMI state machine clock\n");
++ return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
++ }
++
+ vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
+ if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
+ DRM_ERROR("Failed to get pixel bvb clock\n");
+@@ -2859,7 +2872,7 @@ static int vc4_hdmi_runtime_suspend(struct device *dev)
+ {
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+
+- clk_disable_unprepare(vc4_hdmi->hsm_clock);
++ clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock);
+
+ return 0;
+ }
+@@ -2877,11 +2890,11 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ * its frequency while the power domain is active so that it
+ * keeps its rate.
+ */
+- ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
++ ret = clk_set_min_rate(vc4_hdmi->hsm_rpm_clock, HSM_MIN_CLOCK_FREQ);
+ if (ret)
+ return ret;
+
+- ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
++ ret = clk_prepare_enable(vc4_hdmi->hsm_rpm_clock);
+ if (ret)
+ return ret;
+
+@@ -2894,7 +2907,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ * case, it will lead to a silent CPU stall. Let's make sure we
+ * prevent such a case.
+ */
+- rate = clk_get_rate(vc4_hdmi->hsm_clock);
++ rate = clk_get_rate(vc4_hdmi->hsm_rpm_clock);
+ if (!rate) {
+ ret = -EINVAL;
+ goto err_disable_clk;
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
+index c3ed2b07df235..47f141ec8c40c 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -171,6 +171,7 @@ struct vc4_hdmi {
+ struct clk *cec_clock;
+ struct clk *pixel_clock;
+ struct clk *hsm_clock;
++ struct clk *hsm_rpm_clock;
+ struct clk *audio_clock;
+ struct clk *pixel_bvb_clock;
+
+diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
+index e0bc731241960..ab57b49a44ed9 100644
+--- a/drivers/hid/hid-hyperv.c
++++ b/drivers/hid/hid-hyperv.c
+@@ -499,7 +499,7 @@ static int mousevsc_probe(struct hv_device *device,
+
+ ret = hid_add_device(hid_dev);
+ if (ret)
+- goto probe_err1;
++ goto probe_err2;
+
+
+ ret = hid_parse(hid_dev);
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index d049239256a26..2bd1a43021c92 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -2522,11 +2522,12 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
+
+ if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) {
+ int id = wacom_wac->id[0];
+- if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 &&
+- wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) {
+- wacom_wac->hid_data.barrelswitch = 0;
+- wacom_wac->hid_data.barrelswitch2 = 0;
+- wacom_wac->hid_data.barrelswitch3 = 1;
++ if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3) {
++ int sw_state = wacom_wac->hid_data.barrelswitch |
++ (wacom_wac->hid_data.barrelswitch2 << 1);
++ wacom_wac->hid_data.barrelswitch = sw_state == 1;
++ wacom_wac->hid_data.barrelswitch2 = sw_state == 2;
++ wacom_wac->hid_data.barrelswitch3 = sw_state == 3;
+ }
+ input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch);
+ input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2);
+diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
+index 80ea45b3a815f..9734e149d981b 100644
+--- a/drivers/hwspinlock/qcom_hwspinlock.c
++++ b/drivers/hwspinlock/qcom_hwspinlock.c
+@@ -121,7 +121,7 @@ static const struct regmap_config tcsr_mutex_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+- .max_register = 0x40000,
++ .max_register = 0x20000,
+ .fast_io = true,
+ };
+
+diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
+index aff36a933ebec..55d8bd232695c 100644
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -12,6 +12,7 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "cqhci.h"
+
+@@ -55,7 +56,7 @@ static void brcmstb_reset(struct sdhci_host *host, u8 mask)
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
+
+- sdhci_reset(host, mask);
++ sdhci_and_cqhci_reset(host, mask);
+
+ /* Reset will clear this, so re-enable it */
+ if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK)
+diff --git a/drivers/mmc/host/sdhci-cqhci.h b/drivers/mmc/host/sdhci-cqhci.h
+new file mode 100644
+index 0000000000000..cf8e7ba71bbd7
+--- /dev/null
++++ b/drivers/mmc/host/sdhci-cqhci.h
+@@ -0,0 +1,24 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright 2022 The Chromium OS Authors
++ *
++ * Support that applies to the combination of SDHCI and CQHCI, while not
++ * expressing a dependency between the two modules.
++ */
++
++#ifndef __MMC_HOST_SDHCI_CQHCI_H__
++#define __MMC_HOST_SDHCI_CQHCI_H__
++
++#include "cqhci.h"
++#include "sdhci.h"
++
++static inline void sdhci_and_cqhci_reset(struct sdhci_host *host, u8 mask)
++{
++ if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) &&
++ host->mmc->cqe_private)
++ cqhci_deactivate(host->mmc);
++
++ sdhci_reset(host, mask);
++}
++
++#endif /* __MMC_HOST_SDHCI_CQHCI_H__ */
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 747df79d90eef..31ea0a2fce358 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -25,6 +25,7 @@
+ #include <linux/of_device.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/pm_runtime.h>
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "sdhci-esdhc.h"
+ #include "cqhci.h"
+@@ -1288,7 +1289,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
+
+ static void esdhc_reset(struct sdhci_host *host, u8 mask)
+ {
+- sdhci_reset(host, mask);
++ sdhci_and_cqhci_reset(host, mask);
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+@@ -1671,14 +1672,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
+ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+
+- if (host->caps & MMC_CAP_8_BIT_DATA &&
++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA &&
+ imx_data->socdata->flags & ESDHC_FLAG_HS400)
+ host->mmc->caps2 |= MMC_CAP2_HS400;
+
+ if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
+ host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
+
+- if (host->caps & MMC_CAP_8_BIT_DATA &&
++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA &&
+ imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+ host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+ host->mmc_host_ops.hs400_enhanced_strobe =
+diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
+index 3997cad1f793d..cfb891430174a 100644
+--- a/drivers/mmc/host/sdhci-of-arasan.c
++++ b/drivers/mmc/host/sdhci-of-arasan.c
+@@ -25,6 +25,7 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+
+ #include "cqhci.h"
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+
+ #define SDHCI_ARASAN_VENDOR_REGISTER 0x78
+@@ -366,7 +367,7 @@ static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+
+- sdhci_reset(host, mask);
++ sdhci_and_cqhci_reset(host, mask);
+
+ if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) {
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 413925bce0ca8..c71000a07656e 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -28,6 +28,7 @@
+
+ #include <soc/tegra/common.h>
+
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "cqhci.h"
+
+@@ -367,7 +368,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
+ const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+ u32 misc_ctrl, clk_ctrl, pad_ctrl;
+
+- sdhci_reset(host, mask);
++ sdhci_and_cqhci_reset(host, mask);
+
+ if (!(mask & SDHCI_RESET_ALL))
+ return;
+diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c
+index e7ced1496a073..b82ab5f1fcf31 100644
+--- a/drivers/mmc/host/sdhci_am654.c
++++ b/drivers/mmc/host/sdhci_am654.c
+@@ -15,6 +15,7 @@
+ #include <linux/sys_soc.h>
+
+ #include "cqhci.h"
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+
+ /* CTL_CFG Registers */
+@@ -378,7 +379,7 @@ static void sdhci_am654_reset(struct sdhci_host *host, u8 mask)
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
+
+- sdhci_reset(host, mask);
++ sdhci_and_cqhci_reset(host, mask);
+
+ if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+@@ -464,7 +465,7 @@ static struct sdhci_ops sdhci_am654_ops = {
+ .set_clock = sdhci_am654_set_clock,
+ .write_b = sdhci_am654_write_b,
+ .irq = sdhci_am654_cqhci_irq,
+- .reset = sdhci_reset,
++ .reset = sdhci_and_cqhci_reset,
+ };
+
+ static const struct sdhci_pltfm_data sdhci_am654_pdata = {
+@@ -494,7 +495,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = {
+ .set_clock = sdhci_am654_set_clock,
+ .write_b = sdhci_am654_write_b,
+ .irq = sdhci_am654_cqhci_irq,
+- .reset = sdhci_reset,
++ .reset = sdhci_and_cqhci_reset,
+ };
+
+ static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
+diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
+index 3a2d109a3792f..199cb200f2bdd 100644
+--- a/drivers/net/can/at91_can.c
++++ b/drivers/net/can/at91_can.c
+@@ -452,7 +452,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ unsigned int mb, prio;
+ u32 reg_mid, reg_mcr;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ mb = get_tx_next_mb(priv);
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index d6605dbb7737b..c63f7fc1e6917 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -457,7 +457,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
+ struct c_can_tx_ring *tx_ring = &priv->tx;
+ u32 idx, obj, cmd = IF_COMM_TX;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ if (c_can_tx_busy(priv, tx_ring))
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index 0aa1af31d0fe4..0941977807761 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -813,7 +813,7 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
+ struct can327 *elm = netdev_priv(dev);
+ struct can_frame *frame = (struct can_frame *)skb->data;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ /* We shouldn't get here after a hardware fault:
+diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
+index 0b9dfc76e769c..30909f3aab576 100644
+--- a/drivers/net/can/cc770/cc770.c
++++ b/drivers/net/can/cc770/cc770.c
+@@ -429,7 +429,7 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ struct cc770_priv *priv = netdev_priv(dev);
+ unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
+index 3c18d028bd8ce..c2c51d7af1bd4 100644
+--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
+@@ -600,7 +600,7 @@ static netdev_tx_t ctucan_start_xmit(struct sk_buff *skb, struct net_device *nde
+ bool ok;
+ unsigned long flags;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (unlikely(!CTU_CAN_FD_TXTNF(priv))) {
+diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
+index 07e0feac86292..3f37149d2c7aa 100644
+--- a/drivers/net/can/dev/skb.c
++++ b/drivers/net/can/dev/skb.c
+@@ -5,7 +5,6 @@
+ */
+
+ #include <linux/can/dev.h>
+-#include <linux/can/netlink.h>
+ #include <linux/module.h>
+
+ #define MOD_DESC "CAN device driver interface"
+@@ -300,7 +299,6 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
+ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
+ {
+ const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+- struct can_priv *priv = netdev_priv(dev);
+
+ if (skb->protocol == htons(ETH_P_CAN)) {
+ if (unlikely(skb->len != CAN_MTU ||
+@@ -314,13 +312,8 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
+ goto inval_skb;
+ }
+
+- if (!can_skb_headroom_valid(dev, skb)) {
+- goto inval_skb;
+- } else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+- netdev_info_once(dev,
+- "interface in listen only mode, dropping skb\n");
++ if (!can_skb_headroom_valid(dev, skb))
+ goto inval_skb;
+- }
+
+ return false;
+
+diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
+index ccb438eca517d..1fcc65350f102 100644
+--- a/drivers/net/can/flexcan/flexcan-core.c
++++ b/drivers/net/can/flexcan/flexcan-core.c
+@@ -742,7 +742,7 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
+ u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16);
+ int i;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
+index 6c37aab93eb3a..4bedcc3eea0d6 100644
+--- a/drivers/net/can/grcan.c
++++ b/drivers/net/can/grcan.c
+@@ -1345,7 +1345,7 @@ static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+ unsigned long flags;
+ u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ /* Trying to transmit in silent mode will generate error interrupts, but
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index ad7a89b95da71..78b6e31487cff 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -860,7 +860,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb,
+ u32 txst, txid, txdlc;
+ int i;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ /* Check if the TX buffer is full */
+diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
+index 71a2caae07579..0732a50921418 100644
+--- a/drivers/net/can/janz-ican3.c
++++ b/drivers/net/can/janz-ican3.c
+@@ -1693,7 +1693,7 @@ static netdev_tx_t ican3_xmit(struct sk_buff *skb, struct net_device *ndev)
+ void __iomem *desc_addr;
+ unsigned long flags;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ spin_lock_irqsave(&mod->lock, flags);
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index ed54c0b3c7d46..e7cc499c17733 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -775,7 +775,7 @@ static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb,
+ int nwords;
+ u8 count;
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb);
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 4709c012b1dc9..4dc67fdfcdb9d 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1722,7 +1722,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
+ {
+ struct m_can_classdev *cdev = netdev_priv(dev);
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ if (cdev->is_peripheral) {
+diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
+index 2119fbb287efc..a6829cdc0e81f 100644
+--- a/drivers/net/can/mscan/mscan.c
++++ b/drivers/net/can/mscan/mscan.c
+@@ -191,7 +191,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ int i, rtr, buf_id;
+ u32 can_id;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ out_8(®s->cantier, 0);
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index 0558ff67ec6ab..2a44b2803e555 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -882,7 +882,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
+ int i;
+ u32 id2;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ tx_obj_no = priv->tx_obj;
+diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
+index f8420cc1d9075..31c9c127e24bb 100644
+--- a/drivers/net/can/peak_canfd/peak_canfd.c
++++ b/drivers/net/can/peak_canfd/peak_canfd.c
+@@ -651,7 +651,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
+ int room_left;
+ u8 len;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ msg_size = ALIGN(sizeof(*msg) + cf->len, 4);
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 6ee968c59ac90..cc43c9c5e38c5 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -590,7 +590,7 @@ static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 data, i;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index d77c8d6d191a6..26ba650a8cbc2 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -81,8 +81,7 @@ enum rcanfd_chip_id {
+
+ /* RSCFDnCFDGERFL / RSCFDnGERFL */
+ #define RCANFD_GERFL_EEF0_7 GENMASK(23, 16)
+-#define RCANFD_GERFL_EEF1 BIT(17)
+-#define RCANFD_GERFL_EEF0 BIT(16)
++#define RCANFD_GERFL_EEF(ch) BIT(16 + (ch))
+ #define RCANFD_GERFL_CMPOF BIT(3) /* CAN FD only */
+ #define RCANFD_GERFL_THLES BIT(2)
+ #define RCANFD_GERFL_MES BIT(1)
+@@ -90,7 +89,7 @@ enum rcanfd_chip_id {
+
+ #define RCANFD_GERFL_ERR(gpriv, x) \
+ ((x) & (reg_v3u(gpriv, RCANFD_GERFL_EEF0_7, \
+- RCANFD_GERFL_EEF0 | RCANFD_GERFL_EEF1) | \
++ RCANFD_GERFL_EEF(0) | RCANFD_GERFL_EEF(1)) | \
+ RCANFD_GERFL_MES | \
+ ((gpriv)->fdmode ? RCANFD_GERFL_CMPOF : 0)))
+
+@@ -936,12 +935,8 @@ static void rcar_canfd_global_error(struct net_device *ndev)
+ u32 ridx = ch + RCANFD_RFFIFO_IDX;
+
+ gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL);
+- if ((gerfl & RCANFD_GERFL_EEF0) && (ch == 0)) {
+- netdev_dbg(ndev, "Ch0: ECC Error flag\n");
+- stats->tx_dropped++;
+- }
+- if ((gerfl & RCANFD_GERFL_EEF1) && (ch == 1)) {
+- netdev_dbg(ndev, "Ch1: ECC Error flag\n");
++ if (gerfl & RCANFD_GERFL_EEF(ch)) {
++ netdev_dbg(ndev, "Ch%u: ECC Error flag\n", ch);
+ stats->tx_dropped++;
+ }
+ if (gerfl & RCANFD_GERFL_MES) {
+@@ -1481,7 +1476,7 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb,
+ unsigned long flags;
+ u32 ch = priv->channel;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (cf->can_id & CAN_EFF_FLAG) {
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index 98dfd5f295a71..a0a820174a00f 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -291,7 +291,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
+ u8 cmd_reg_val = 0x00;
+ int i;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
+index 8d13fdf8c28a4..fbb34139daa1a 100644
+--- a/drivers/net/can/slcan/slcan-core.c
++++ b/drivers/net/can/slcan/slcan-core.c
+@@ -594,7 +594,7 @@ static netdev_tx_t slcan_netdev_xmit(struct sk_buff *skb,
+ {
+ struct slcan *sl = netdev_priv(dev);
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ spin_lock(&sl->lock);
+diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
+index a5ef57f415f73..c72f505d29fee 100644
+--- a/drivers/net/can/softing/softing_main.c
++++ b/drivers/net/can/softing/softing_main.c
+@@ -60,7 +60,7 @@ static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ uint8_t buf[DPRAM_TX_SIZE];
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ spin_lock(&card->spin);
+diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
+index b87dc420428d9..e1b8533a602e2 100644
+--- a/drivers/net/can/spi/hi311x.c
++++ b/drivers/net/can/spi/hi311x.c
+@@ -373,7 +373,7 @@ static netdev_tx_t hi3110_hard_start_xmit(struct sk_buff *skb,
+ return NETDEV_TX_BUSY;
+ }
+
+- if (can_dropped_invalid_skb(net, skb))
++ if (can_dev_dropped_skb(net, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(net);
+diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
+index 24883a65ca66a..79c4bab5f7246 100644
+--- a/drivers/net/can/spi/mcp251x.c
++++ b/drivers/net/can/spi/mcp251x.c
+@@ -789,7 +789,7 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+ return NETDEV_TX_BUSY;
+ }
+
+- if (can_dropped_invalid_skb(net, skb))
++ if (can_dev_dropped_skb(net, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(net);
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
+index ffb6c36b7d9bd..160528d3cc26b 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
+@@ -172,7 +172,7 @@ netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
+ u8 tx_head;
+ int err;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (mcp251xfd_tx_busy(priv, tx_ring))
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index 525309da1320a..2b78f9197681b 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -429,7 +429,7 @@ static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *d
+ canid_t id;
+ int i;
+
+- if (can_dropped_invalid_skb(dev, skb))
++ if (can_dev_dropped_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
+index b218fb3c6b760..27700f72eac25 100644
+--- a/drivers/net/can/ti_hecc.c
++++ b/drivers/net/can/ti_hecc.c
+@@ -470,7 +470,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
+ u32 mbxno, mbx_mask, data;
+ unsigned long flags;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ mbxno = get_tx_head_mb(priv);
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index d31191686a549..050c0b49938a4 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -747,7 +747,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
+ size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
+ + sizeof(struct cpc_can_msg);
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
+index 1bcfad11b1e44..81b88e9e5bdc0 100644
+--- a/drivers/net/can/usb/esd_usb.c
++++ b/drivers/net/can/usb/esd_usb.c
+@@ -725,7 +725,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
+ int ret = NETDEV_TX_OK;
+ size_t size = sizeof(struct esd_usb_msg);
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 51294b7170405..25f863b4f5f06 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -1913,7 +1913,7 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
+ unsigned int frame_len;
+ int ret;
+
+- if (can_dropped_invalid_skb(netdev, skb)) {
++ if (can_dev_dropped_skb(netdev, skb)) {
+ if (priv->tx_urb)
+ goto xmit_commit;
+ return NETDEV_TX_OK;
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index c1ff3c046d62c..cd4115a1b81c6 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -605,7 +605,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ unsigned int idx;
+ struct gs_tx_context *txc;
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* find an empty context to keep track of transmission */
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index e91648ed73862..802e27c0ecedb 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -570,7 +570,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
+ unsigned int i;
+ unsigned long flags;
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
+index 69346c63021fe..218b098b261df 100644
+--- a/drivers/net/can/usb/mcba_usb.c
++++ b/drivers/net/can/usb/mcba_usb.c
+@@ -311,7 +311,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
+ .cmd_id = MBCA_CMD_TRANSMIT_MESSAGE_EV
+ };
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ ctx = mcba_usb_get_free_ctx(priv, cf);
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index 8c9d53f6e24c3..ca92d027ba3ef 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -351,7 +351,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,
+ int i, err;
+ size_t size = dev->adapter->tx_buffer_size;
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++)
+diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
+index 7c35f50fda4ee..67c2ff407d066 100644
+--- a/drivers/net/can/usb/ucan.c
++++ b/drivers/net/can/usb/ucan.c
+@@ -1120,7 +1120,7 @@ static netdev_tx_t ucan_start_xmit(struct sk_buff *skb,
+ struct can_frame *cf = (struct can_frame *)skb->data;
+
+ /* check skb */
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* allocate a context and slow down tx path, if fifo state is low */
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index 64c00abe91cf0..8a5596ce4e463 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -602,7 +602,7 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
+ int i, err;
+ size_t size = sizeof(struct usb_8dev_tx_msg);
+
+- if (can_dropped_invalid_skb(netdev, skb))
++ if (can_dev_dropped_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
+index 5d3172795ad01..43c812ea1de02 100644
+--- a/drivers/net/can/xilinx_can.c
++++ b/drivers/net/can/xilinx_can.c
+@@ -743,7 +743,7 @@ static netdev_tx_t xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ struct xcan_priv *priv = netdev_priv(ndev);
+ int ret;
+
+- if (can_dropped_invalid_skb(ndev, skb))
++ if (can_dev_dropped_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES)
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+index 53dc8d5fede86..c51d9edb3828a 100644
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+@@ -1004,8 +1004,10 @@ static int xgene_enet_open(struct net_device *ndev)
+
+ xgene_enet_napi_enable(pdata);
+ ret = xgene_enet_register_irq(ndev);
+- if (ret)
++ if (ret) {
++ xgene_enet_napi_disable(pdata);
+ return ret;
++ }
+
+ if (ndev->phydev) {
+ phy_start(ndev->phydev);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+index 8b53d6688a4bd..958b7f8c77d91 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+@@ -585,6 +585,7 @@ static int aq_update_txsa(struct aq_nic_s *nic, const unsigned int sc_idx,
+
+ ret = aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx);
+
++ memzero_explicit(&key_rec, sizeof(key_rec));
+ return ret;
+ }
+
+@@ -932,6 +933,7 @@ static int aq_update_rxsa(struct aq_nic_s *nic, const unsigned int sc_idx,
+
+ ret = aq_mss_set_ingress_sakey_record(hw, &sa_key_record, sa_idx);
+
++ memzero_explicit(&sa_key_record, sizeof(sa_key_record));
+ return ret;
+ }
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c b/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
+index 36c7cf05630a1..4319249595207 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
++++ b/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
+@@ -757,6 +757,7 @@ set_ingress_sakey_record(struct aq_hw_s *hw,
+ u16 table_index)
+ {
+ u16 packed_record[18];
++ int ret;
+
+ if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
+ return -EINVAL;
+@@ -789,9 +790,12 @@ set_ingress_sakey_record(struct aq_hw_s *hw,
+
+ packed_record[16] = rec->key_len & 0x3;
+
+- return set_raw_ingress_record(hw, packed_record, 18, 2,
+- ROWOFFSET_INGRESSSAKEYRECORD +
+- table_index);
++ ret = set_raw_ingress_record(hw, packed_record, 18, 2,
++ ROWOFFSET_INGRESSSAKEYRECORD +
++ table_index);
++
++ memzero_explicit(packed_record, sizeof(packed_record));
++ return ret;
+ }
+
+ int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw,
+@@ -1739,14 +1743,14 @@ static int set_egress_sakey_record(struct aq_hw_s *hw,
+ ret = set_raw_egress_record(hw, packed_record, 8, 2,
+ ROWOFFSET_EGRESSSAKEYRECORD + table_index);
+ if (unlikely(ret))
+- return ret;
++ goto clear_key;
+ ret = set_raw_egress_record(hw, packed_record + 8, 8, 2,
+ ROWOFFSET_EGRESSSAKEYRECORD + table_index -
+ 32);
+- if (unlikely(ret))
+- return ret;
+
+- return 0;
++clear_key:
++ memzero_explicit(packed_record, sizeof(packed_record));
++ return ret;
+ }
+
+ int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw,
+diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
+index 56e0fb07aec7f..1cd3c289f49be 100644
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -77,7 +77,7 @@ config BCMGENET
+ select BCM7XXX_PHY
+ select MDIO_BCM_UNIMAC
+ select DIMLIB
+- select BROADCOM_PHY if ARCH_BCM2835
++ select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL)
+ help
+ This driver supports the built-in Ethernet MACs found in the
+ Broadcom BCM7xxx Set Top Box family chipset.
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 96da0ba3d5078..be5df8fca264e 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12894,8 +12894,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(fltr, head, hash) {
+ if (bnxt_fltr_match(fltr, new_fltr)) {
++ rc = fltr->sw_id;
+ rcu_read_unlock();
+- rc = 0;
+ goto err_free;
+ }
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 87eb5362ad70a..a182254569661 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -162,7 +162,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
+ }
+
+ reset_coalesce:
+- if (netif_running(dev)) {
++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) {
+ if (update_stats) {
+ rc = bnxt_close_nic(bp, true, false);
+ if (!rc)
+diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+index 174b1e156669e..481d85bfa483f 100644
+--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+@@ -1302,6 +1302,7 @@ static int cxgb_up(struct adapter *adap)
+ if (ret < 0) {
+ CH_ERR(adap, "failed to bind qsets, err %d\n", ret);
+ t3_intr_disable(adap);
++ quiesce_rx(adap);
+ free_irq_resources(adap);
+ err = ret;
+ goto out;
+diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+index c2822e635f896..40bb473ec3c89 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+@@ -858,7 +858,7 @@ static int cxgb4vf_open(struct net_device *dev)
+ */
+ err = t4vf_update_port_info(pi);
+ if (err < 0)
+- return err;
++ goto err_unwind;
+
+ /*
+ * Note that this interface is up and start everything up ...
+diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
+index 39ae965cd4f64..b0c756b65cc2e 100644
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -882,12 +882,21 @@ _return:
+ return err;
+ }
+
++static int mac_remove(struct platform_device *pdev)
++{
++ struct mac_device *mac_dev = platform_get_drvdata(pdev);
++
++ platform_device_unregister(mac_dev->priv->eth_dev);
++ return 0;
++}
++
+ static struct platform_driver mac_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = mac_match,
+ },
+ .probe = mac_probe,
++ .remove = mac_remove,
+ };
+
+ builtin_platform_driver(mac_driver);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index 5a9e6563923eb..24a701fd140e9 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -2438,6 +2438,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ list_for_each_entry(f, &adapter->vlan_filter_list, list) {
+ if (f->is_new_vlan) {
+ f->is_new_vlan = false;
++ if (!f->vlan.vid)
++ continue;
+ if (f->vlan.tpid == ETH_P_8021Q)
+ set_bit(f->vlan.vid,
+ adapter->vsi.active_cvlans);
+diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c
+index 1e32438081780..9ee022bb8ec21 100644
+--- a/drivers/net/ethernet/intel/ice/ice_base.c
++++ b/drivers/net/ethernet/intel/ice/ice_base.c
+@@ -959,7 +959,7 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
+ * associated to the queue to schedule NAPI handler
+ */
+ q_vector = ring->q_vector;
+- if (q_vector)
++ if (q_vector && !(vsi->vf && ice_is_vf_disabled(vsi->vf)))
+ ice_trigger_sw_intr(hw, q_vector);
+
+ status = ice_dis_vsi_txq(vsi->port_info, txq_meta->vsi_idx,
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 58d483e2f539e..11399f55e6476 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2222,6 +2222,31 @@ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi)
+ return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings, vsi->num_xdp_txq);
+ }
+
++/**
++ * ice_vsi_is_rx_queue_active
++ * @vsi: the VSI being configured
++ *
++ * Return true if at least one queue is active.
++ */
++bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi)
++{
++ struct ice_pf *pf = vsi->back;
++ struct ice_hw *hw = &pf->hw;
++ int i;
++
++ ice_for_each_rxq(vsi, i) {
++ u32 rx_reg;
++ int pf_q;
++
++ pf_q = vsi->rxq_map[i];
++ rx_reg = rd32(hw, QRX_CTRL(pf_q));
++ if (rx_reg & QRX_CTRL_QENA_STAT_M)
++ return true;
++ }
++
++ return false;
++}
++
+ /**
+ * ice_vsi_is_vlan_pruning_ena - check if VLAN pruning is enabled or not
+ * @vsi: VSI to check whether or not VLAN pruning is enabled.
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
+index 8712b1d2ceec9..441fb132f1941 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_lib.h
+@@ -127,4 +127,5 @@ u16 ice_vsi_num_non_zero_vlans(struct ice_vsi *vsi);
+ bool ice_is_feature_supported(struct ice_pf *pf, enum ice_feature f);
+ void ice_clear_feature_support(struct ice_pf *pf, enum ice_feature f);
+ void ice_init_feature_support(struct ice_pf *pf);
++bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi);
+ #endif /* !_ICE_LIB_H_ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+index 0abeed092de1d..1c51778db951b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+@@ -576,7 +576,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
+ return -EINVAL;
+ }
+ ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
+- ice_vsi_stop_all_rx_rings(vsi);
++
++ if (ice_vsi_is_rx_queue_active(vsi))
++ ice_vsi_stop_all_rx_rings(vsi);
++
+ dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
+ vf->vf_id);
+ return 0;
+diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
+index b6be0552a6c1d..40a5957b14493 100644
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2481,6 +2481,7 @@ out_free:
+ for (i = 0; i < mp->rxq_count; i++)
+ rxq_deinit(mp->rxq + i);
+ out:
++ napi_disable(&mp->napi);
+ free_irq(dev->irq, dev);
+
+ return err;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index d686c7b6252f4..9c2baa437c231 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -863,6 +863,7 @@ static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
+ }
+
+ sq->head = 0;
++ sq->cons_head = 0;
+ sq->sqe_per_sqb = (pfvf->hw.sqb_size / sq->sqe_size) - 1;
+ sq->num_sqbs = (qset->sqe_cnt + sq->sqe_per_sqb) / sq->sqe_per_sqb;
+ /* Set SQE threshold to 10% of total SQEs */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 9376d0e62914b..80fde101df96d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -15,6 +15,7 @@
+ #include <net/ip.h>
+ #include <linux/bpf.h>
+ #include <linux/bpf_trace.h>
++#include <linux/bitfield.h>
+
+ #include "otx2_reg.h"
+ #include "otx2_common.h"
+@@ -1161,6 +1162,59 @@ int otx2_set_real_num_queues(struct net_device *netdev,
+ }
+ EXPORT_SYMBOL(otx2_set_real_num_queues);
+
++static char *nix_sqoperr_e_str[NIX_SQOPERR_MAX] = {
++ "NIX_SQOPERR_OOR",
++ "NIX_SQOPERR_CTX_FAULT",
++ "NIX_SQOPERR_CTX_POISON",
++ "NIX_SQOPERR_DISABLED",
++ "NIX_SQOPERR_SIZE_ERR",
++ "NIX_SQOPERR_OFLOW",
++ "NIX_SQOPERR_SQB_NULL",
++ "NIX_SQOPERR_SQB_FAULT",
++ "NIX_SQOPERR_SQE_SZ_ZERO",
++};
++
++static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = {
++ "NIX_MNQERR_SQ_CTX_FAULT",
++ "NIX_MNQERR_SQ_CTX_POISON",
++ "NIX_MNQERR_SQB_FAULT",
++ "NIX_MNQERR_SQB_POISON",
++ "NIX_MNQERR_TOTAL_ERR",
++ "NIX_MNQERR_LSO_ERR",
++ "NIX_MNQERR_CQ_QUERY_ERR",
++ "NIX_MNQERR_MAX_SQE_SIZE_ERR",
++ "NIX_MNQERR_MAXLEN_ERR",
++ "NIX_MNQERR_SQE_SIZEM1_ZERO",
++};
++
++static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] = {
++ "NIX_SND_STATUS_GOOD",
++ "NIX_SND_STATUS_SQ_CTX_FAULT",
++ "NIX_SND_STATUS_SQ_CTX_POISON",
++ "NIX_SND_STATUS_SQB_FAULT",
++ "NIX_SND_STATUS_SQB_POISON",
++ "NIX_SND_STATUS_HDR_ERR",
++ "NIX_SND_STATUS_EXT_ERR",
++ "NIX_SND_STATUS_JUMP_FAULT",
++ "NIX_SND_STATUS_JUMP_POISON",
++ "NIX_SND_STATUS_CRC_ERR",
++ "NIX_SND_STATUS_IMM_ERR",
++ "NIX_SND_STATUS_SG_ERR",
++ "NIX_SND_STATUS_MEM_ERR",
++ "NIX_SND_STATUS_INVALID_SUBDC",
++ "NIX_SND_STATUS_SUBDC_ORDER_ERR",
++ "NIX_SND_STATUS_DATA_FAULT",
++ "NIX_SND_STATUS_DATA_POISON",
++ "NIX_SND_STATUS_NPC_DROP_ACTION",
++ "NIX_SND_STATUS_LOCK_VIOL",
++ "NIX_SND_STATUS_NPC_UCAST_CHAN_ERR",
++ "NIX_SND_STATUS_NPC_MCAST_CHAN_ERR",
++ "NIX_SND_STATUS_NPC_MCAST_ABORT",
++ "NIX_SND_STATUS_NPC_VTAG_PTR_ERR",
++ "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR",
++ "NIX_SND_STATUS_SEND_STATS_ERR",
++};
++
+ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
+ {
+ struct otx2_nic *pf = data;
+@@ -1194,46 +1248,67 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
+
+ /* SQ */
+ for (qidx = 0; qidx < pf->hw.tot_tx_queues; qidx++) {
++ u64 sq_op_err_dbg, mnq_err_dbg, snd_err_dbg;
++ u8 sq_op_err_code, mnq_err_code, snd_err_code;
++
++ /* Below debug registers captures first errors corresponding to
++ * those registers. We don't have to check against SQ qid as
++ * these are fatal errors.
++ */
++
+ ptr = otx2_get_regaddr(pf, NIX_LF_SQ_OP_INT);
+ val = otx2_atomic64_add((qidx << 44), ptr);
+ otx2_write64(pf, NIX_LF_SQ_OP_INT, (qidx << 44) |
+ (val & NIX_SQINT_BITS));
+
+- if (!(val & (NIX_SQINT_BITS | BIT_ULL(42))))
+- continue;
+-
+ if (val & BIT_ULL(42)) {
+ netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
+ qidx, otx2_read64(pf, NIX_LF_ERR_INT));
+- } else {
+- if (val & BIT_ULL(NIX_SQINT_LMT_ERR)) {
+- netdev_err(pf->netdev, "SQ%lld: LMT store error NIX_LF_SQ_OP_ERR_DBG:0x%llx",
+- qidx,
+- otx2_read64(pf,
+- NIX_LF_SQ_OP_ERR_DBG));
+- otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG,
+- BIT_ULL(44));
+- }
+- if (val & BIT_ULL(NIX_SQINT_MNQ_ERR)) {
+- netdev_err(pf->netdev, "SQ%lld: Meta-descriptor enqueue error NIX_LF_MNQ_ERR_DGB:0x%llx\n",
+- qidx,
+- otx2_read64(pf, NIX_LF_MNQ_ERR_DBG));
+- otx2_write64(pf, NIX_LF_MNQ_ERR_DBG,
+- BIT_ULL(44));
+- }
+- if (val & BIT_ULL(NIX_SQINT_SEND_ERR)) {
+- netdev_err(pf->netdev, "SQ%lld: Send error, NIX_LF_SEND_ERR_DBG 0x%llx",
+- qidx,
+- otx2_read64(pf,
+- NIX_LF_SEND_ERR_DBG));
+- otx2_write64(pf, NIX_LF_SEND_ERR_DBG,
+- BIT_ULL(44));
+- }
+- if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
+- netdev_err(pf->netdev, "SQ%lld: SQB allocation failed",
+- qidx);
++ goto done;
+ }
+
++ sq_op_err_dbg = otx2_read64(pf, NIX_LF_SQ_OP_ERR_DBG);
++ if (!(sq_op_err_dbg & BIT(44)))
++ goto chk_mnq_err_dbg;
++
++ sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg);
++ netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx) err=%s\n",
++ qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]);
++
++ otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44));
++
++ if (sq_op_err_code == NIX_SQOPERR_SQB_NULL)
++ goto chk_mnq_err_dbg;
++
++ /* Err is not NIX_SQOPERR_SQB_NULL, call aq function to read SQ structure.
++ * TODO: But we are in irq context. How to call mbox functions which does sleep
++ */
++
++chk_mnq_err_dbg:
++ mnq_err_dbg = otx2_read64(pf, NIX_LF_MNQ_ERR_DBG);
++ if (!(mnq_err_dbg & BIT(44)))
++ goto chk_snd_err_dbg;
++
++ mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg);
++ netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx) err=%s\n",
++ qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code]);
++ otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44));
++
++chk_snd_err_dbg:
++ snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG);
++ if (snd_err_dbg & BIT(44)) {
++ snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg);
++ netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n",
++ qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]);
++ otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44));
++ }
++
++done:
++ /* Print values and reset */
++ if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
++ netdev_err(pf->netdev, "SQ%lld: SQB allocation failed",
++ qidx);
++
+ schedule_work(&pf->reset_task);
+ }
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
+index 4bbd12ff26e64..e5f30fd778fc1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
+@@ -274,4 +274,61 @@ enum nix_sqint_e {
+ BIT_ULL(NIX_SQINT_SEND_ERR) | \
+ BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
+
++enum nix_sqoperr_e {
++ NIX_SQOPERR_OOR = 0,
++ NIX_SQOPERR_CTX_FAULT = 1,
++ NIX_SQOPERR_CTX_POISON = 2,
++ NIX_SQOPERR_DISABLED = 3,
++ NIX_SQOPERR_SIZE_ERR = 4,
++ NIX_SQOPERR_OFLOW = 5,
++ NIX_SQOPERR_SQB_NULL = 6,
++ NIX_SQOPERR_SQB_FAULT = 7,
++ NIX_SQOPERR_SQE_SZ_ZERO = 8,
++ NIX_SQOPERR_MAX,
++};
++
++enum nix_mnqerr_e {
++ NIX_MNQERR_SQ_CTX_FAULT = 0,
++ NIX_MNQERR_SQ_CTX_POISON = 1,
++ NIX_MNQERR_SQB_FAULT = 2,
++ NIX_MNQERR_SQB_POISON = 3,
++ NIX_MNQERR_TOTAL_ERR = 4,
++ NIX_MNQERR_LSO_ERR = 5,
++ NIX_MNQERR_CQ_QUERY_ERR = 6,
++ NIX_MNQERR_MAX_SQE_SIZE_ERR = 7,
++ NIX_MNQERR_MAXLEN_ERR = 8,
++ NIX_MNQERR_SQE_SIZEM1_ZERO = 9,
++ NIX_MNQERR_MAX,
++};
++
++enum nix_snd_status_e {
++ NIX_SND_STATUS_GOOD = 0x0,
++ NIX_SND_STATUS_SQ_CTX_FAULT = 0x1,
++ NIX_SND_STATUS_SQ_CTX_POISON = 0x2,
++ NIX_SND_STATUS_SQB_FAULT = 0x3,
++ NIX_SND_STATUS_SQB_POISON = 0x4,
++ NIX_SND_STATUS_HDR_ERR = 0x5,
++ NIX_SND_STATUS_EXT_ERR = 0x6,
++ NIX_SND_STATUS_JUMP_FAULT = 0x7,
++ NIX_SND_STATUS_JUMP_POISON = 0x8,
++ NIX_SND_STATUS_CRC_ERR = 0x9,
++ NIX_SND_STATUS_IMM_ERR = 0x10,
++ NIX_SND_STATUS_SG_ERR = 0x11,
++ NIX_SND_STATUS_MEM_ERR = 0x12,
++ NIX_SND_STATUS_INVALID_SUBDC = 0x13,
++ NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14,
++ NIX_SND_STATUS_DATA_FAULT = 0x15,
++ NIX_SND_STATUS_DATA_POISON = 0x16,
++ NIX_SND_STATUS_NPC_DROP_ACTION = 0x17,
++ NIX_SND_STATUS_LOCK_VIOL = 0x18,
++ NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19,
++ NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20,
++ NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21,
++ NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22,
++ NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23,
++ NIX_SND_STATUS_SEND_MEM_FAULT = 0x24,
++ NIX_SND_STATUS_SEND_STATS_ERR = 0x25,
++ NIX_SND_STATUS_MAX,
++};
++
+ #endif /* OTX2_STRUCT_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+index a18e8efd0f1ee..664f977433f4a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+@@ -435,6 +435,7 @@ static int otx2_tx_napi_handler(struct otx2_nic *pfvf,
+ struct otx2_cq_queue *cq, int budget)
+ {
+ int tx_pkts = 0, tx_bytes = 0, qidx;
++ struct otx2_snd_queue *sq;
+ struct nix_cqe_tx_s *cqe;
+ int processed_cqe = 0;
+
+@@ -445,6 +446,9 @@ static int otx2_tx_napi_handler(struct otx2_nic *pfvf,
+ return 0;
+
+ process_cqe:
++ qidx = cq->cq_idx - pfvf->hw.rx_queues;
++ sq = &pfvf->qset.sq[qidx];
++
+ while (likely(processed_cqe < budget) && cq->pend_cqe) {
+ cqe = (struct nix_cqe_tx_s *)otx2_get_next_cqe(cq);
+ if (unlikely(!cqe)) {
+@@ -452,18 +456,20 @@ process_cqe:
+ return 0;
+ break;
+ }
++
+ if (cq->cq_type == CQ_XDP) {
+- qidx = cq->cq_idx - pfvf->hw.rx_queues;
+- otx2_xdp_snd_pkt_handler(pfvf, &pfvf->qset.sq[qidx],
+- cqe);
++ otx2_xdp_snd_pkt_handler(pfvf, sq, cqe);
+ } else {
+- otx2_snd_pkt_handler(pfvf, cq,
+- &pfvf->qset.sq[cq->cint_idx],
+- cqe, budget, &tx_pkts, &tx_bytes);
++ otx2_snd_pkt_handler(pfvf, cq, sq, cqe, budget,
++ &tx_pkts, &tx_bytes);
+ }
++
+ cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID;
+ processed_cqe++;
+ cq->pend_cqe--;
++
++ sq->cons_head++;
++ sq->cons_head &= (sq->sqe_cnt - 1);
+ }
+
+ /* Free CQEs to HW */
+@@ -972,17 +978,17 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq,
+ {
+ struct netdev_queue *txq = netdev_get_tx_queue(netdev, qidx);
+ struct otx2_nic *pfvf = netdev_priv(netdev);
+- int offset, num_segs, free_sqe;
++ int offset, num_segs, free_desc;
+ struct nix_sqe_hdr_s *sqe_hdr;
+
+- /* Check if there is room for new SQE.
+- * 'Num of SQBs freed to SQ's pool - SQ's Aura count'
+- * will give free SQE count.
++ /* Check if there is enough room between producer
++ * and consumer index.
+ */
+- free_sqe = (sq->num_sqbs - *sq->aura_fc_addr) * sq->sqe_per_sqb;
++ free_desc = (sq->cons_head - sq->head - 1 + sq->sqe_cnt) & (sq->sqe_cnt - 1);
++ if (free_desc < sq->sqe_thresh)
++ return false;
+
+- if (free_sqe < sq->sqe_thresh ||
+- free_sqe < otx2_get_sqe_count(pfvf, skb))
++ if (free_desc < otx2_get_sqe_count(pfvf, skb))
+ return false;
+
+ num_segs = skb_shinfo(skb)->nr_frags + 1;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+index fbe62bbfb789a..93cac2c2664c2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+@@ -79,6 +79,7 @@ struct sg_list {
+ struct otx2_snd_queue {
+ u8 aura_id;
+ u16 head;
++ u16 cons_head;
+ u16 sqe_size;
+ u32 sqe_cnt;
+ u16 num_sqbs;
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
+index dc3e3ddc60bf5..faa5109a09d7a 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
+@@ -776,6 +776,7 @@ tx_done:
+ int prestera_rxtx_switch_init(struct prestera_switch *sw)
+ {
+ struct prestera_rxtx *rxtx;
++ int err;
+
+ rxtx = kzalloc(sizeof(*rxtx), GFP_KERNEL);
+ if (!rxtx)
+@@ -783,7 +784,11 @@ int prestera_rxtx_switch_init(struct prestera_switch *sw)
+
+ sw->rxtx = rxtx;
+
+- return prestera_sdma_switch_init(sw);
++ err = prestera_sdma_switch_init(sw);
++ if (err)
++ kfree(rxtx);
++
++ return err;
+ }
+
+ void prestera_rxtx_switch_fini(struct prestera_switch *sw)
+diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+index 3f0e5e64de505..57f4373b30ba1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+@@ -1026,6 +1026,8 @@ static int mtk_star_enable(struct net_device *ndev)
+ return 0;
+
+ err_free_irq:
++ napi_disable(&priv->rx_napi);
++ napi_disable(&priv->tx_napi);
+ free_irq(ndev->irq, ndev);
+ err_free_skbs:
+ mtk_star_free_rx_skbs(priv);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 46ba4c2faad21..2e0d59ca62b50 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -1770,12 +1770,17 @@ void mlx5_cmd_flush(struct mlx5_core_dev *dev)
+ struct mlx5_cmd *cmd = &dev->cmd;
+ int i;
+
+- for (i = 0; i < cmd->max_reg_cmds; i++)
+- while (down_trylock(&cmd->sem))
++ for (i = 0; i < cmd->max_reg_cmds; i++) {
++ while (down_trylock(&cmd->sem)) {
+ mlx5_cmd_trigger_completions(dev);
++ cond_resched();
++ }
++ }
+
+- while (down_trylock(&cmd->pages_sem))
++ while (down_trylock(&cmd->pages_sem)) {
+ mlx5_cmd_trigger_completions(dev);
++ cond_resched();
++ }
+
+ /* Unlock cmdif */
+ up(&cmd->pages_sem);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+index 39ef2a2561a30..8099a21e674c9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+@@ -164,6 +164,36 @@ static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr
+ return err;
+ }
+
++static int
++mlx5_esw_bridge_changeupper_validate_netdev(void *ptr)
++{
++ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++ struct netdev_notifier_changeupper_info *info = ptr;
++ struct net_device *upper = info->upper_dev;
++ struct net_device *lower;
++ struct list_head *iter;
++
++ if (!netif_is_bridge_master(upper) || !netif_is_lag_master(dev))
++ return 0;
++
++ netdev_for_each_lower_dev(dev, lower, iter) {
++ struct mlx5_core_dev *mdev;
++ struct mlx5e_priv *priv;
++
++ if (!mlx5e_eswitch_rep(lower))
++ continue;
++
++ priv = netdev_priv(lower);
++ mdev = priv->mdev;
++ if (!mlx5_lag_is_active(mdev))
++ return -EAGAIN;
++ if (!mlx5_lag_is_shared_fdb(mdev))
++ return -EOPNOTSUPP;
++ }
++
++ return 0;
++}
++
+ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+ {
+@@ -171,6 +201,7 @@ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
+
+ switch (event) {
+ case NETDEV_PRECHANGEUPPER:
++ err = mlx5_esw_bridge_changeupper_validate_netdev(ptr);
+ break;
+
+ case NETDEV_CHANGEUPPER:
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
+index 305fde62a78de..3337241cfd84c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
+@@ -6,70 +6,42 @@
+ #include "en/tc_priv.h"
+ #include "mlx5_core.h"
+
+-/* Must be aligned with enum flow_action_id. */
+ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
+- &mlx5e_tc_act_accept,
+- &mlx5e_tc_act_drop,
+- &mlx5e_tc_act_trap,
+- &mlx5e_tc_act_goto,
+- &mlx5e_tc_act_mirred,
+- &mlx5e_tc_act_mirred,
+- &mlx5e_tc_act_redirect_ingress,
+- NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
+- &mlx5e_tc_act_vlan,
+- &mlx5e_tc_act_vlan,
+- &mlx5e_tc_act_vlan_mangle,
+- &mlx5e_tc_act_tun_encap,
+- &mlx5e_tc_act_tun_decap,
+- &mlx5e_tc_act_pedit,
+- &mlx5e_tc_act_pedit,
+- &mlx5e_tc_act_csum,
+- NULL, /* FLOW_ACTION_MARK, */
+- &mlx5e_tc_act_ptype,
+- NULL, /* FLOW_ACTION_PRIORITY, */
+- NULL, /* FLOW_ACTION_WAKE, */
+- NULL, /* FLOW_ACTION_QUEUE, */
+- &mlx5e_tc_act_sample,
+- &mlx5e_tc_act_police,
+- &mlx5e_tc_act_ct,
+- NULL, /* FLOW_ACTION_CT_METADATA, */
+- &mlx5e_tc_act_mpls_push,
+- &mlx5e_tc_act_mpls_pop,
+- NULL, /* FLOW_ACTION_MPLS_MANGLE, */
+- NULL, /* FLOW_ACTION_GATE, */
+- NULL, /* FLOW_ACTION_PPPOE_PUSH, */
+- NULL, /* FLOW_ACTION_JUMP, */
+- NULL, /* FLOW_ACTION_PIPE, */
+- &mlx5e_tc_act_vlan,
+- &mlx5e_tc_act_vlan,
++ [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
++ [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
++ [FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap,
++ [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
++ [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred,
++ [FLOW_ACTION_MIRRED] = &mlx5e_tc_act_mirred,
++ [FLOW_ACTION_REDIRECT_INGRESS] = &mlx5e_tc_act_redirect_ingress,
++ [FLOW_ACTION_VLAN_PUSH] = &mlx5e_tc_act_vlan,
++ [FLOW_ACTION_VLAN_POP] = &mlx5e_tc_act_vlan,
++ [FLOW_ACTION_VLAN_MANGLE] = &mlx5e_tc_act_vlan_mangle,
++ [FLOW_ACTION_TUNNEL_ENCAP] = &mlx5e_tc_act_tun_encap,
++ [FLOW_ACTION_TUNNEL_DECAP] = &mlx5e_tc_act_tun_decap,
++ [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
++ [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
++ [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
++ [FLOW_ACTION_PTYPE] = &mlx5e_tc_act_ptype,
++ [FLOW_ACTION_SAMPLE] = &mlx5e_tc_act_sample,
++ [FLOW_ACTION_POLICE] = &mlx5e_tc_act_police,
++ [FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
++ [FLOW_ACTION_MPLS_PUSH] = &mlx5e_tc_act_mpls_push,
++ [FLOW_ACTION_MPLS_POP] = &mlx5e_tc_act_mpls_pop,
++ [FLOW_ACTION_VLAN_PUSH_ETH] = &mlx5e_tc_act_vlan,
++ [FLOW_ACTION_VLAN_POP_ETH] = &mlx5e_tc_act_vlan,
+ };
+
+-/* Must be aligned with enum flow_action_id. */
+ static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = {
+- &mlx5e_tc_act_accept,
+- &mlx5e_tc_act_drop,
+- NULL, /* FLOW_ACTION_TRAP, */
+- &mlx5e_tc_act_goto,
+- &mlx5e_tc_act_mirred_nic,
+- NULL, /* FLOW_ACTION_MIRRED, */
+- NULL, /* FLOW_ACTION_REDIRECT_INGRESS, */
+- NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
+- NULL, /* FLOW_ACTION_VLAN_PUSH, */
+- NULL, /* FLOW_ACTION_VLAN_POP, */
+- NULL, /* FLOW_ACTION_VLAN_MANGLE, */
+- NULL, /* FLOW_ACTION_TUNNEL_ENCAP, */
+- NULL, /* FLOW_ACTION_TUNNEL_DECAP, */
+- &mlx5e_tc_act_pedit,
+- &mlx5e_tc_act_pedit,
+- &mlx5e_tc_act_csum,
+- &mlx5e_tc_act_mark,
+- NULL, /* FLOW_ACTION_PTYPE, */
+- NULL, /* FLOW_ACTION_PRIORITY, */
+- NULL, /* FLOW_ACTION_WAKE, */
+- NULL, /* FLOW_ACTION_QUEUE, */
+- NULL, /* FLOW_ACTION_SAMPLE, */
+- NULL, /* FLOW_ACTION_POLICE, */
+- &mlx5e_tc_act_ct,
++ [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
++ [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
++ [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
++ [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred_nic,
++ [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
++ [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
++ [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
++ [FLOW_ACTION_MARK] = &mlx5e_tc_act_mark,
++ [FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
+ };
+
+ /**
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index ff8ca7a7e1036..aeed165a2dec2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -11,6 +11,27 @@
+
+ #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
+
++/* IPSEC inline data includes:
++ * 1. ESP trailer: up to 255 bytes of padding, 1 byte for pad length, 1 byte for
++ * next header.
++ * 2. ESP authentication data: 16 bytes for ICV.
++ */
++#define MLX5E_MAX_TX_IPSEC_DS DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + \
++ 255 + 1 + 1 + 16, MLX5_SEND_WQE_DS)
++
++/* 366 should be big enough to cover all L2, L3 and L4 headers with possible
++ * encapsulations.
++ */
++#define MLX5E_MAX_TX_INLINE_DS DIV_ROUND_UP(366 - INL_HDR_START_SZ + VLAN_HLEN, \
++ MLX5_SEND_WQE_DS)
++
++/* Sync the calculation with mlx5e_sq_calc_wqe_attr. */
++#define MLX5E_MAX_TX_WQEBBS DIV_ROUND_UP(MLX5E_TX_WQE_EMPTY_DS_COUNT + \
++ MLX5E_MAX_TX_INLINE_DS + \
++ MLX5E_MAX_TX_IPSEC_DS + \
++ MAX_SKB_FRAGS + 1, \
++ MLX5_SEND_WQEBB_NUM_DS)
++
+ #define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND)
+
+ static inline
+@@ -424,6 +445,8 @@ mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
+
+ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_size)
+ {
++ WARN_ON_ONCE(PAGE_SIZE / MLX5_SEND_WQE_BB < mlx5e_get_max_sq_wqebbs(mdev));
++
+ /* A WQE must not cross the page boundary, hence two conditions:
+ * 1. Its size must not exceed the page size.
+ * 2. If the WQE size is X, and the space remaining in a page is less
+@@ -436,7 +459,6 @@ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_si
+ "wqe_size %u is greater than max SQ WQEBBs %u",
+ wqe_size, mlx5e_get_max_sq_wqebbs(mdev));
+
+-
+ return MLX5E_STOP_ROOM(wqe_size);
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 02eb2f0fa2ae7..6cf6a81775a85 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -5514,6 +5514,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
+ if (priv->fs)
+ priv->fs->state_destroy = !test_bit(MLX5E_STATE_DESTROYING, &priv->state);
+
++ /* Validate the max_wqe_size_sq capability. */
++ if (WARN_ON_ONCE(mlx5e_get_max_sq_wqebbs(priv->mdev) < MLX5E_MAX_TX_WQEBBS)) {
++ mlx5_core_warn(priv->mdev, "MLX5E: Max SQ WQEBBs firmware capability: %u, needed %lu\n",
++ mlx5e_get_max_sq_wqebbs(priv->mdev), MLX5E_MAX_TX_WQEBBS);
++ return -EIO;
++ }
++
+ /* max number of channels may have changed */
+ max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile);
+ if (priv->channels.params.num_channels > max_nch) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index a687f047e3aeb..229c14b1af004 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -4739,12 +4739,6 @@ int mlx5e_policer_validate(const struct flow_action *action,
+ return -EOPNOTSUPP;
+ }
+
+- if (act->police.rate_pkt_ps) {
+- NL_SET_ERR_MSG_MOD(extack,
+- "QoS offload not support packets per second");
+- return -EOPNOTSUPP;
+- }
+-
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+index 4d45150a3f8ef..a30e50d9969f7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+@@ -304,6 +304,8 @@ static void mlx5e_sq_calc_wqe_attr(struct sk_buff *skb, const struct mlx5e_tx_at
+ u16 ds_cnt_inl = 0;
+ u16 ds_cnt_ids = 0;
+
++ /* Sync the calculation with MLX5E_MAX_TX_WQEBBS. */
++
+ if (attr->insz)
+ ds_cnt_ids = DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + attr->insz,
+ MLX5_SEND_WQE_DS);
+@@ -316,6 +318,9 @@ static void mlx5e_sq_calc_wqe_attr(struct sk_buff *skb, const struct mlx5e_tx_at
+ inl += VLAN_HLEN;
+
+ ds_cnt_inl = DIV_ROUND_UP(inl, MLX5_SEND_WQE_DS);
++ if (WARN_ON_ONCE(ds_cnt_inl > MLX5E_MAX_TX_INLINE_DS))
++ netdev_warn(skb->dev, "ds_cnt_inl = %u > max %u\n", ds_cnt_inl,
++ (u16)MLX5E_MAX_TX_INLINE_DS);
+ ds_cnt += ds_cnt_inl;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 6aa58044b949b..4d8b8f6143cc9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -1388,12 +1388,14 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw)
+ esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS",
+ esw->esw_funcs.num_vfs, esw->enabled_vports);
+
+- esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED;
+- if (esw->mode == MLX5_ESWITCH_OFFLOADS)
+- esw_offloads_disable(esw);
+- else if (esw->mode == MLX5_ESWITCH_LEGACY)
+- esw_legacy_disable(esw);
+- mlx5_esw_acls_ns_cleanup(esw);
++ if (esw->fdb_table.flags & MLX5_ESW_FDB_CREATED) {
++ esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED;
++ if (esw->mode == MLX5_ESWITCH_OFFLOADS)
++ esw_offloads_disable(esw);
++ else if (esw->mode == MLX5_ESWITCH_LEGACY)
++ esw_legacy_disable(esw);
++ mlx5_esw_acls_ns_cleanup(esw);
++ }
+
+ if (esw->mode == MLX5_ESWITCH_OFFLOADS)
+ devl_rate_nodes_destroy(devlink);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index a9f4c652f859c..3c68cac4a9c2c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -2207,7 +2207,7 @@ out_free:
+ static int esw_offloads_start(struct mlx5_eswitch *esw,
+ struct netlink_ext_ack *extack)
+ {
+- int err, err1;
++ int err;
+
+ esw->mode = MLX5_ESWITCH_OFFLOADS;
+ err = mlx5_eswitch_enable_locked(esw, esw->dev->priv.sriov.num_vfs);
+@@ -2215,11 +2215,6 @@ static int esw_offloads_start(struct mlx5_eswitch *esw,
+ NL_SET_ERR_MSG_MOD(extack,
+ "Failed setting eswitch to offloads");
+ esw->mode = MLX5_ESWITCH_LEGACY;
+- err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+- if (err1) {
+- NL_SET_ERR_MSG_MOD(extack,
+- "Failed setting eswitch back to legacy");
+- }
+ mlx5_rescan_drivers(esw->dev);
+ }
+ if (esw->offloads.inline_mode == MLX5_INLINE_MODE_NONE) {
+@@ -3272,19 +3267,12 @@ err_metadata:
+ static int esw_offloads_stop(struct mlx5_eswitch *esw,
+ struct netlink_ext_ack *extack)
+ {
+- int err, err1;
++ int err;
+
+ esw->mode = MLX5_ESWITCH_LEGACY;
+ err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+- if (err) {
++ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
+- esw->mode = MLX5_ESWITCH_OFFLOADS;
+- err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+- if (err1) {
+- NL_SET_ERR_MSG_MOD(extack,
+- "Failed setting eswitch back to offloads");
+- }
+- }
+
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+index ee568bf34ae25..108a3503f413c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+@@ -30,9 +30,9 @@ mlx5_eswitch_termtbl_hash(struct mlx5_flow_act *flow_act,
+ sizeof(dest->vport.num), hash);
+ hash = jhash((const void *)&dest->vport.vhca_id,
+ sizeof(dest->vport.num), hash);
+- if (dest->vport.pkt_reformat)
+- hash = jhash(dest->vport.pkt_reformat,
+- sizeof(*dest->vport.pkt_reformat),
++ if (flow_act->pkt_reformat)
++ hash = jhash(flow_act->pkt_reformat,
++ sizeof(*flow_act->pkt_reformat),
+ hash);
+ return hash;
+ }
+@@ -53,9 +53,11 @@ mlx5_eswitch_termtbl_cmp(struct mlx5_flow_act *flow_act1,
+ if (ret)
+ return ret;
+
+- return dest1->vport.pkt_reformat && dest2->vport.pkt_reformat ?
+- memcmp(dest1->vport.pkt_reformat, dest2->vport.pkt_reformat,
+- sizeof(*dest1->vport.pkt_reformat)) : 0;
++ if (flow_act1->pkt_reformat && flow_act2->pkt_reformat)
++ return memcmp(flow_act1->pkt_reformat, flow_act2->pkt_reformat,
++ sizeof(*flow_act1->pkt_reformat));
++
++ return !(flow_act1->pkt_reformat == flow_act2->pkt_reformat);
+ }
+
+ static int
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 07c583996c297..9d908a0ccfef1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -152,7 +152,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ mlx5_unload_one(dev);
+ if (mlx5_health_wait_pci_up(dev))
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+- mlx5_load_one(dev, false);
++ else
++ mlx5_load_one(dev, false);
+ devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
+ BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+ BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
+index 30f955efa8308..8f74c039b3be2 100644
+--- a/drivers/net/ethernet/neterion/s2io.c
++++ b/drivers/net/ethernet/neterion/s2io.c
+@@ -7128,9 +7128,8 @@ static int s2io_card_up(struct s2io_nic *sp)
+ if (ret) {
+ DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
+ dev->name);
+- s2io_reset(sp);
+- free_rx_buffers(sp);
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto err_fill_buff;
+ }
+ DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
+ ring->rx_bufs_left);
+@@ -7168,18 +7167,16 @@ static int s2io_card_up(struct s2io_nic *sp)
+ /* Enable Rx Traffic and interrupts on the NIC */
+ if (start_nic(sp)) {
+ DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
+- s2io_reset(sp);
+- free_rx_buffers(sp);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err_out;
+ }
+
+ /* Add interrupt service routine */
+ if (s2io_add_isr(sp) != 0) {
+ if (sp->config.intr_type == MSI_X)
+ s2io_rem_isr(sp);
+- s2io_reset(sp);
+- free_rx_buffers(sp);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err_out;
+ }
+
+ timer_setup(&sp->alarm_timer, s2io_alarm_handle, 0);
+@@ -7199,6 +7196,20 @@ static int s2io_card_up(struct s2io_nic *sp)
+ }
+
+ return 0;
++
++err_out:
++ if (config->napi) {
++ if (config->intr_type == MSI_X) {
++ for (i = 0; i < sp->config.rx_ring_num; i++)
++ napi_disable(&sp->mac_control.rings[i].napi);
++ } else {
++ napi_disable(&sp->napi);
++ }
++ }
++err_fill_buff:
++ s2io_reset(sp);
++ free_rx_buffers(sp);
++ return ret;
+ }
+
+ /**
+diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
+index 4b3482ce90a1c..4fc279a175629 100644
+--- a/drivers/net/ethernet/ni/nixge.c
++++ b/drivers/net/ethernet/ni/nixge.c
+@@ -900,6 +900,7 @@ static int nixge_open(struct net_device *ndev)
+ err_rx_irq:
+ free_irq(priv->tx_irq, ndev);
+ err_tx_irq:
++ napi_disable(&priv->napi);
+ phy_stop(phy);
+ phy_disconnect(phy);
+ tasklet_kill(&priv->dma_err_tasklet);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+index 9af25be424014..66c30a40a6a21 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+@@ -630,7 +630,6 @@ static int ehl_common_data(struct pci_dev *pdev,
+ {
+ plat->rx_queues_to_use = 8;
+ plat->tx_queues_to_use = 8;
+- plat->clk_ptp_rate = 200000000;
+ plat->use_phy_wol = 1;
+
+ plat->safety_feat_cfg->tsoee = 1;
+@@ -655,6 +654,8 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
+ plat->serdes_powerup = intel_serdes_powerup;
+ plat->serdes_powerdown = intel_serdes_powerdown;
+
++ plat->clk_ptp_rate = 204800000;
++
+ return ehl_common_data(pdev, plat);
+ }
+
+@@ -668,6 +669,8 @@ static int ehl_rgmii_data(struct pci_dev *pdev,
+ plat->bus_id = 1;
+ plat->phy_interface = PHY_INTERFACE_MODE_RGMII;
+
++ plat->clk_ptp_rate = 204800000;
++
+ return ehl_common_data(pdev, plat);
+ }
+
+@@ -684,6 +687,8 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
+ plat->bus_id = 2;
+ plat->addr64 = 32;
+
++ plat->clk_ptp_rate = 200000000;
++
+ intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+
+ return ehl_common_data(pdev, plat);
+@@ -723,6 +728,8 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
+ plat->bus_id = 3;
+ plat->addr64 = 32;
+
++ plat->clk_ptp_rate = 200000000;
++
+ intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+
+ return ehl_common_data(pdev, plat);
+@@ -758,7 +765,7 @@ static int tgl_common_data(struct pci_dev *pdev,
+ {
+ plat->rx_queues_to_use = 6;
+ plat->tx_queues_to_use = 4;
+- plat->clk_ptp_rate = 200000000;
++ plat->clk_ptp_rate = 204800000;
+ plat->speed_mode_2500 = intel_speed_mode_2500;
+
+ plat->safety_feat_cfg->tsoee = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index 79fa7870563b8..a25c187d31853 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -75,20 +75,24 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+ sizeof(*plat->mdio_bus_data),
+ GFP_KERNEL);
+- if (!plat->mdio_bus_data)
+- return -ENOMEM;
++ if (!plat->mdio_bus_data) {
++ ret = -ENOMEM;
++ goto err_put_node;
++ }
+ plat->mdio_bus_data->needs_reset = true;
+ }
+
+ plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL);
+- if (!plat->dma_cfg)
+- return -ENOMEM;
++ if (!plat->dma_cfg) {
++ ret = -ENOMEM;
++ goto err_put_node;
++ }
+
+ /* Enable pci device */
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", __func__);
+- return ret;
++ goto err_put_node;
+ }
+
+ /* Get the base address of device */
+@@ -97,7 +101,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ continue;
+ ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
+ if (ret)
+- return ret;
++ goto err_disable_device;
+ break;
+ }
+
+@@ -108,7 +112,8 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ phy_mode = device_get_phy_mode(&pdev->dev);
+ if (phy_mode < 0) {
+ dev_err(&pdev->dev, "phy_mode not found\n");
+- return phy_mode;
++ ret = phy_mode;
++ goto err_disable_device;
+ }
+
+ plat->phy_interface = phy_mode;
+@@ -125,6 +130,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ if (res.irq < 0) {
+ dev_err(&pdev->dev, "IRQ macirq not found\n");
+ ret = -ENODEV;
++ goto err_disable_msi;
+ }
+
+ res.wol_irq = of_irq_get_byname(np, "eth_wake_irq");
+@@ -137,15 +143,31 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ if (res.lpi_irq < 0) {
+ dev_err(&pdev->dev, "IRQ eth_lpi not found\n");
+ ret = -ENODEV;
++ goto err_disable_msi;
+ }
+
+- return stmmac_dvr_probe(&pdev->dev, plat, &res);
++ ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
++ if (ret)
++ goto err_disable_msi;
++
++ return ret;
++
++err_disable_msi:
++ pci_disable_msi(pdev);
++err_disable_device:
++ pci_disable_device(pdev);
++err_put_node:
++ of_node_put(plat->mdio_node);
++ return ret;
+ }
+
+ static void loongson_dwmac_remove(struct pci_dev *pdev)
+ {
++ struct net_device *ndev = dev_get_drvdata(&pdev->dev);
++ struct stmmac_priv *priv = netdev_priv(ndev);
+ int i;
+
++ of_node_put(priv->plat->mdio_node);
+ stmmac_dvr_remove(&pdev->dev);
+
+ for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+@@ -155,6 +177,7 @@ static void loongson_dwmac_remove(struct pci_dev *pdev)
+ break;
+ }
+
++ pci_disable_msi(pdev);
+ pci_disable_device(pdev);
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+index c7a6588d9398b..e8b507f88fbce 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+@@ -272,11 +272,9 @@ static int meson8b_devm_clk_prepare_enable(struct meson8b_dwmac *dwmac,
+ if (ret)
+ return ret;
+
+- devm_add_action_or_reset(dwmac->dev,
+- (void(*)(void *))clk_disable_unprepare,
+- dwmac->rgmii_tx_clk);
+-
+- return 0;
++ return devm_add_action_or_reset(dwmac->dev,
++ (void(*)(void *))clk_disable_unprepare,
++ clk);
+ }
+
+ static int meson8b_init_rgmii_delays(struct meson8b_dwmac *dwmac)
+diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+index 61d1d07dc0704..d6f1fef4ff3af 100644
+--- a/drivers/net/ethernet/sunplus/spl2sw_driver.c
++++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+@@ -286,7 +286,6 @@ static u32 spl2sw_init_netdev(struct platform_device *pdev, u8 *mac_addr,
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n",
+ ndev->name);
+- free_netdev(ndev);
+ *r_ndev = NULL;
+ return ret;
+ }
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index f4a6b590a1e39..348201e10d497 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -2791,7 +2791,6 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
+ if (ret < 0)
+ return ret;
+
+- am65_cpsw_nuss_phylink_cleanup(common);
+ am65_cpsw_unregister_devlink(common);
+ am65_cpsw_unregister_notifiers(common);
+
+@@ -2799,6 +2798,7 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
+ * dma_deconfigure(dev) before devres_release_all(dev)
+ */
+ am65_cpsw_nuss_cleanup_ndev(common);
++ am65_cpsw_nuss_phylink_cleanup(common);
+
+ of_platform_device_destroy(common->mdio_dev, NULL);
+
+diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
+index ed66c4d4d8301..613e2c7c950ca 100644
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -854,6 +854,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
+
+ err_cleanup:
+ if (!cpsw->usage_count) {
++ napi_disable(&cpsw->napi_rx);
++ napi_disable(&cpsw->napi_tx);
+ cpdma_ctlr_stop(cpsw->dma);
+ cpsw_destroy_xdp_rxqs(cpsw);
+ }
+diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
+index 5251fc3242219..a2fe0534c769b 100644
+--- a/drivers/net/ethernet/tundra/tsi108_eth.c
++++ b/drivers/net/ethernet/tundra/tsi108_eth.c
+@@ -1303,12 +1303,15 @@ static int tsi108_open(struct net_device *dev)
+
+ data->rxring = dma_alloc_coherent(&data->pdev->dev, rxring_size,
+ &data->rxdma, GFP_KERNEL);
+- if (!data->rxring)
++ if (!data->rxring) {
++ free_irq(data->irq_num, dev);
+ return -ENOMEM;
++ }
+
+ data->txring = dma_alloc_coherent(&data->pdev->dev, txring_size,
+ &data->txdma, GFP_KERNEL);
+ if (!data->txring) {
++ free_irq(data->irq_num, dev);
+ dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
+ data->rxdma);
+ return -ENOMEM;
+diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
+index 30af0081e2bef..83a16d10eedbc 100644
+--- a/drivers/net/hamradio/bpqether.c
++++ b/drivers/net/hamradio/bpqether.c
+@@ -533,7 +533,7 @@ static int bpq_device_event(struct notifier_block *this,
+ if (!net_eq(dev_net(dev), &init_net))
+ return NOTIFY_DONE;
+
+- if (!dev_is_ethdev(dev))
++ if (!dev_is_ethdev(dev) && !bpq_get_ax25_dev(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index c6d271e5687e9..ddfa853ec9b53 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1427,7 +1427,8 @@ static struct macsec_rx_sc *del_rx_sc(struct macsec_secy *secy, sci_t sci)
+ return NULL;
+ }
+
+-static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci)
++static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci,
++ bool active)
+ {
+ struct macsec_rx_sc *rx_sc;
+ struct macsec_dev *macsec;
+@@ -1451,7 +1452,7 @@ static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci)
+ }
+
+ rx_sc->sci = sci;
+- rx_sc->active = true;
++ rx_sc->active = active;
+ refcount_set(&rx_sc->refcnt, 1);
+
+ secy = &macsec_priv(dev)->secy;
+@@ -1860,6 +1861,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
+ secy->key_len);
+
+ err = macsec_offload(ops->mdo_add_rxsa, &ctx);
++ memzero_explicit(ctx.sa.key, secy->key_len);
+ if (err)
+ goto cleanup;
+ }
+@@ -1904,7 +1906,7 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ struct macsec_rx_sc *rx_sc;
+ struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
+ struct macsec_secy *secy;
+- bool was_active;
++ bool active = true;
+ int ret;
+
+ if (!attrs[MACSEC_ATTR_IFINDEX])
+@@ -1926,16 +1928,15 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ secy = &macsec_priv(dev)->secy;
+ sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]);
+
+- rx_sc = create_rx_sc(dev, sci);
++ if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE])
++ active = nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
++
++ rx_sc = create_rx_sc(dev, sci, active);
+ if (IS_ERR(rx_sc)) {
+ rtnl_unlock();
+ return PTR_ERR(rx_sc);
+ }
+
+- was_active = rx_sc->active;
+- if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE])
+- rx_sc->active = !!nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
+-
+ if (macsec_is_offloaded(netdev_priv(dev))) {
+ const struct macsec_ops *ops;
+ struct macsec_context ctx;
+@@ -1959,7 +1960,8 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ return 0;
+
+ cleanup:
+- rx_sc->active = was_active;
++ del_rx_sc(secy, sci);
++ free_rx_sc(rx_sc);
+ rtnl_unlock();
+ return ret;
+ }
+@@ -2102,6 +2104,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
+ secy->key_len);
+
+ err = macsec_offload(ops->mdo_add_txsa, &ctx);
++ memzero_explicit(ctx.sa.key, secy->key_len);
+ if (err)
+ goto cleanup;
+ }
+@@ -2598,7 +2601,7 @@ static bool macsec_is_configured(struct macsec_dev *macsec)
+ struct macsec_tx_sc *tx_sc = &secy->tx_sc;
+ int i;
+
+- if (secy->n_rx_sc > 0)
++ if (secy->rx_sc)
+ return true;
+
+ for (i = 0; i < MACSEC_NUM_AN; i++)
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 1080d6ebff63b..9983d37ee87d9 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1533,8 +1533,10 @@ destroy_macvlan_port:
+ /* the macvlan port may be freed by macvlan_uninit when fail to register.
+ * so we destroy the macvlan port only when it's valid.
+ */
+- if (create && macvlan_port_get_rtnl(lowerdev))
++ if (create && macvlan_port_get_rtnl(lowerdev)) {
++ macvlan_flush_sources(port, vlan);
+ macvlan_port_destroy(port->dev);
++ }
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c
+index b7b2521c73fb6..c00eef457b850 100644
+--- a/drivers/net/phy/mscc/mscc_macsec.c
++++ b/drivers/net/phy/mscc/mscc_macsec.c
+@@ -632,6 +632,7 @@ static void vsc8584_macsec_free_flow(struct vsc8531_private *priv,
+
+ list_del(&flow->list);
+ clear_bit(flow->index, bitmap);
++ memzero_explicit(flow->key, sizeof(flow->key));
+ kfree(flow);
+ }
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index b02bd0a6c0a93..3387074a2bdb8 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1967,17 +1967,25 @@ drop:
+ skb_headlen(skb));
+
+ if (unlikely(headlen > skb_headlen(skb))) {
++ WARN_ON_ONCE(1);
++ err = -ENOMEM;
+ dev_core_stats_rx_dropped_inc(tun->dev);
++napi_busy:
+ napi_free_frags(&tfile->napi);
+ rcu_read_unlock();
+ mutex_unlock(&tfile->napi_mutex);
+- WARN_ON(1);
+- return -ENOMEM;
++ return err;
+ }
+
+- local_bh_disable();
+- napi_gro_frags(&tfile->napi);
+- local_bh_enable();
++ if (likely(napi_schedule_prep(&tfile->napi))) {
++ local_bh_disable();
++ napi_gro_frags(&tfile->napi);
++ napi_complete(&tfile->napi);
++ local_bh_enable();
++ } else {
++ err = -EBUSY;
++ goto napi_busy;
++ }
+ mutex_unlock(&tfile->napi_mutex);
+ } else if (tfile->napi_enabled) {
+ struct sk_buff_head *queue = &tfile->sk.sk_write_queue;
+diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
+index 960f1393595cc..d62a904d2e422 100644
+--- a/drivers/net/wan/lapbether.c
++++ b/drivers/net/wan/lapbether.c
+@@ -325,6 +325,7 @@ static int lapbeth_open(struct net_device *dev)
+
+ err = lapb_register(dev, &lapbeth_callbacks);
+ if (err != LAPB_OK) {
++ napi_disable(&lapbeth->napi);
+ pr_err("lapb_register error: %d\n", err);
+ return -ENODEV;
+ }
+@@ -446,7 +447,7 @@ static int lapbeth_device_event(struct notifier_block *this,
+ if (dev_net(dev) != &init_net)
+ return NOTIFY_DONE;
+
+- if (!dev_is_ethdev(dev))
++ if (!dev_is_ethdev(dev) && !lapbeth_get_x25_dev(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
+index 7ee3ff69dfc85..6fae4e61ede7f 100644
+--- a/drivers/net/wireless/ath/ath11k/reg.c
++++ b/drivers/net/wireless/ath/ath11k/reg.c
+@@ -287,11 +287,7 @@ int ath11k_regd_update(struct ath11k *ar)
+ goto err;
+ }
+
+- rtnl_lock();
+- wiphy_lock(ar->hw->wiphy);
+- ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy);
+- wiphy_unlock(ar->hw->wiphy);
+- rtnl_unlock();
++ ret = regulatory_set_wiphy_regd(ar->hw->wiphy, regd_copy);
+
+ kfree(regd_copy);
+
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
+index 57304a5adf68e..6e32eb91bba95 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
+@@ -91,6 +91,14 @@ void ipc_imem_wwan_channel_init(struct iosm_imem *ipc_imem,
+ }
+
+ ipc_chnl_cfg_get(&chnl_cfg, ipc_imem->nr_of_channels);
++
++ if (ipc_imem->mmio->mux_protocol == MUX_AGGREGATION &&
++ ipc_imem->nr_of_channels == IPC_MEM_IP_CHL_ID_0) {
++ chnl_cfg.ul_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_UL;
++ chnl_cfg.dl_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_DL;
++ chnl_cfg.dl_buf_size = IPC_MEM_MAX_ADB_BUF_SIZE;
++ }
++
+ ipc_imem_channel_init(ipc_imem, IPC_CTYPE_WWAN, chnl_cfg,
+ IRQ_MOD_OFF);
+
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.h b/drivers/net/wwan/iosm/iosm_ipc_mux.h
+index cd9d74cc097f1..9968bb885c1f3 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux.h
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux.h
+@@ -10,6 +10,7 @@
+
+ #define IPC_MEM_MAX_UL_DG_ENTRIES 100
+ #define IPC_MEM_MAX_TDS_MUX_AGGR_UL 60
++#define IPC_MEM_MAX_TDS_MUX_AGGR_DL 60
+
+ #define IPC_MEM_MAX_ADB_BUF_SIZE (16 * 1024)
+ #define IPC_MEM_MAX_UL_ADB_BUF_SIZE IPC_MEM_MAX_ADB_BUF_SIZE
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 31f57b986df28..97cb6846c6ae2 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -232,6 +232,7 @@ static void ipc_pcie_config_init(struct iosm_pcie *ipc_pcie)
+ */
+ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ {
++ enum ipc_pcie_sleep_state sleep_state = IPC_PCIE_D0L12;
+ union acpi_object *object;
+ acpi_handle handle_acpi;
+
+@@ -242,12 +243,16 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ }
+
+ object = acpi_evaluate_dsm(handle_acpi, &wwan_acpi_guid, 0, 3, NULL);
++ if (!object)
++ goto default_ret;
++
++ if (object->integer.value == 3)
++ sleep_state = IPC_PCIE_D3L2;
+
+- if (object && object->integer.value == 3)
+- return IPC_PCIE_D3L2;
++ kfree(object);
+
+ default_ret:
+- return IPC_PCIE_D0L12;
++ return sleep_state;
+ }
+
+ static int ipc_pcie_probe(struct pci_dev *pci,
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+index 4712f01a7e33e..3d70b34f96e31 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+@@ -168,6 +168,7 @@ static void ipc_wwan_setup(struct net_device *iosm_dev)
+ iosm_dev->max_mtu = ETH_MAX_MTU;
+
+ iosm_dev->flags = IFF_POINTOPOINT | IFF_NOARP;
++ iosm_dev->needs_free_netdev = true;
+
+ iosm_dev->netdev_ops = &ipc_inm_ops;
+ }
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
+index 6872782e8dd89..ef70bb7c88ad6 100644
+--- a/drivers/net/wwan/mhi_wwan_mbim.c
++++ b/drivers/net/wwan/mhi_wwan_mbim.c
+@@ -582,6 +582,7 @@ static void mhi_mbim_setup(struct net_device *ndev)
+ ndev->min_mtu = ETH_MIN_MTU;
+ ndev->max_mtu = MHI_MAX_BUF_SZ - ndev->needed_headroom;
+ ndev->tx_queue_len = 1000;
++ ndev->needs_free_netdev = true;
+ }
+
+ static const struct wwan_ops mhi_mbim_wwan_ops = {
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index e7c6f6629e7c5..ba64284eaf9fa 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -1614,7 +1614,7 @@ out:
+
+ static u32 hv_compose_msi_req_v1(
+ struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
+- u32 slot, u8 vector, u8 vector_count)
++ u32 slot, u8 vector, u16 vector_count)
+ {
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+ int_pkt->wslot.slot = slot;
+@@ -1642,7 +1642,7 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
+
+ static u32 hv_compose_msi_req_v2(
+ struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
+- u32 slot, u8 vector, u8 vector_count)
++ u32 slot, u8 vector, u16 vector_count)
+ {
+ int cpu;
+
+@@ -1661,7 +1661,7 @@ static u32 hv_compose_msi_req_v2(
+
+ static u32 hv_compose_msi_req_v3(
+ struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
+- u32 slot, u32 vector, u8 vector_count)
++ u32 slot, u32 vector, u16 vector_count)
+ {
+ int cpu;
+
+@@ -1701,7 +1701,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ struct compose_comp_ctxt comp;
+ struct tran_int_desc *int_desc;
+ struct msi_desc *msi_desc;
+- u8 vector, vector_count;
++ /*
++ * vector_count should be u16: see hv_msi_desc, hv_msi_desc2
++ * and hv_msi_desc3. vector must be u32: see hv_msi_desc3.
++ */
++ u16 vector_count;
++ u32 vector;
+ struct {
+ struct pci_packet pci_pkt;
+ union {
+@@ -1767,6 +1772,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ vector_count = 1;
+ }
+
++ /*
++ * hv_compose_msi_req_v1 and v2 are for x86 only, meaning 'vector'
++ * can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly
++ * for better readability.
++ */
+ memset(&ctxt, 0, sizeof(ctxt));
+ init_completion(&comp.comp_pkt.host_event);
+ ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
+@@ -1777,7 +1787,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+ dest,
+ hpdev->desc.win_slot.slot,
+- vector,
++ (u8)vector,
+ vector_count);
+ break;
+
+@@ -1786,7 +1796,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+ dest,
+ hpdev->desc.win_slot.slot,
+- vector,
++ (u8)vector,
+ vector_count);
+ break;
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 4b18289761044..3e730c05ac3fb 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -1914,7 +1914,7 @@ static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
+ static void qcom_qmp_phy_combo_disable_autonomous_mode(struct qmp_phy *qphy)
+ {
+ const struct qmp_phy_cfg *cfg = qphy->cfg;
+- void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs_usb;
++ void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
+ void __iomem *pcs_misc = qphy->pcs_misc;
+
+ /* Disable i/o clamp_n on resume for normal mode */
+diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
+index 5e6530f545b5c..85888ab2d307a 100644
+--- a/drivers/phy/ralink/phy-mt7621-pci.c
++++ b/drivers/phy/ralink/phy-mt7621-pci.c
+@@ -280,7 +280,8 @@ static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
+ }
+
+ static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
+- { .soc_id = "mt7621", .revision = "E2" }
++ { .soc_id = "mt7621", .revision = "E2" },
++ { /* sentinel */ }
+ };
+
+ static const struct regmap_config mt7621_pci_phy_regmap_config = {
+diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
+index a98c911cc37ae..5bb9647b078f1 100644
+--- a/drivers/phy/st/phy-stm32-usbphyc.c
++++ b/drivers/phy/st/phy-stm32-usbphyc.c
+@@ -710,6 +710,8 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
+ ret = of_property_read_u32(child, "reg", &index);
+ if (ret || index > usbphyc->nphys) {
+ dev_err(&phy->dev, "invalid reg property: %d\n", ret);
++ if (!ret)
++ ret = -EINVAL;
+ goto put_child;
+ }
+
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index fc8dbbd6fc7c2..4fbe91769c915 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -1298,8 +1298,16 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
+ wwan_rfkill = NULL;
+ rfkill2_count = 0;
+
+- if (hp_wmi_rfkill_setup(device))
+- hp_wmi_rfkill2_setup(device);
++ /*
++ * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that
++ * BIOS no longer controls the power for the wireless
++ * devices. All features supported by this command will no
++ * longer be supported.
++ */
++ if (!hp_wmi_bios_2009_later()) {
++ if (hp_wmi_rfkill_setup(device))
++ hp_wmi_rfkill2_setup(device);
++ }
+
+ err = hp_wmi_hwmon_init();
+
+diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
+index 384d0962ae93a..1cf2471d54dde 100644
+--- a/drivers/platform/x86/p2sb.c
++++ b/drivers/platform/x86/p2sb.c
+@@ -19,26 +19,23 @@
+ #define P2SBC 0xe0
+ #define P2SBC_HIDE BIT(8)
+
++#define P2SB_DEVFN_DEFAULT PCI_DEVFN(31, 1)
++
+ static const struct x86_cpu_id p2sb_cpu_ids[] = {
+ X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, PCI_DEVFN(13, 0)),
+- X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, PCI_DEVFN(31, 1)),
+- X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, PCI_DEVFN(31, 1)),
+- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, PCI_DEVFN(31, 1)),
+- X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, PCI_DEVFN(31, 1)),
+- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, PCI_DEVFN(31, 1)),
+- X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, PCI_DEVFN(31, 1)),
+ {}
+ };
+
+ static int p2sb_get_devfn(unsigned int *devfn)
+ {
++ unsigned int fn = P2SB_DEVFN_DEFAULT;
+ const struct x86_cpu_id *id;
+
+ id = x86_match_cpu(p2sb_cpu_ids);
+- if (!id)
+- return -ENODEV;
++ if (id)
++ fn = (unsigned int)id->driver_data;
+
+- *devfn = (unsigned int)id->driver_data;
++ *devfn = fn;
+ return 0;
+ }
+
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index 3a992a6478c30..6e5990611d834 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -344,6 +344,9 @@ static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *swrm, u8 cmd_data,
+ if (swrm_wait_for_wr_fifo_avail(swrm))
+ return SDW_CMD_FAIL_OTHER;
+
++ if (cmd_id == SWR_BROADCAST_CMD_ID)
++ reinit_completion(&swrm->broadcast);
++
+ /* Its assumed that write is okay as we do not get any status back */
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_WR_CMD, val);
+
+@@ -377,6 +380,12 @@ static int qcom_swrm_cmd_fifo_rd_cmd(struct qcom_swrm_ctrl *swrm,
+
+ val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr);
+
++ /*
++ * Check for outstanding cmd wrt. write fifo depth to avoid
++ * overflow as read will also increase write fifo cnt.
++ */
++ swrm_wait_for_wr_fifo_avail(swrm);
++
+ /* wait for FIFO RD to complete to avoid overflow */
+ usleep_range(100, 105);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
+diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
+index 66063687ae271..3f6db482b6c71 100644
+--- a/drivers/spi/spi-intel.c
++++ b/drivers/spi/spi-intel.c
+@@ -52,17 +52,17 @@
+ #define FRACC 0x50
+
+ #define FREG(n) (0x54 + ((n) * 4))
+-#define FREG_BASE_MASK 0x3fff
++#define FREG_BASE_MASK GENMASK(14, 0)
+ #define FREG_LIMIT_SHIFT 16
+-#define FREG_LIMIT_MASK (0x03fff << FREG_LIMIT_SHIFT)
++#define FREG_LIMIT_MASK GENMASK(30, 16)
+
+ /* Offset is from @ispi->pregs */
+ #define PR(n) ((n) * 4)
+ #define PR_WPE BIT(31)
+ #define PR_LIMIT_SHIFT 16
+-#define PR_LIMIT_MASK (0x3fff << PR_LIMIT_SHIFT)
++#define PR_LIMIT_MASK GENMASK(30, 16)
+ #define PR_RPE BIT(15)
+-#define PR_BASE_MASK 0x3fff
++#define PR_BASE_MASK GENMASK(14, 0)
+
+ /* Offsets are from @ispi->sregs */
+ #define SSFSTS_CTL 0x00
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 0a3b9f7eed30f..cd9dc358d3967 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -551,14 +551,17 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
+ writel(cmd, mdata->base + SPI_CMD_REG);
+ }
+
+-static int mtk_spi_get_mult_delta(u32 xfer_len)
++static int mtk_spi_get_mult_delta(struct mtk_spi *mdata, u32 xfer_len)
+ {
+- u32 mult_delta;
++ u32 mult_delta = 0;
+
+- if (xfer_len > MTK_SPI_PACKET_SIZE)
+- mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
+- else
+- mult_delta = 0;
++ if (mdata->dev_comp->ipm_design) {
++ if (xfer_len > MTK_SPI_IPM_PACKET_SIZE)
++ mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE;
++ } else {
++ if (xfer_len > MTK_SPI_PACKET_SIZE)
++ mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
++ }
+
+ return mult_delta;
+ }
+@@ -570,22 +573,22 @@ static void mtk_spi_update_mdata_len(struct spi_master *master)
+
+ if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
+ if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
+- mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
++ mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
+ mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+ mdata->rx_sgl_len = mult_delta;
+ mdata->tx_sgl_len -= mdata->xfer_len;
+ } else {
+- mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
++ mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
+ mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+ mdata->tx_sgl_len = mult_delta;
+ mdata->rx_sgl_len -= mdata->xfer_len;
+ }
+ } else if (mdata->tx_sgl_len) {
+- mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
++ mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
+ mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+ mdata->tx_sgl_len = mult_delta;
+ } else if (mdata->rx_sgl_len) {
+- mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
++ mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
+ mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+ mdata->rx_sgl_len = mult_delta;
+ }
+diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
+index 9853f6c7e81d7..583c22df40403 100644
+--- a/drivers/thunderbolt/tb.c
++++ b/drivers/thunderbolt/tb.c
+@@ -105,6 +105,32 @@ static void tb_remove_dp_resources(struct tb_switch *sw)
+ }
+ }
+
++static void tb_discover_dp_resource(struct tb *tb, struct tb_port *port)
++{
++ struct tb_cm *tcm = tb_priv(tb);
++ struct tb_port *p;
++
++ list_for_each_entry(p, &tcm->dp_resources, list) {
++ if (p == port)
++ return;
++ }
++
++ tb_port_dbg(port, "DP %s resource available discovered\n",
++ tb_port_is_dpin(port) ? "IN" : "OUT");
++ list_add_tail(&port->list, &tcm->dp_resources);
++}
++
++static void tb_discover_dp_resources(struct tb *tb)
++{
++ struct tb_cm *tcm = tb_priv(tb);
++ struct tb_tunnel *tunnel;
++
++ list_for_each_entry(tunnel, &tcm->tunnel_list, list) {
++ if (tb_tunnel_is_dp(tunnel))
++ tb_discover_dp_resource(tb, tunnel->dst_port);
++ }
++}
++
+ static void tb_switch_discover_tunnels(struct tb_switch *sw,
+ struct list_head *list,
+ bool alloc_hopids)
+@@ -1446,6 +1472,8 @@ static int tb_start(struct tb *tb)
+ tb_scan_switch(tb->root_switch);
+ /* Find out tunnels created by the boot firmware */
+ tb_discover_tunnels(tb);
++ /* Add DP resources from the DP tunnels created by the boot firmware */
++ tb_discover_dp_resources(tb);
+ /*
+ * If the boot firmware did not create USB 3.x tunnels create them
+ * now for the whole topology.
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 2633137c3e9f1..aa4bc213d301b 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2544,7 +2544,9 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
+ fs_info->dev_root = root;
+ }
+ /* Initialize fs_info for all devices in any case */
+- btrfs_init_devices_late(fs_info);
++ ret = btrfs_init_devices_late(fs_info);
++ if (ret)
++ goto out;
+
+ /*
+ * This tree can share blocks with some other fs tree during relocation
+diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
+index cc9377cf56a33..8c8e28dff2f12 100644
+--- a/fs/btrfs/tests/btrfs-tests.c
++++ b/fs/btrfs/tests/btrfs-tests.c
+@@ -200,7 +200,7 @@ void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
+
+ void btrfs_free_dummy_root(struct btrfs_root *root)
+ {
+- if (!root)
++ if (IS_ERR_OR_NULL(root))
+ return;
+ /* Will be freed by btrfs_free_fs_roots */
+ if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 5d004772ab493..7aa220742c61d 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1009,6 +1009,18 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
+ rcu_assign_pointer(device->name, name);
+ }
+
++ if (orig_dev->zone_info) {
++ struct btrfs_zoned_device_info *zone_info;
++
++ zone_info = btrfs_clone_dev_zone_info(orig_dev);
++ if (!zone_info) {
++ btrfs_free_device(device);
++ ret = -ENOMEM;
++ goto error;
++ }
++ device->zone_info = zone_info;
++ }
++
+ list_add(&device->dev_list, &fs_devices->devices);
+ device->fs_devices = fs_devices;
+ fs_devices->num_devices++;
+@@ -6805,18 +6817,18 @@ static bool dev_args_match_fs_devices(const struct btrfs_dev_lookup_args *args,
+ static bool dev_args_match_device(const struct btrfs_dev_lookup_args *args,
+ const struct btrfs_device *device)
+ {
+- ASSERT((args->devid != (u64)-1) || args->missing);
++ if (args->missing) {
++ if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
++ !device->bdev)
++ return true;
++ return false;
++ }
+
+- if ((args->devid != (u64)-1) && device->devid != args->devid)
++ if (device->devid != args->devid)
+ return false;
+ if (args->uuid && memcmp(device->uuid, args->uuid, BTRFS_UUID_SIZE) != 0)
+ return false;
+- if (!args->missing)
+- return true;
+- if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
+- !device->bdev)
+- return true;
+- return false;
++ return true;
+ }
+
+ /*
+@@ -7631,10 +7643,11 @@ error:
+ return ret;
+ }
+
+-void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
++int btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
+ {
+ struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
+ struct btrfs_device *device;
++ int ret = 0;
+
+ fs_devices->fs_info = fs_info;
+
+@@ -7643,12 +7656,18 @@ void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
+ device->fs_info = fs_info;
+
+ list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
+- list_for_each_entry(device, &seed_devs->devices, dev_list)
++ list_for_each_entry(device, &seed_devs->devices, dev_list) {
+ device->fs_info = fs_info;
++ ret = btrfs_get_dev_zone_info(device, false);
++ if (ret)
++ break;
++ }
+
+ seed_devs->fs_info = fs_info;
+ }
+ mutex_unlock(&fs_devices->device_list_mutex);
++
++ return ret;
+ }
+
+ static u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
+diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
+index 5639961b3626f..6d6cf77cd1b57 100644
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -629,7 +629,7 @@ int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
+ void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
+ int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,
+ struct btrfs_ioctl_get_dev_stats *stats);
+-void btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
++int btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
+ int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
+ int btrfs_run_dev_stats(struct btrfs_trans_handle *trans);
+ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_device *srcdev);
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index 73c6929f7be66..a227d27a63bfd 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -639,6 +639,46 @@ void btrfs_destroy_dev_zone_info(struct btrfs_device *device)
+ device->zone_info = NULL;
+ }
+
++struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev)
++{
++ struct btrfs_zoned_device_info *zone_info;
++
++ zone_info = kmemdup(orig_dev->zone_info, sizeof(*zone_info), GFP_KERNEL);
++ if (!zone_info)
++ return NULL;
++
++ zone_info->seq_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++ if (!zone_info->seq_zones)
++ goto out;
++
++ bitmap_copy(zone_info->seq_zones, orig_dev->zone_info->seq_zones,
++ zone_info->nr_zones);
++
++ zone_info->empty_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++ if (!zone_info->empty_zones)
++ goto out;
++
++ bitmap_copy(zone_info->empty_zones, orig_dev->zone_info->empty_zones,
++ zone_info->nr_zones);
++
++ zone_info->active_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++ if (!zone_info->active_zones)
++ goto out;
++
++ bitmap_copy(zone_info->active_zones, orig_dev->zone_info->active_zones,
++ zone_info->nr_zones);
++ zone_info->zone_cache = NULL;
++
++ return zone_info;
++
++out:
++ bitmap_free(zone_info->seq_zones);
++ bitmap_free(zone_info->empty_zones);
++ bitmap_free(zone_info->active_zones);
++ kfree(zone_info);
++ return NULL;
++}
++
+ int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
+ struct blk_zone *zone)
+ {
+diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
+index e17462db3a842..8bd16d40b7c65 100644
+--- a/fs/btrfs/zoned.h
++++ b/fs/btrfs/zoned.h
+@@ -36,6 +36,7 @@ int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
+ int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info);
+ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache);
+ void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
++struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev);
+ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
+ int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
+ int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
+@@ -103,6 +104,16 @@ static inline int btrfs_get_dev_zone_info(struct btrfs_device *device,
+
+ static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
+
++/*
++ * In case the kernel is compiled without CONFIG_BLK_DEV_ZONED we'll never call
++ * into btrfs_clone_dev_zone_info() so it's safe to return NULL here.
++ */
++static inline struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(
++ struct btrfs_device *orig_dev)
++{
++ return NULL;
++}
++
+ static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
+ {
+ if (!btrfs_is_zoned(fs_info))
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 56d2c6fc61753..8568c33d4a76f 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -317,7 +317,7 @@ void nilfs_relax_pressure_in_lock(struct super_block *sb)
+ struct the_nilfs *nilfs = sb->s_fs_info;
+ struct nilfs_sc_info *sci = nilfs->ns_writer;
+
+- if (!sci || !sci->sc_flush_request)
++ if (sb_rdonly(sb) || unlikely(!sci) || !sci->sc_flush_request)
+ return;
+
+ set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
+@@ -2243,7 +2243,7 @@ int nilfs_construct_segment(struct super_block *sb)
+ struct nilfs_transaction_info *ti;
+ int err;
+
+- if (!sci)
++ if (sb_rdonly(sb) || unlikely(!sci))
+ return -EROFS;
+
+ /* A call inside transactions causes a deadlock. */
+@@ -2282,7 +2282,7 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
+ struct nilfs_transaction_info ti;
+ int err = 0;
+
+- if (!sci)
++ if (sb_rdonly(sb) || unlikely(!sci))
+ return -EROFS;
+
+ nilfs_transaction_lock(sb, &ti, 0);
+@@ -2778,11 +2778,12 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
+
+ if (nilfs->ns_writer) {
+ /*
+- * This happens if the filesystem was remounted
+- * read/write after nilfs_error degenerated it into a
+- * read-only mount.
++ * This happens if the filesystem is made read-only by
++ * __nilfs_error or nilfs_remount and then remounted
++ * read/write. In these cases, reuse the existing
++ * writer.
+ */
+- nilfs_detach_log_writer(sb);
++ return 0;
+ }
+
+ nilfs->ns_writer = nilfs_segctor_new(sb, root);
+diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
+index ba108f915391e..6edb6e0dd61f7 100644
+--- a/fs/nilfs2/super.c
++++ b/fs/nilfs2/super.c
+@@ -1133,8 +1133,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
+ if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
+ goto out;
+ if (*flags & SB_RDONLY) {
+- /* Shutting down log writer */
+- nilfs_detach_log_writer(sb);
+ sb->s_flags |= SB_RDONLY;
+
+ /*
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index 3b4a079c9617c..c8b89b4f94e0e 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -690,9 +690,7 @@ int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
+ {
+ unsigned long ncleansegs;
+
+- down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+ ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
+- up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+ *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
+ return 0;
+ }
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index b3d5f97f16cdb..865e658535b11 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -240,7 +240,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
+ poffset - lfi);
+ else {
+ if (!copy_name) {
+- copy_name = kmalloc(UDF_NAME_LEN,
++ copy_name = kmalloc(UDF_NAME_LEN_CS0,
+ GFP_NOFS);
+ if (!copy_name) {
+ fi = ERR_PTR(-ENOMEM);
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index 7c90b1ab3e00d..594422890f8d8 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -333,6 +333,7 @@
+ #define DATA_DATA \
+ *(.xiptext) \
+ *(DATA_MAIN) \
++ *(.data..decrypted) \
+ *(.ref.data) \
+ *(.data..shared_aligned) /* percpu related */ \
+ MEM_KEEP(init.data*) \
+@@ -975,7 +976,6 @@
+ #ifdef CONFIG_AMD_MEM_ENCRYPT
+ #define PERCPU_DECRYPTED_SECTION \
+ . = ALIGN(PAGE_SIZE); \
+- *(.data..decrypted) \
+ *(.data..percpu..decrypted) \
+ . = ALIGN(PAGE_SIZE);
+ #else
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 1fdddbf3546b4..184b957e28ada 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -348,6 +348,27 @@ struct bpf_verifier_state {
+ iter < frame->allocated_stack / BPF_REG_SIZE; \
+ iter++, reg = bpf_get_spilled_reg(iter, frame))
+
++/* Invoke __expr over regsiters in __vst, setting __state and __reg */
++#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr) \
++ ({ \
++ struct bpf_verifier_state *___vstate = __vst; \
++ int ___i, ___j; \
++ for (___i = 0; ___i <= ___vstate->curframe; ___i++) { \
++ struct bpf_reg_state *___regs; \
++ __state = ___vstate->frame[___i]; \
++ ___regs = __state->regs; \
++ for (___j = 0; ___j < MAX_BPF_REG; ___j++) { \
++ __reg = &___regs[___j]; \
++ (void)(__expr); \
++ } \
++ bpf_for_each_spilled_reg(___j, __state, __reg) { \
++ if (!__reg) \
++ continue; \
++ (void)(__expr); \
++ } \
++ } \
++ })
++
+ /* linked list of verifier states used to prune search */
+ struct bpf_verifier_state_list {
+ struct bpf_verifier_state state;
+diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
+index c3e50e537e397..20631a2463769 100644
+--- a/include/linux/can/dev.h
++++ b/include/linux/can/dev.h
+@@ -147,6 +147,22 @@ static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
+ return priv->ctrlmode & ~priv->ctrlmode_supported;
+ }
+
++/* drop skb if it does not contain a valid CAN frame for sending */
++static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *skb)
++{
++ struct can_priv *priv = netdev_priv(dev);
++
++ if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) {
++ netdev_info_once(dev,
++ "interface in listen only mode, dropping skb\n");
++ kfree_skb(skb);
++ dev->stats.tx_dropped++;
++ return true;
++ }
++
++ return can_dropped_invalid_skb(dev, skb);
++}
++
+ void can_setup(struct net_device *dev);
+
+ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 48f4b645193b7..70d6cb94e5802 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -376,7 +376,7 @@ static inline void sk_psock_report_error(struct sk_psock *psock, int err)
+ }
+
+ struct sk_psock *sk_psock_init(struct sock *sk, int node);
+-void sk_psock_stop(struct sk_psock *psock, bool wait);
++void sk_psock_stop(struct sk_psock *psock);
+
+ #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)
+ int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock);
+diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
+index 463d1ba2232ac..3d61a0ae055d4 100644
+--- a/include/uapi/linux/capability.h
++++ b/include/uapi/linux/capability.h
+@@ -426,7 +426,7 @@ struct vfs_ns_cap_data {
+ */
+
+ #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */
+-#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
++#define CAP_TO_MASK(x) (1U << ((x) & 31)) /* mask for indexed __u32 */
+
+
+ #endif /* _UAPI_LINUX_CAPABILITY_H */
+diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h
+index 095299c75828c..2b9e7feba3f32 100644
+--- a/include/uapi/linux/idxd.h
++++ b/include/uapi/linux/idxd.h
+@@ -29,6 +29,7 @@ enum idxd_scmd_stat {
+ IDXD_SCMD_WQ_NO_SIZE = 0x800e0000,
+ IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
+ IDXD_SCMD_WQ_IRQ_ERR = 0x80100000,
++ IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000,
+ };
+
+ #define IDXD_SCMD_SOFTERR_MASK 0x80000000
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index 25cd724ade184..e2c46889d5fab 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -346,6 +346,8 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
+ tmp = READ_ONCE(sqe->off);
+ if (tmp > USHRT_MAX)
+ return -E2BIG;
++ if (tmp + p->nbufs >= USHRT_MAX)
++ return -EINVAL;
+ p->bid = tmp;
+ return 0;
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 8b5ea7f6b5365..69fb46fdf7635 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1011,12 +1011,17 @@ out:
+ */
+ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
+ {
++ void *new_arr;
++
+ if (!new_n || old_n == new_n)
+ goto out;
+
+- arr = krealloc_array(arr, new_n, size, GFP_KERNEL);
+- if (!arr)
++ new_arr = krealloc_array(arr, new_n, size, GFP_KERNEL);
++ if (!new_arr) {
++ kfree(arr);
+ return NULL;
++ }
++ arr = new_arr;
+
+ if (new_n > old_n)
+ memset(arr + old_n * size, 0, (new_n - old_n) * size);
+@@ -6495,31 +6500,15 @@ static int check_func_proto(const struct bpf_func_proto *fn, int func_id,
+ /* Packet data might have moved, any old PTR_TO_PACKET[_META,_END]
+ * are now invalid, so turn them into unknown SCALAR_VALUE.
+ */
+-static void __clear_all_pkt_pointers(struct bpf_verifier_env *env,
+- struct bpf_func_state *state)
++static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
+ {
+- struct bpf_reg_state *regs = state->regs, *reg;
+- int i;
+-
+- for (i = 0; i < MAX_BPF_REG; i++)
+- if (reg_is_pkt_pointer_any(®s[i]))
+- mark_reg_unknown(env, regs, i);
++ struct bpf_func_state *state;
++ struct bpf_reg_state *reg;
+
+- bpf_for_each_spilled_reg(i, state, reg) {
+- if (!reg)
+- continue;
++ bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
+ if (reg_is_pkt_pointer_any(reg))
+ __mark_reg_unknown(env, reg);
+- }
+-}
+-
+-static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
+-{
+- struct bpf_verifier_state *vstate = env->cur_state;
+- int i;
+-
+- for (i = 0; i <= vstate->curframe; i++)
+- __clear_all_pkt_pointers(env, vstate->frame[i]);
++ }));
+ }
+
+ enum {
+@@ -6548,41 +6537,28 @@ static void mark_pkt_end(struct bpf_verifier_state *vstate, int regn, bool range
+ reg->range = AT_PKT_END;
+ }
+
+-static void release_reg_references(struct bpf_verifier_env *env,
+- struct bpf_func_state *state,
+- int ref_obj_id)
+-{
+- struct bpf_reg_state *regs = state->regs, *reg;
+- int i;
+-
+- for (i = 0; i < MAX_BPF_REG; i++)
+- if (regs[i].ref_obj_id == ref_obj_id)
+- mark_reg_unknown(env, regs, i);
+-
+- bpf_for_each_spilled_reg(i, state, reg) {
+- if (!reg)
+- continue;
+- if (reg->ref_obj_id == ref_obj_id)
+- __mark_reg_unknown(env, reg);
+- }
+-}
+-
+ /* The pointer with the specified id has released its reference to kernel
+ * resources. Identify all copies of the same pointer and clear the reference.
+ */
+ static int release_reference(struct bpf_verifier_env *env,
+ int ref_obj_id)
+ {
+- struct bpf_verifier_state *vstate = env->cur_state;
++ struct bpf_func_state *state;
++ struct bpf_reg_state *reg;
+ int err;
+- int i;
+
+ err = release_reference_state(cur_func(env), ref_obj_id);
+ if (err)
+ return err;
+
+- for (i = 0; i <= vstate->curframe; i++)
+- release_reg_references(env, vstate->frame[i], ref_obj_id);
++ bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
++ if (reg->ref_obj_id == ref_obj_id) {
++ if (!env->allow_ptr_leaks)
++ __mark_reg_not_init(env, reg);
++ else
++ __mark_reg_unknown(env, reg);
++ }
++ }));
+
+ return 0;
+ }
+@@ -9278,34 +9254,14 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ return 0;
+ }
+
+-static void __find_good_pkt_pointers(struct bpf_func_state *state,
+- struct bpf_reg_state *dst_reg,
+- enum bpf_reg_type type, int new_range)
+-{
+- struct bpf_reg_state *reg;
+- int i;
+-
+- for (i = 0; i < MAX_BPF_REG; i++) {
+- reg = &state->regs[i];
+- if (reg->type == type && reg->id == dst_reg->id)
+- /* keep the maximum range already checked */
+- reg->range = max(reg->range, new_range);
+- }
+-
+- bpf_for_each_spilled_reg(i, state, reg) {
+- if (!reg)
+- continue;
+- if (reg->type == type && reg->id == dst_reg->id)
+- reg->range = max(reg->range, new_range);
+- }
+-}
+-
+ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
+ struct bpf_reg_state *dst_reg,
+ enum bpf_reg_type type,
+ bool range_right_open)
+ {
+- int new_range, i;
++ struct bpf_func_state *state;
++ struct bpf_reg_state *reg;
++ int new_range;
+
+ if (dst_reg->off < 0 ||
+ (dst_reg->off == 0 && range_right_open))
+@@ -9370,9 +9326,11 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
+ * the range won't allow anything.
+ * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16.
+ */
+- for (i = 0; i <= vstate->curframe; i++)
+- __find_good_pkt_pointers(vstate->frame[i], dst_reg, type,
+- new_range);
++ bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++ if (reg->type == type && reg->id == dst_reg->id)
++ /* keep the maximum range already checked */
++ reg->range = max(reg->range, new_range);
++ }));
+ }
+
+ static int is_branch32_taken(struct bpf_reg_state *reg, u32 val, u8 opcode)
+@@ -9861,7 +9819,7 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
+
+ if (!reg_may_point_to_spin_lock(reg)) {
+ /* For not-NULL ptr, reg->ref_obj_id will be reset
+- * in release_reg_references().
++ * in release_reference().
+ *
+ * reg->id is still used by spin_lock ptr. Other
+ * than spin_lock ptr type, reg->id can be reset.
+@@ -9871,22 +9829,6 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
+ }
+ }
+
+-static void __mark_ptr_or_null_regs(struct bpf_func_state *state, u32 id,
+- bool is_null)
+-{
+- struct bpf_reg_state *reg;
+- int i;
+-
+- for (i = 0; i < MAX_BPF_REG; i++)
+- mark_ptr_or_null_reg(state, &state->regs[i], id, is_null);
+-
+- bpf_for_each_spilled_reg(i, state, reg) {
+- if (!reg)
+- continue;
+- mark_ptr_or_null_reg(state, reg, id, is_null);
+- }
+-}
+-
+ /* The logic is similar to find_good_pkt_pointers(), both could eventually
+ * be folded together at some point.
+ */
+@@ -9894,10 +9836,9 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
+ bool is_null)
+ {
+ struct bpf_func_state *state = vstate->frame[vstate->curframe];
+- struct bpf_reg_state *regs = state->regs;
++ struct bpf_reg_state *regs = state->regs, *reg;
+ u32 ref_obj_id = regs[regno].ref_obj_id;
+ u32 id = regs[regno].id;
+- int i;
+
+ if (ref_obj_id && ref_obj_id == id && is_null)
+ /* regs[regno] is in the " == NULL" branch.
+@@ -9906,8 +9847,9 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
+ */
+ WARN_ON_ONCE(release_reference_state(state, id));
+
+- for (i = 0; i <= vstate->curframe; i++)
+- __mark_ptr_or_null_regs(vstate->frame[i], id, is_null);
++ bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++ mark_ptr_or_null_reg(state, reg, id, is_null);
++ }));
+ }
+
+ static bool try_match_pkt_pointers(const struct bpf_insn *insn,
+@@ -10020,23 +9962,11 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate,
+ {
+ struct bpf_func_state *state;
+ struct bpf_reg_state *reg;
+- int i, j;
+
+- for (i = 0; i <= vstate->curframe; i++) {
+- state = vstate->frame[i];
+- for (j = 0; j < MAX_BPF_REG; j++) {
+- reg = &state->regs[j];
+- if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
+- *reg = *known_reg;
+- }
+-
+- bpf_for_each_spilled_reg(j, state, reg) {
+- if (!reg)
+- continue;
+- if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
+- *reg = *known_reg;
+- }
+- }
++ bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++ if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
++ *reg = *known_reg;
++ }));
+ }
+
+ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
+index 4e51466c4e74d..dafe7e71329b8 100644
+--- a/mm/damon/dbgfs.c
++++ b/mm/damon/dbgfs.c
+@@ -882,6 +882,7 @@ out:
+ static int dbgfs_rm_context(char *name)
+ {
+ struct dentry *root, *dir, **new_dirs;
++ struct inode *inode;
+ struct damon_ctx **new_ctxs;
+ int i, j;
+ int ret = 0;
+@@ -897,6 +898,12 @@ static int dbgfs_rm_context(char *name)
+ if (!dir)
+ return -ENOENT;
+
++ inode = d_inode(dir);
++ if (!S_ISDIR(inode->i_mode)) {
++ ret = -EINVAL;
++ goto out_dput;
++ }
++
+ new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs),
+ GFP_KERNEL);
+ if (!new_dirs) {
+diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
+index 20f414c0379f9..fffb78378d6c0 100644
+--- a/mm/hugetlb_vmemmap.c
++++ b/mm/hugetlb_vmemmap.c
+@@ -11,6 +11,7 @@
+ #define pr_fmt(fmt) "HugeTLB: " fmt
+
+ #include <linux/pgtable.h>
++#include <linux/moduleparam.h>
+ #include <linux/bootmem_info.h>
+ #include <asm/pgalloc.h>
+ #include <asm/tlbflush.h>
+diff --git a/mm/memremap.c b/mm/memremap.c
+index 58b20c3c300b8..b893e37c95c1e 100644
+--- a/mm/memremap.c
++++ b/mm/memremap.c
+@@ -330,6 +330,7 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
+ WARN(1, "File system DAX not supported\n");
+ return ERR_PTR(-EINVAL);
+ }
++ params.pgprot = pgprot_decrypted(params.pgprot);
+ break;
+ case MEMORY_DEVICE_GENERIC:
+ break;
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
+index 7327b2573f7c2..9fb3a8bd21102 100644
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -64,7 +64,7 @@ int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
+ pte_t _dst_pte, *dst_pte;
+ bool writable = dst_vma->vm_flags & VM_WRITE;
+ bool vm_shared = dst_vma->vm_flags & VM_SHARED;
+- bool page_in_cache = page->mapping;
++ bool page_in_cache = page_mapping(page);
+ spinlock_t *ptl;
+ struct inode *inode;
+ pgoff_t offset, max_off;
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index 1fb49d51b25d6..e48ccf7cf2007 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -451,7 +451,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
+
+ /* insert new receiver (dev,canid,mask) -> (func,data) */
+
+- if (dev && dev->type != ARPHRD_CAN)
++ if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev)))
+ return -ENODEV;
+
+ if (dev && !net_eq(net, dev_net(dev)))
+diff --git a/net/can/isotp.c b/net/can/isotp.c
+index 43a27d19cdacf..58e7d79ccd292 100644
+--- a/net/can/isotp.c
++++ b/net/can/isotp.c
+@@ -111,6 +111,9 @@ MODULE_ALIAS("can-proto-6");
+ #define ISOTP_FC_WT 1 /* wait */
+ #define ISOTP_FC_OVFLW 2 /* overflow */
+
++#define ISOTP_FC_TIMEOUT 1 /* 1 sec */
++#define ISOTP_ECHO_TIMEOUT 2 /* 2 secs */
++
+ enum {
+ ISOTP_IDLE = 0,
+ ISOTP_WAIT_FIRST_FC,
+@@ -258,7 +261,8 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
+ so->lastrxcf_tstamp = ktime_set(0, 0);
+
+ /* start rx timeout watchdog */
+- hrtimer_start(&so->rxtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT);
++ hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
++ HRTIMER_MODE_REL_SOFT);
+ return 0;
+ }
+
+@@ -344,6 +348,8 @@ static int check_pad(struct isotp_sock *so, struct canfd_frame *cf,
+ return 0;
+ }
+
++static void isotp_send_cframe(struct isotp_sock *so);
++
+ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
+ {
+ struct sock *sk = &so->sk;
+@@ -398,14 +404,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
+ case ISOTP_FC_CTS:
+ so->tx.bs = 0;
+ so->tx.state = ISOTP_SENDING;
+- /* start cyclic timer for sending CF frame */
+- hrtimer_start(&so->txtimer, so->tx_gap,
++ /* send CF frame and enable echo timeout handling */
++ hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0),
+ HRTIMER_MODE_REL_SOFT);
++ isotp_send_cframe(so);
+ break;
+
+ case ISOTP_FC_WT:
+ /* start timer to wait for next FC frame */
+- hrtimer_start(&so->txtimer, ktime_set(1, 0),
++ hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ HRTIMER_MODE_REL_SOFT);
+ break;
+
+@@ -600,7 +607,7 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
+ /* perform blocksize handling, if enabled */
+ if (!so->rxfc.bs || ++so->rx.bs < so->rxfc.bs) {
+ /* start rx timeout watchdog */
+- hrtimer_start(&so->rxtimer, ktime_set(1, 0),
++ hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ HRTIMER_MODE_REL_SOFT);
+ return 0;
+ }
+@@ -829,7 +836,7 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
+ struct isotp_sock *so = isotp_sk(sk);
+ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+
+- /* only handle my own local echo skb's */
++ /* only handle my own local echo CF/SF skb's (no FF!) */
+ if (skb->sk != sk || so->cfecho != *(u32 *)cf->data)
+ return;
+
+@@ -849,13 +856,16 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
+ if (so->txfc.bs && so->tx.bs >= so->txfc.bs) {
+ /* stop and wait for FC with timeout */
+ so->tx.state = ISOTP_WAIT_FC;
+- hrtimer_start(&so->txtimer, ktime_set(1, 0),
++ hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ HRTIMER_MODE_REL_SOFT);
+ return;
+ }
+
+ /* no gap between data frames needed => use burst mode */
+ if (!so->tx_gap) {
++ /* enable echo timeout handling */
++ hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0),
++ HRTIMER_MODE_REL_SOFT);
+ isotp_send_cframe(so);
+ return;
+ }
+@@ -879,7 +889,7 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
+ /* start timeout for unlikely lost echo skb */
+ hrtimer_set_expires(&so->txtimer,
+ ktime_add(ktime_get(),
+- ktime_set(2, 0)));
++ ktime_set(ISOTP_ECHO_TIMEOUT, 0)));
+ restart = HRTIMER_RESTART;
+
+ /* push out the next consecutive frame */
+@@ -907,7 +917,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
+ break;
+
+ default:
+- WARN_ON_ONCE(1);
++ WARN_ONCE(1, "can-isotp: tx timer state %08X cfecho %08X\n",
++ so->tx.state, so->cfecho);
+ }
+
+ return restart;
+@@ -923,7 +934,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ struct canfd_frame *cf;
+ int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0;
+ int wait_tx_done = (so->opt.flags & CAN_ISOTP_WAIT_TX_DONE) ? 1 : 0;
+- s64 hrtimer_sec = 0;
++ s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT;
+ int off;
+ int err;
+
+@@ -942,6 +953,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ if (err)
+ goto err_out;
++
++ so->tx.state = ISOTP_SENDING;
+ }
+
+ if (!size || size > MAX_MSG_LENGTH) {
+@@ -986,6 +999,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ cf = (struct canfd_frame *)skb->data;
+ skb_put_zero(skb, so->ll.mtu);
+
++ /* cfecho should have been zero'ed by init / former isotp_rcv_echo() */
++ if (so->cfecho)
++ pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho);
++
+ /* check for single frame transmission depending on TX_DL */
+ if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) {
+ /* The message size generally fits into a SingleFrame - good.
+@@ -1011,11 +1028,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ else
+ cf->data[ae] |= size;
+
+- so->tx.state = ISOTP_IDLE;
+- wake_up_interruptible(&so->wait);
+-
+- /* don't enable wait queue for a single frame transmission */
+- wait_tx_done = 0;
++ /* set CF echo tag for isotp_rcv_echo() (SF-mode) */
++ so->cfecho = *(u32 *)cf->data;
+ } else {
+ /* send first frame */
+
+@@ -1031,31 +1045,23 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ /* disable wait for FCs due to activated block size */
+ so->txfc.bs = 0;
+
+- /* cfecho should have been zero'ed by init */
+- if (so->cfecho)
+- pr_notice_once("can-isotp: no fc cfecho %08X\n",
+- so->cfecho);
+-
+- /* set consecutive frame echo tag */
++ /* set CF echo tag for isotp_rcv_echo() (CF-mode) */
+ so->cfecho = *(u32 *)cf->data;
+-
+- /* switch directly to ISOTP_SENDING state */
+- so->tx.state = ISOTP_SENDING;
+-
+- /* start timeout for unlikely lost echo skb */
+- hrtimer_sec = 2;
+ } else {
+ /* standard flow control check */
+ so->tx.state = ISOTP_WAIT_FIRST_FC;
+
+ /* start timeout for FC */
+- hrtimer_sec = 1;
+- }
++ hrtimer_sec = ISOTP_FC_TIMEOUT;
+
+- hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0),
+- HRTIMER_MODE_REL_SOFT);
++ /* no CF echo tag for isotp_rcv_echo() (FF-mode) */
++ so->cfecho = 0;
++ }
+ }
+
++ hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0),
++ HRTIMER_MODE_REL_SOFT);
++
+ /* send the first or only CAN frame */
+ cf->flags = so->ll.tx_flags;
+
+@@ -1068,8 +1074,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ __func__, ERR_PTR(err));
+
+ /* no transmission -> no timeout monitoring */
+- if (hrtimer_sec)
+- hrtimer_cancel(&so->txtimer);
++ hrtimer_cancel(&so->txtimer);
+
+ /* reset consecutive frame echo tag */
+ so->cfecho = 0;
+diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
+index 8452b0fbb78c9..82671a882716f 100644
+--- a/net/can/j1939/main.c
++++ b/net/can/j1939/main.c
+@@ -332,6 +332,9 @@ int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb)
+ /* re-claim the CAN_HDR from the SKB */
+ cf = skb_push(skb, J1939_CAN_HDR);
+
++ /* initialize header structure */
++ memset(cf, 0, J1939_CAN_HDR);
++
+ /* make it a full can frame again */
+ skb_put(skb, J1939_CAN_FTR + (8 - dlc));
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 5e1a8eeb5e322..d9c19ae05fe67 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4031,23 +4031,25 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
+ int i = 0;
+ int pos;
+
+- if (list_skb && !list_skb->head_frag && skb_headlen(list_skb) &&
+- (skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY)) {
+- /* gso_size is untrusted, and we have a frag_list with a linear
+- * non head_frag head.
+- *
+- * (we assume checking the first list_skb member suffices;
+- * i.e if either of the list_skb members have non head_frag
+- * head, then the first one has too).
+- *
+- * If head_skb's headlen does not fit requested gso_size, it
+- * means that the frag_list members do NOT terminate on exact
+- * gso_size boundaries. Hence we cannot perform skb_frag_t page
+- * sharing. Therefore we must fallback to copying the frag_list
+- * skbs; we do so by disabling SG.
+- */
+- if (mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb))
+- features &= ~NETIF_F_SG;
++ if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) &&
++ mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) {
++ struct sk_buff *check_skb;
++
++ for (check_skb = list_skb; check_skb; check_skb = check_skb->next) {
++ if (skb_headlen(check_skb) && !check_skb->head_frag) {
++ /* gso_size is untrusted, and we have a frag_list with
++ * a linear non head_frag item.
++ *
++ * If head_skb's headlen does not fit requested gso_size,
++ * it means that the frag_list members do NOT terminate
++ * on exact gso_size boundaries. Hence we cannot perform
++ * skb_frag_t page sharing. Therefore we must fallback to
++ * copying the frag_list skbs; we do so by disabling SG.
++ */
++ features &= ~NETIF_F_SG;
++ break;
++ }
++ }
+ }
+
+ __skb_push(head_skb, doffset);
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 1efdc47a999b4..e6b9ced3eda82 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -803,16 +803,13 @@ static void sk_psock_link_destroy(struct sk_psock *psock)
+ }
+ }
+
+-void sk_psock_stop(struct sk_psock *psock, bool wait)
++void sk_psock_stop(struct sk_psock *psock)
+ {
+ spin_lock_bh(&psock->ingress_lock);
+ sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
+ sk_psock_cork_free(psock);
+ __sk_psock_zap_ingress(psock);
+ spin_unlock_bh(&psock->ingress_lock);
+-
+- if (wait)
+- cancel_work_sync(&psock->work);
+ }
+
+ static void sk_psock_done_strp(struct sk_psock *psock);
+@@ -850,7 +847,7 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock)
+ sk_psock_stop_verdict(sk, psock);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+- sk_psock_stop(psock, false);
++ sk_psock_stop(psock);
+
+ INIT_RCU_WORK(&psock->rwork, sk_psock_destroy);
+ queue_rcu_work(system_wq, &psock->rwork);
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 9a9fb9487d636..632df0c525625 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -1596,7 +1596,7 @@ void sock_map_destroy(struct sock *sk)
+ saved_destroy = psock->saved_destroy;
+ sock_map_remove_links(sk, psock);
+ rcu_read_unlock();
+- sk_psock_stop(psock, false);
++ sk_psock_stop(psock);
+ sk_psock_put(sk, psock);
+ saved_destroy(sk);
+ }
+@@ -1619,9 +1619,10 @@ void sock_map_close(struct sock *sk, long timeout)
+ saved_close = psock->saved_close;
+ sock_map_remove_links(sk, psock);
+ rcu_read_unlock();
+- sk_psock_stop(psock, true);
+- sk_psock_put(sk, psock);
++ sk_psock_stop(psock);
+ release_sock(sk);
++ cancel_work_sync(&psock->work);
++ sk_psock_put(sk, psock);
+ saved_close(sk, timeout);
+ }
+ EXPORT_SYMBOL_GPL(sock_map_close);
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5fbd0a5b48f7e..cdd4f2f60f0c6 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3648,7 +3648,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
+ case TCP_REPAIR_OPTIONS:
+ if (!tp->repair)
+ err = -EINVAL;
+- else if (sk->sk_state == TCP_ESTABLISHED)
++ else if (sk->sk_state == TCP_ESTABLISHED && !tp->bytes_sent)
+ err = tcp_repair_options_est(sk, optval, optlen);
+ else
+ err = -EPERM;
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index c501c329b1dbe..cf9c3e8f7ccbf 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -278,7 +278,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+ {
+ bool cork = false, enospc = sk_msg_full(msg);
+ struct sock *sk_redir;
+- u32 tosend, delta = 0;
++ u32 tosend, origsize, sent, delta = 0;
+ u32 eval = __SK_NONE;
+ int ret;
+
+@@ -333,10 +333,12 @@ more_data:
+ cork = true;
+ psock->cork = NULL;
+ }
+- sk_msg_return(sk, msg, msg->sg.size);
++ sk_msg_return(sk, msg, tosend);
+ release_sock(sk);
+
++ origsize = msg->sg.size;
+ ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags);
++ sent = origsize - msg->sg.size;
+
+ if (eval == __SK_REDIRECT)
+ sock_put(sk_redir);
+@@ -375,7 +377,7 @@ more_data:
+ msg->sg.data[msg->sg.start].page_link &&
+ msg->sg.data[msg->sg.start].length) {
+ if (eval == __SK_REDIRECT)
+- sk_mem_charge(sk, msg->sg.size);
++ sk_mem_charge(sk, tosend - sent);
+ goto more_data;
+ }
+ }
+diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
+index 8a22486cf2702..17ac45aa7194c 100644
+--- a/net/ipv6/addrlabel.c
++++ b/net/ipv6/addrlabel.c
+@@ -437,6 +437,7 @@ static void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
+ {
+ struct ifaddrlblmsg *ifal = nlmsg_data(nlh);
+ ifal->ifal_family = AF_INET6;
++ ifal->__ifal_reserved = 0;
+ ifal->ifal_prefixlen = prefixlen;
+ ifal->ifal_flags = 0;
+ ifal->ifal_index = ifindex;
+diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c
+index 8ca7d45d6daae..c1f964e9991cd 100644
+--- a/net/mac80211/s1g.c
++++ b/net/mac80211/s1g.c
+@@ -112,6 +112,9 @@ ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
+ goto out;
+ }
+
++ /* TWT Information not supported yet */
++ twt->control |= IEEE80211_TWT_CONTROL_RX_DISABLED;
++
+ drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
+ out:
+ ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 13249e97a0692..d2c4f9226f947 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -4379,6 +4379,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+ if (likely(!is_multicast_ether_addr(eth->h_dest)))
+ goto normal;
+
++ if (unlikely(!ieee80211_sdata_running(sdata))) {
++ kfree_skb(skb);
++ return NETDEV_TX_OK;
++ }
++
+ if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) {
+ struct sk_buff_head queue;
+
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index b6b5e496fa403..fc9e728b6333a 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -665,12 +665,14 @@ static __init int mctp_init(void)
+
+ rc = mctp_neigh_init();
+ if (rc)
+- goto err_unreg_proto;
++ goto err_unreg_routes;
+
+ mctp_device_init();
+
+ return 0;
+
++err_unreg_routes:
++ mctp_routes_exit();
+ err_unreg_proto:
+ proto_unregister(&mctp_proto);
+ err_unreg_sock:
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 2155f15a074cd..f9a80b82dc511 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -1400,7 +1400,7 @@ int __init mctp_routes_init(void)
+ return register_pernet_subsys(&mctp_net_ops);
+ }
+
+-void __exit mctp_routes_exit(void)
++void mctp_routes_exit(void)
+ {
+ unregister_pernet_subsys(&mctp_net_ops);
+ rtnl_unregister(PF_MCTP, RTM_DELROUTE);
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 879f4a1a27d54..42e370575c304 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -10090,7 +10090,8 @@ static void __net_exit nf_tables_exit_net(struct net *net)
+ struct nftables_pernet *nft_net = nft_pernet(net);
+
+ mutex_lock(&nft_net->commit_mutex);
+- if (!list_empty(&nft_net->commit_list))
++ if (!list_empty(&nft_net->commit_list) ||
++ !list_empty(&nft_net->module_list))
+ __nf_tables_abort(net, NFNL_ABORT_NONE);
+ __nft_release_tables(net);
+ mutex_unlock(&nft_net->commit_mutex);
+diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
+index 9c44518cb70ff..6d18fb3468683 100644
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -294,6 +294,7 @@ replay:
+ nfnl_lock(subsys_id);
+ if (nfnl_dereference_protected(subsys_id) != ss ||
+ nfnetlink_find_client(type, ss) != nc) {
++ nfnl_unlock(subsys_id);
+ err = -EAGAIN;
+ break;
+ }
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
+index 0749df80454d4..ce00f271ca6b2 100644
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -880,7 +880,7 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg)
+ };
+
+ ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);
+- if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query))
++ if (TLV_GET_DATA_LEN(msg->req) < (int)sizeof(struct tipc_name_table_query))
+ return -EINVAL;
+
+ depth = ntohl(ntq->depth);
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index d5c7a5aa68532..c3d950d294329 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1084,6 +1084,8 @@ MODULE_FIRMWARE("regulatory.db");
+
+ static int query_regdb_file(const char *alpha2)
+ {
++ int err;
++
+ ASSERT_RTNL();
+
+ if (regdb)
+@@ -1093,9 +1095,13 @@ static int query_regdb_file(const char *alpha2)
+ if (!alpha2)
+ return -ENOMEM;
+
+- return request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
+- ®_pdev->dev, GFP_KERNEL,
+- (void *)alpha2, regdb_fw_cb);
++ err = request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
++ ®_pdev->dev, GFP_KERNEL,
++ (void *)alpha2, regdb_fw_cb);
++ if (err)
++ kfree(alpha2);
++
++ return err;
+ }
+
+ int reg_reload_regdb(void)
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 39fb9cc25cdca..9067e4b70855a 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -1674,7 +1674,9 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ if (old == rcu_access_pointer(known->pub.ies))
+ rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+
+- cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
++ cfg80211_update_hidden_bsses(known,
++ rcu_access_pointer(new->pub.beacon_ies),
++ old);
+
+ if (old)
+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
+index e55c0421718b3..2ca33fd5a5757 100644
+--- a/sound/arm/pxa2xx-ac97-lib.c
++++ b/sound/arm/pxa2xx-ac97-lib.c
+@@ -402,8 +402,10 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
+ goto err_clk2;
+
+ irq = platform_get_irq(dev, 0);
+- if (!irq)
++ if (irq < 0) {
++ ret = irq;
+ goto err_irq;
++ }
+
+ ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
+ if (ret < 0)
+diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
+index cfcd8eff41398..d311cff8d5bef 100644
+--- a/sound/core/memalloc.c
++++ b/sound/core/memalloc.c
+@@ -9,6 +9,7 @@
+ #include <linux/slab.h>
+ #include <linux/mm.h>
+ #include <linux/dma-mapping.h>
++#include <linux/dma-map-ops.h>
+ #include <linux/genalloc.h>
+ #include <linux/highmem.h>
+ #include <linux/vmalloc.h>
+@@ -528,17 +529,17 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
+
+ sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
+ DEFAULT_GFP, 0);
+- if (!sgt) {
+ #ifdef CONFIG_SND_DMA_SGBUF
++ if (!sgt && !get_dma_ops(dmab->dev.dev)) {
+ if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
+ dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
+ else
+ dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK;
+ return snd_dma_sg_fallback_alloc(dmab, size);
+-#else
+- return NULL;
+-#endif
+ }
++#endif
++ if (!sgt)
++ return NULL;
+
+ dmab->dev.need_sync = dma_need_sync(dmab->dev.dev,
+ sg_dma_address(sgt->sgl));
+@@ -874,7 +875,7 @@ static const struct snd_malloc_ops snd_dma_noncoherent_ops = {
+ /*
+ * Entry points
+ */
+-static const struct snd_malloc_ops *dma_ops[] = {
++static const struct snd_malloc_ops *snd_dma_ops[] = {
+ [SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops,
+ [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops,
+ #ifdef CONFIG_HAS_DMA
+@@ -900,7 +901,7 @@ static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)
+ if (WARN_ON_ONCE(!dmab))
+ return NULL;
+ if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN ||
+- dmab->dev.type >= ARRAY_SIZE(dma_ops)))
++ dmab->dev.type >= ARRAY_SIZE(snd_dma_ops)))
+ return NULL;
+- return dma_ops[dmab->dev.type];
++ return snd_dma_ops[dmab->dev.type];
+ }
+diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
+index e47de49a32e3e..62a9615dcf529 100644
+--- a/sound/hda/hdac_sysfs.c
++++ b/sound/hda/hdac_sysfs.c
+@@ -346,8 +346,10 @@ static int add_widget_node(struct kobject *parent, hda_nid_t nid,
+ return -ENOMEM;
+ kobject_init(kobj, &widget_ktype);
+ err = kobject_add(kobj, parent, "%02x", nid);
+- if (err < 0)
++ if (err < 0) {
++ kobject_put(kobj);
+ return err;
++ }
+ err = sysfs_create_group(kobj, group);
+ if (err < 0) {
+ kobject_put(kobj);
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 1631e1de84046..8f8b9ebe5c5ff 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2718,6 +2718,9 @@ static const struct pci_device_id azx_ids[] = {
+ { PCI_DEVICE(0x1002, 0xab28),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+ AZX_DCAPS_PM_RUNTIME },
++ { PCI_DEVICE(0x1002, 0xab30),
++ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
++ AZX_DCAPS_PM_RUNTIME },
+ { PCI_DEVICE(0x1002, 0xab38),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+ AZX_DCAPS_PM_RUNTIME },
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 208933792787d..801dd8d44953b 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -1306,6 +1306,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
+ SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
+ SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
+ SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
++ SND_PCI_QUIRK(0x3842, 0x1055, "EVGA Z390 DARK", QUIRK_R3DI),
+ SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
+ SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
+ SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 6e25a0f89f6b4..b7cccbef401ce 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9414,6 +9414,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
++ SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+@@ -9618,6 +9619,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+ SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+ SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
++ SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
+ SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index a5ed11ea11456..26268ffb82742 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -742,6 +742,18 @@ get_alias_quirk(struct usb_device *dev, unsigned int id)
+ return NULL;
+ }
+
++/* register card if we reach to the last interface or to the specified
++ * one given via option
++ */
++static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
++{
++ if (check_delayed_register_option(chip) == ifnum ||
++ chip->last_iface == ifnum ||
++ usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface)))
++ return snd_card_register(chip->card);
++ return 0;
++}
++
+ /*
+ * probe the active usb device
+ *
+@@ -880,15 +892,9 @@ static int usb_audio_probe(struct usb_interface *intf,
+ chip->need_delayed_register = false; /* clear again */
+ }
+
+- /* register card if we reach to the last interface or to the specified
+- * one given via option
+- */
+- if (check_delayed_register_option(chip) == ifnum ||
+- usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
+- err = snd_card_register(chip->card);
+- if (err < 0)
+- goto __error;
+- }
++ err = try_to_register_card(chip, ifnum);
++ if (err < 0)
++ goto __error_no_register;
+
+ if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) {
+ /* don't want to fail when snd_media_device_create() fails */
+@@ -907,6 +913,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+ return 0;
+
+ __error:
++ /* in the case of error in secondary interface, still try to register */
++ if (chip)
++ try_to_register_card(chip, ifnum);
++
++ __error_no_register:
+ if (chip) {
+ /* chip->active is inside the chip->card object,
+ * decrement before memory is possibly returned.
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 06dfdd45cff8c..874fcf245747f 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -2049,6 +2049,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ }
+ }
+ },
++{
++ /* M-Audio Micro */
++ USB_DEVICE_VENDOR_SPEC(0x0763, 0x201a),
++},
+ {
+ USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index eadac586bcc83..250bda7cda075 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1913,6 +1913,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
+ /* XMOS based USB DACs */
+ switch (chip->usb_id) {
+ case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */
++ case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */
+ case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
+ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
+ if (fp->altsetting == 2)
+diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
+index 6674bdb096f34..ee71f15eed7f2 100644
+--- a/tools/arch/x86/include/asm/msr-index.h
++++ b/tools/arch/x86/include/asm/msr-index.h
+@@ -530,6 +530,11 @@
+ #define MSR_AMD64_CPUID_FN_1 0xc0011004
+ #define MSR_AMD64_LS_CFG 0xc0011020
+ #define MSR_AMD64_DC_CFG 0xc0011022
++
++#define MSR_AMD64_DE_CFG 0xc0011029
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT)
++
+ #define MSR_AMD64_BU_CFG2 0xc001102a
+ #define MSR_AMD64_IBSFETCHCTL 0xc0011030
+ #define MSR_AMD64_IBSFETCHLINAD 0xc0011031
+@@ -632,9 +637,6 @@
+ #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL
+ #define FAM10H_MMIO_CONF_BASE_SHIFT 20
+ #define MSR_FAM10H_NODE_ID 0xc001100c
+-#define MSR_F10H_DECFG 0xc0011029
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
+
+ /* K8 MSRs */
+ #define MSR_K8_TOP_MEM1 0xc001001a
+diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
+index 067e9ea59e3b0..3bdbc0ce75b15 100644
+--- a/tools/bpf/bpftool/common.c
++++ b/tools/bpf/bpftool/common.c
+@@ -300,6 +300,9 @@ int do_pin_any(int argc, char **argv, int (*get_fd)(int *, char ***))
+ int err;
+ int fd;
+
++ if (!REQ_ARGS(3))
++ return -EINVAL;
++
+ fd = get_fd(&argc, &argv);
+ if (fd < 0)
+ return fd;
+diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
+index 4b9c71faa01ad..f136309044dab 100644
+--- a/tools/perf/.gitignore
++++ b/tools/perf/.gitignore
+@@ -4,6 +4,7 @@ PERF-GUI-VARS
+ PERF-VERSION-FILE
+ FEATURE-DUMP
+ perf
++!include/perf/
+ perf-read-vdso32
+ perf-read-vdsox32
+ perf-help
+diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh
+index ec801cffae6bc..d7ff5c4b4da4c 100755
+--- a/tools/perf/tests/shell/test_brstack.sh
++++ b/tools/perf/tests/shell/test_brstack.sh
+@@ -13,7 +13,10 @@ fi
+
+ # skip the test if the hardware doesn't support branch stack sampling
+ # and if the architecture doesn't support filter types: any,save_type,u
+-perf record -b -o- -B --branch-filter any,save_type,u true > /dev/null 2>&1 || exit 2
++if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then
++ echo "skip: system doesn't support filter types: any,save_type,u"
++ exit 2
++fi
+
+ TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
+
+diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
+index bb4aa88c50a82..35264b5684d09 100644
+--- a/tools/perf/util/parse-branch-options.c
++++ b/tools/perf/util/parse-branch-options.c
+@@ -101,8 +101,10 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
+ /*
+ * cannot set it twice, -b + --branch-filter for instance
+ */
+- if (*mode)
++ if (*mode) {
++ pr_err("Error: Can't use --branch-any (-b) with --branch-filter (-j).\n");
+ return -1;
++ }
+
+ return parse_branch_str(str, mode);
+ }
+diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
+index b82844cb0ce77..7c5f5219dbff2 100644
+--- a/tools/perf/util/stat-display.c
++++ b/tools/perf/util/stat-display.c
+@@ -273,7 +273,7 @@ static void new_line_csv(struct perf_stat_config *config, void *ctx)
+
+ fputc('\n', os->fh);
+ if (os->prefix)
+- fprintf(os->fh, "%s%s", os->prefix, config->csv_sep);
++ fprintf(os->fh, "%s", os->prefix);
+ aggr_printout(config, os->evsel, os->id, os->nr);
+ for (i = 0; i < os->nfields; i++)
+ fputs(config->csv_sep, os->fh);
+@@ -556,7 +556,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
+ [AGGR_CORE] = 2,
+ [AGGR_THREAD] = 1,
+ [AGGR_UNSET] = 0,
+- [AGGR_NODE] = 0,
++ [AGGR_NODE] = 1,
+ };
+
+ pm = config->metric_only ? print_metric_only_csv : print_metric_csv;
+@@ -1126,6 +1126,7 @@ static int aggr_header_lens[] = {
+ [AGGR_SOCKET] = 12,
+ [AGGR_NONE] = 6,
+ [AGGR_THREAD] = 24,
++ [AGGR_NODE] = 6,
+ [AGGR_GLOBAL] = 0,
+ };
+
+@@ -1135,6 +1136,7 @@ static const char *aggr_header_csv[] = {
+ [AGGR_SOCKET] = "socket,cpus",
+ [AGGR_NONE] = "cpu,",
+ [AGGR_THREAD] = "comm-pid,",
++ [AGGR_NODE] = "node,",
+ [AGGR_GLOBAL] = ""
+ };
+
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4c5259828efdc..b76c775f61f99 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -5404,6 +5404,7 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
+ int (*get)(void *, u64 *), int (*set)(void *, u64),
+ const char *fmt)
+ {
++ int ret;
+ struct kvm_stat_data *stat_data = (struct kvm_stat_data *)
+ inode->i_private;
+
+@@ -5415,15 +5416,13 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
+ if (!kvm_get_kvm_safe(stat_data->kvm))
+ return -ENOENT;
+
+- if (simple_attr_open(inode, file, get,
+- kvm_stats_debugfs_mode(stat_data->desc) & 0222
+- ? set : NULL,
+- fmt)) {
++ ret = simple_attr_open(inode, file, get,
++ kvm_stats_debugfs_mode(stat_data->desc) & 0222
++ ? set : NULL, fmt);
++ if (ret)
+ kvm_put_kvm(stat_data->kvm);
+- return -ENOMEM;
+- }
+
+- return 0;
++ return ret;
+ }
+
+ static int kvm_debugfs_release(struct inode *inode, struct file *file)
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-26 11:55 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-26 11:55 UTC (permalink / raw
To: gentoo-commits
commit: 1137db9487524d1e9d14c4ae6ab65a07d73cfdfe
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 26 11:55:30 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Nov 26 11:55:30 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=1137db94
Linux patch 6.0.10
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1009_linux-6.0.10.patch | 10001 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 10005 insertions(+)
diff --git a/0000_README b/0000_README
index bda6a465..bf26e8c8 100644
--- a/0000_README
+++ b/0000_README
@@ -79,6 +79,10 @@ Patch: 1008_linux-6.0.9.patch
From: http://www.kernel.org
Desc: Linux 6.0.9
+Patch: 1009_linux-6.0.10.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.10
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1009_linux-6.0.10.patch b/1009_linux-6.0.10.patch
new file mode 100644
index 00000000..4342593b
--- /dev/null
+++ b/1009_linux-6.0.10.patch
@@ -0,0 +1,10001 @@
+diff --git a/Documentation/driver-api/miscellaneous.rst b/Documentation/driver-api/miscellaneous.rst
+index 304ffb146cf9c..4a5104a368ac6 100644
+--- a/Documentation/driver-api/miscellaneous.rst
++++ b/Documentation/driver-api/miscellaneous.rst
+@@ -16,12 +16,11 @@ Parallel Port Devices
+ 16x50 UART Driver
+ =================
+
+-.. kernel-doc:: drivers/tty/serial/serial_core.c
+- :export:
+-
+ .. kernel-doc:: drivers/tty/serial/8250/8250_core.c
+ :export:
+
++See serial/driver.rst for related APIs.
++
+ Pulse-Width Modulation (PWM)
+ ============================
+
+diff --git a/Documentation/process/code-of-conduct-interpretation.rst b/Documentation/process/code-of-conduct-interpretation.rst
+index 4f8a06b00f608..43da2cc2e3b9b 100644
+--- a/Documentation/process/code-of-conduct-interpretation.rst
++++ b/Documentation/process/code-of-conduct-interpretation.rst
+@@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're
+ uncertain how to handle situations that come up. It will not be
+ considered a violation report unless you want it to be. If you are
+ uncertain about approaching the TAB or any other maintainers, please
+-reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>.
++reach out to our conflict mediator, Joanna Lee <jlee@linuxfoundation.org>.
+
+ In the end, "be kind to each other" is really what the end goal is for
+ everybody. We know everyone is human and we all fail at times, but the
+diff --git a/Makefile b/Makefile
+index a234f16783ede..4f7da26fef784 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 9
++SUBLEVEL = 10
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 29148285f9fc8..1dc3bfac30b68 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -1270,10 +1270,10 @@
+ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+ };
+
+- gpmi: nand-controller@33002000{
++ gpmi: nand-controller@33002000 {
+ compatible = "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+- #size-cells = <1>;
++ #size-cells = <0>;
+ reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm/boot/dts/sama7g5-pinfunc.h b/arch/arm/boot/dts/sama7g5-pinfunc.h
+index 4eb30445d2057..6e87f0d4b8fce 100644
+--- a/arch/arm/boot/dts/sama7g5-pinfunc.h
++++ b/arch/arm/boot/dts/sama7g5-pinfunc.h
+@@ -261,7 +261,7 @@
+ #define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1)
+ #define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1)
+ #define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1)
+-#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3)
++#define PIN_PB2__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB2, 6, 3)
+ #define PIN_PB3 35
+ #define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0)
+ #define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1)
+diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
+index ffed4d9490428..e4904faf17532 100644
+--- a/arch/arm/mach-at91/pm_suspend.S
++++ b/arch/arm/mach-at91/pm_suspend.S
+@@ -169,10 +169,15 @@ sr_ena_2:
+ cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW
+ bne sr_ena_2
+
+- /* Put DDR PHY's DLL in bypass mode for non-backup modes. */
++ /* Disable DX DLLs for non-backup modes. */
+ cmp r7, #AT91_PM_BACKUP
+ beq sr_ena_3
+
++ /* Do not soft reset the AC DLL. */
++ ldr tmp1, [r3, DDR3PHY_ACDLLCR]
++ bic tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST
++ str tmp1, [r3, DDR3PHY_ACDLLCR]
++
+ /* Disable DX DLLs. */
+ ldr tmp1, [r3, #DDR3PHY_DX0DLLCR]
+ orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+index 7e0aeb2db3054..a0aeac6199299 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+@@ -34,11 +34,25 @@
+ off-on-delay-us = <12000>;
+ };
+
+- extcon_usbotg1: extcon-usbotg1 {
+- compatible = "linux,extcon-usb-gpio";
++ connector {
++ compatible = "gpio-usb-b-connector", "usb-b-connector";
++ type = "micro";
++ label = "X19";
+ pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_usb1_extcon>;
+- id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
++ pinctrl-0 = <&pinctrl_usb1_connector>;
++ id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ usb_dr_connector: endpoint {
++ remote-endpoint = <&usb1_drd_sw>;
++ };
++ };
++ };
+ };
+ };
+
+@@ -105,13 +119,19 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ dr_mode = "otg";
+- extcon = <&extcon_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ over-current-active-low;
++ usb-role-switch;
+ status = "okay";
++
++ port {
++ usb1_drd_sw: endpoint {
++ remote-endpoint = <&usb_dr_connector>;
++ };
++ };
+ };
+
+ &usbotg2 {
+@@ -231,7 +251,7 @@
+ <MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x84>;
+ };
+
+- pinctrl_usb1_extcon: usb1-extcongrp {
++ pinctrl_usb1_connector: usb1-connectorgrp {
+ fsl,pins = <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c0>;
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index dabd94dc30c4b..50ef92915c671 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -1244,10 +1244,10 @@
+ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ };
+
+- gpmi: nand-controller@33002000{
++ gpmi: nand-controller@33002000 {
+ compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+- #size-cells = <1>;
++ #size-cells = <0>;
+ reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+index ad0b99adf6911..67b554ba690ca 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+@@ -1102,7 +1102,7 @@
+ gpmi: nand-controller@33002000 {
+ compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+- #size-cells = <1>;
++ #size-cells = <0>;
+ reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/freescale/imx93-pinfunc.h b/arch/arm64/boot/dts/freescale/imx93-pinfunc.h
+old mode 100755
+new mode 100644
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index b9bf43215ada9..79351c6157eaa 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -668,7 +668,7 @@
+
+ apcs_glb: mailbox@b111000 {
+ compatible = "qcom,ipq8074-apcs-apps-global";
+- reg = <0x0b111000 0x6000>;
++ reg = <0x0b111000 0x1000>;
+
+ #clock-cells = <1>;
+ #mbox-cells = <1>;
+diff --git a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+index ba547ca9fc6bd..ddb9cb1821520 100644
+--- a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+@@ -43,7 +43,6 @@
+
+ regulator-always-on;
+ regulator-boot-on;
+- regulator-allow-set-load;
+
+ vin-supply = <&vreg_3p3>;
+ };
+@@ -137,6 +136,9 @@
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a_1p8: ldo7 {
+@@ -152,6 +154,9 @@
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11a_0p8: ldo11 {
+@@ -258,6 +263,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_1p8: ldo7 {
+@@ -273,6 +281,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+index ca5f5ad32ce5f..5b16ac76fefbc 100644
+--- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+@@ -83,6 +83,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c: ldo4 {
+@@ -98,6 +101,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c: ldo7 {
+@@ -113,6 +119,9 @@
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17c: ldo17 {
+@@ -121,6 +130,9 @@
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index 51ed691075ad3..b3c3844f97a01 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -2177,7 +2177,8 @@
+
+ lpass_audiocc: clock-controller@3300000 {
+ compatible = "qcom,sc7280-lpassaudiocc";
+- reg = <0 0x03300000 0 0x30000>;
++ reg = <0 0x03300000 0 0x30000>,
++ <0 0x032a9000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>;
+ clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src";
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+index 6792e88b2c6c5..a3796502d4255 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+@@ -124,6 +124,9 @@
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13c: ldo13 {
+@@ -146,6 +149,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4d: ldo4 {
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 49ea8b5612fc2..6d82dea3675b1 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -885,13 +885,13 @@
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0xe10>;
++ reg = <0 0x01d87000 0 0x1c8>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clock-names = "ref",
+ "ref_aux";
+- clocks = <&rpmhcc RPMH_CXO_CLK>,
++ clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+
+ resets = <&ufs_mem_hc 0>;
+@@ -953,13 +953,13 @@
+
+ ufs_card_phy: phy@1da7000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+- reg = <0 0x01da7000 0 0xe10>;
++ reg = <0 0x01da7000 0 0x1c8>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clock-names = "ref",
+ "ref_aux";
+- clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
++ clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
+
+ resets = <&ufs_card_hc 0>;
+@@ -1181,26 +1181,16 @@
+ usb_0_ssphy: usb3-phy@88eb400 {
+ reg = <0 0x088eb400 0 0x100>,
+ <0 0x088eb600 0 0x3ec>,
+- <0 0x088ec400 0 0x1f0>,
++ <0 0x088ec400 0 0x364>,
+ <0 0x088eba00 0 0x100>,
+ <0 0x088ebc00 0 0x3ec>,
+- <0 0x088ec700 0 0x64>;
++ <0 0x088ec200 0 0x18>;
+ #phy-cells = <0>;
+ #clock-cells = <0>;
+ clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "usb0_phy_pipe_clk_src";
+ };
+-
+- usb_0_dpphy: dp-phy@88ed200 {
+- reg = <0 0x088ed200 0 0x200>,
+- <0 0x088ed400 0 0x200>,
+- <0 0x088eda00 0 0x200>,
+- <0 0x088ea600 0 0x200>,
+- <0 0x088ea800 0 0x200>;
+- #clock-cells = <1>;
+- #phy-cells = <0>;
+- };
+ };
+
+ usb_1_hsphy: phy@8902000 {
+@@ -1242,8 +1232,8 @@
+
+ usb_1_ssphy: usb3-phy@8903400 {
+ reg = <0 0x08903400 0 0x100>,
+- <0 0x08903c00 0 0x3ec>,
+- <0 0x08904400 0 0x1f0>,
++ <0 0x08903600 0 0x3ec>,
++ <0 0x08904400 0 0x364>,
+ <0 0x08903a00 0 0x100>,
+ <0 0x08903c00 0 0x3ec>,
+ <0 0x08904200 0 0x18>;
+@@ -1253,16 +1243,6 @@
+ clock-names = "pipe0";
+ clock-output-names = "usb1_phy_pipe_clk_src";
+ };
+-
+- usb_1_dpphy: dp-phy@8904200 {
+- reg = <0 0x08904200 0 0x200>,
+- <0 0x08904400 0 0x200>,
+- <0 0x08904a00 0 0x200>,
+- <0 0x08904600 0 0x200>,
+- <0 0x08904800 0 0x200>;
+- #clock-cells = <1>;
+- #phy-cells = <0>;
+- };
+ };
+
+ system-cache-controller@9200000 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+index 014fe3a315489..fb6e5a140c9f6 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+@@ -348,6 +348,9 @@
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_3p0: ldo7 {
+@@ -367,6 +370,9 @@
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index 549e0a2aa9fe4..5428aab3058dd 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -317,6 +317,9 @@
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_2p85: ldo7 {
+@@ -339,6 +342,9 @@
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index bc773e210023c..052b4dbc1ee44 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -334,6 +334,7 @@
+ exit-latency-us = <6562>;
+ min-residency-us = <9987>;
+ local-timer-stop;
++ status = "disabled";
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+index 0fcf5bd88fc7d..69ae6503c2f66 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
++++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+@@ -107,6 +107,9 @@
+ regulator-max-microvolt = <888000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p2: ldo6 {
+@@ -115,6 +118,9 @@
+ regulator-max-microvolt = <1208000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_2p96: ldo7 {
+@@ -123,6 +129,9 @@
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_1p2: ldo9 {
+@@ -131,6 +140,9 @@
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
++ regulator-allowed-modes =
++ <RPMH_REGULATOR_MODE_LPM
++ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index abc418650fec0..65e53ef5a3960 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -41,7 +41,7 @@
+ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
+
+ #define MIDR_CPU_MODEL(imp, partnum) \
+- (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \
++ ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \
+ (0xf << MIDR_ARCHITECTURE_SHIFT) | \
+ ((partnum) << MIDR_PARTNUM_SHIFT))
+
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index b5df82aa99e64..d78e69293d127 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
+
+ static inline bool pmd_user_accessible_page(pmd_t pmd)
+ {
+- return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
++ return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+ }
+
+ static inline bool pud_user_accessible_page(pud_t pud)
+ {
+- return pud_present(pud) && pud_user(pud);
++ return pud_leaf(pud) && pud_user(pud);
+ }
+ #endif
+
+diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
+index eb489302c28a4..e8de94dd5a606 100644
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -539,7 +539,7 @@ static void __init map_mem(pgd_t *pgdp)
+ */
+ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
+
+- if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
++ if (can_set_direct_map())
+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+
+ /*
+@@ -1551,11 +1551,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
+
+ VM_BUG_ON(!mhp_range_allowed(start, size, true));
+
+- /*
+- * KFENCE requires linear map to be mapped at page granularity, so that
+- * it is possible to protect/unprotect single pages in the KFENCE pool.
+- */
+- if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
++ if (can_set_direct_map())
+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+
+ __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
+diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
+index 64e985eaa52d8..5922178d7a064 100644
+--- a/arch/arm64/mm/pageattr.c
++++ b/arch/arm64/mm/pageattr.c
+@@ -21,7 +21,13 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED
+
+ bool can_set_direct_map(void)
+ {
+- return rodata_full || debug_pagealloc_enabled();
++ /*
++ * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be
++ * mapped at page granularity, so that it is possible to
++ * protect/unprotect single pages.
++ */
++ return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
++ IS_ENABLED(CONFIG_KFENCE);
+ }
+
+ static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
+@@ -96,7 +102,8 @@ static int change_memory_common(unsigned long addr, int numpages,
+ * If we are manipulating read-only permissions, apply the same
+ * change to the linear mapping of the pages that back this VM area.
+ */
+- if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
++ if (rodata_enabled &&
++ rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
+ pgprot_val(clear_mask) == PTE_RDONLY)) {
+ for (i = 0; i < area->nr_pages; i++) {
+ __change_memory_common((u64)page_address(area->pages[i]),
+diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
+index cfde14b48fd8d..f5b2ef979b437 100644
+--- a/arch/mips/kernel/relocate_kernel.S
++++ b/arch/mips/kernel/relocate_kernel.S
+@@ -145,8 +145,7 @@ LEAF(kexec_smp_wait)
+ * kexec_args[0..3] are used to prepare register values.
+ */
+
+-kexec_args:
+- EXPORT(kexec_args)
++EXPORT(kexec_args)
+ arg0: PTR_WD 0x0
+ arg1: PTR_WD 0x0
+ arg2: PTR_WD 0x0
+@@ -159,8 +158,7 @@ arg3: PTR_WD 0x0
+ * their registers a0-a3. secondary_kexec_args[0..3] are used
+ * to prepare register values.
+ */
+-secondary_kexec_args:
+- EXPORT(secondary_kexec_args)
++EXPORT(secondary_kexec_args)
+ s_arg0: PTR_WD 0x0
+ s_arg1: PTR_WD 0x0
+ s_arg2: PTR_WD 0x0
+@@ -171,19 +169,16 @@ kexec_flag:
+
+ #endif
+
+-kexec_start_address:
+- EXPORT(kexec_start_address)
++EXPORT(kexec_start_address)
+ PTR_WD 0x0
+ .size kexec_start_address, PTRSIZE
+
+-kexec_indirection_page:
+- EXPORT(kexec_indirection_page)
++EXPORT(kexec_indirection_page)
+ PTR_WD 0
+ .size kexec_indirection_page, PTRSIZE
+
+ relocate_new_kernel_end:
+
+-relocate_new_kernel_size:
+- EXPORT(relocate_new_kernel_size)
++EXPORT(relocate_new_kernel_size)
+ PTR_WD relocate_new_kernel_end - relocate_new_kernel
+ .size relocate_new_kernel_size, PTRSIZE
+diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c
+index 758d5d26aaaa2..e420800043b08 100644
+--- a/arch/mips/loongson64/reset.c
++++ b/arch/mips/loongson64/reset.c
+@@ -16,6 +16,7 @@
+ #include <asm/bootinfo.h>
+ #include <asm/idle.h>
+ #include <asm/reboot.h>
++#include <asm/bug.h>
+
+ #include <loongson.h>
+ #include <boot_param.h>
+@@ -159,8 +160,17 @@ static int __init mips_reboot_setup(void)
+
+ #ifdef CONFIG_KEXEC
+ kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
++ if (WARN_ON(!kexec_argv))
++ return -ENOMEM;
++
+ kdump_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
++ if (WARN_ON(!kdump_argv))
++ return -ENOMEM;
++
+ kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL);
++ if (WARN_ON(!kexec_envp))
++ return -ENOMEM;
++
+ fw_arg1 = KEXEC_ARGV_ADDR;
+ memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE);
+
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index cbe7bb029aec8..c1d36a22de308 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -284,7 +284,7 @@ config PPC
+ #
+
+ config PPC_LONG_DOUBLE_128
+- depends on PPC64
++ depends on PPC64 && ALTIVEC
+ def_bool $(success,test "$(shell,echo __LONG_DOUBLE_128__ | $(CC) -E -P -)" = 1)
+
+ config PPC_BARRIER_NOSPEC
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index bd66f8e349492..00f45d8f1efa0 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -202,7 +202,16 @@ unsigned long __get_wchan(struct task_struct *p);
+ /* Has task runtime instrumentation enabled ? */
+ #define is_ri_task(tsk) (!!(tsk)->thread.ri_cb)
+
+-register unsigned long current_stack_pointer asm("r15");
++/* avoid using global register due to gcc bug in versions < 8.4 */
++#define current_stack_pointer (__current_stack_pointer())
++
++static __always_inline unsigned long __current_stack_pointer(void)
++{
++ unsigned long sp;
++
++ asm volatile("lgr %0,15" : "=d" (sp));
++ return sp;
++}
+
+ static __always_inline unsigned short stap(void)
+ {
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index 9ac3718410ce4..7e39c47d7759b 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -896,8 +896,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
+ pmu_enabled = cpuc->enabled;
+ cpuc->enabled = 0;
+
+- /* stop everything (includes BRS) */
+- amd_pmu_disable_all();
++ amd_brs_disable_all();
+
+ /* Drain BRS is in use (could be inactive) */
+ if (cpuc->lbr_users)
+@@ -908,7 +907,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
+
+ cpuc->enabled = pmu_enabled;
+ if (pmu_enabled)
+- amd_pmu_enable_all(0);
++ amd_brs_enable_all();
+
+ return amd_pmu_adjust_nmi_window(handled);
+ }
+diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
+index d568afc705d2e..83f15fe411b3f 100644
+--- a/arch/x86/events/amd/uncore.c
++++ b/arch/x86/events/amd/uncore.c
+@@ -553,6 +553,7 @@ static void uncore_clean_online(void)
+
+ hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) {
+ hlist_del(&uncore->node);
++ kfree(uncore->events);
+ kfree(uncore);
+ }
+ }
+diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
+index 82ef87e9a897c..42a55794004a7 100644
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -1263,6 +1263,15 @@ static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages)
+ if (1 << order != nr_pages)
+ goto out;
+
++ /*
++ * Some processors cannot always support single range for more than
++ * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might
++ * also be affected, so for now rather than trying to keep track of
++ * which ones, just disable it for all.
++ */
++ if (nr_pages > 1)
++ goto out;
++
+ buf->single = true;
+ buf->nr_pages = nr_pages;
+ ret = 0;
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 5d75fe2293421..347707d459c67 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -107,6 +107,11 @@
+
+ #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */
+
++#define INTEL_FAM6_EMERALDRAPIDS_X 0xCF
++
++#define INTEL_FAM6_GRANITERAPIDS_X 0xAD
++#define INTEL_FAM6_GRANITERAPIDS_D 0xAE
++
+ #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */
+ #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */
+ #define INTEL_FAM6_ALDERLAKE_N 0xBE
+@@ -118,7 +123,7 @@
+ #define INTEL_FAM6_METEORLAKE 0xAC
+ #define INTEL_FAM6_METEORLAKE_L 0xAA
+
+-/* "Small Core" Processors (Atom) */
++/* "Small Core" Processors (Atom/E-Core) */
+
+ #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
+ #define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */
+@@ -145,6 +150,10 @@
+ #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */
+ #define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */
+
++#define INTEL_FAM6_SIERRAFOREST_X 0xAF
++
++#define INTEL_FAM6_GRANDRIDGE 0xB6
++
+ /* Xeon Phi */
+
+ #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index da7c361f47e0d..6ec0b7ce74531 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -196,22 +196,15 @@ void __init check_bugs(void)
+ }
+
+ /*
+- * NOTE: This function is *only* called for SVM. VMX spec_ctrl handling is
+- * done in vmenter.S.
++ * NOTE: This function is *only* called for SVM, since Intel uses
++ * MSR_IA32_SPEC_CTRL for SSBD.
+ */
+ void
+ x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest)
+ {
+- u64 msrval, guestval = guest_spec_ctrl, hostval = spec_ctrl_current();
++ u64 guestval, hostval;
+ struct thread_info *ti = current_thread_info();
+
+- if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) {
+- if (hostval != guestval) {
+- msrval = setguest ? guestval : hostval;
+- wrmsrl(MSR_IA32_SPEC_CTRL, msrval);
+- }
+- }
+-
+ /*
+ * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update
+ * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported.
+diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
+index ebe79d60619f2..da8b8ea6b063d 100644
+--- a/arch/x86/kernel/cpu/sgx/ioctl.c
++++ b/arch/x86/kernel/cpu/sgx/ioctl.c
+@@ -356,6 +356,9 @@ static int sgx_validate_offset_length(struct sgx_encl *encl,
+ if (!length || !IS_ALIGNED(length, PAGE_SIZE))
+ return -EINVAL;
+
++ if (offset + length < offset)
++ return -EINVAL;
++
+ if (offset + length - PAGE_SIZE >= encl->size)
+ return -EINVAL;
+
+diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
+index 3b28c5b25e12c..d00db56a88682 100644
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -605,9 +605,9 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal)
+ if (test_thread_flag(TIF_NEED_FPU_LOAD))
+ fpregs_restore_userregs();
+ save_fpregs_to_fpstate(dst_fpu);
++ fpregs_unlock();
+ if (!(clone_flags & CLONE_THREAD))
+ fpu_inherit_perms(dst_fpu);
+- fpregs_unlock();
+
+ /*
+ * Children never inherit PASID state.
+diff --git a/arch/x86/kvm/kvm-asm-offsets.c b/arch/x86/kvm/kvm-asm-offsets.c
+index f83e88b85bf21..24a710d373238 100644
+--- a/arch/x86/kvm/kvm-asm-offsets.c
++++ b/arch/x86/kvm/kvm-asm-offsets.c
+@@ -16,8 +16,10 @@ static void __used common(void)
+ BLANK();
+ OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs);
+ OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb);
++ OFFSET(SVM_spec_ctrl, vcpu_svm, spec_ctrl);
+ OFFSET(SVM_vmcb01, vcpu_svm, vmcb01);
+ OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa);
++ OFFSET(SD_save_area_pa, svm_cpu_data, save_area_pa);
+ }
+
+ if (IS_ENABLED(CONFIG_KVM_INTEL)) {
+diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
+index c9c9bd453a97d..efaaef2b7ae11 100644
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -196,7 +196,7 @@ static void sev_asid_free(struct kvm_sev_info *sev)
+ __set_bit(sev->asid, sev_reclaim_asid_bitmap);
+
+ for_each_possible_cpu(cpu) {
+- sd = per_cpu(svm_data, cpu);
++ sd = per_cpu_ptr(&svm_data, cpu);
+ sd->sev_vmcbs[sev->asid] = NULL;
+ }
+
+@@ -2600,7 +2600,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
+
+ void pre_sev_run(struct vcpu_svm *svm, int cpu)
+ {
+- struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ int asid = sev_get_asid(svm->vcpu.kvm);
+
+ /* Assign the asid allocated with this SEV guest */
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 454746641a483..e80756ab141bf 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -245,7 +245,7 @@ struct kvm_ldttss_desc {
+ u32 zero1;
+ } __attribute__((packed));
+
+-DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
++DEFINE_PER_CPU(struct svm_cpu_data, svm_data);
+
+ /*
+ * Only MSR_TSC_AUX is switched via the user return hook. EFER is switched via
+@@ -583,12 +583,7 @@ static int svm_hardware_enable(void)
+ pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me);
+ return -EINVAL;
+ }
+- sd = per_cpu(svm_data, me);
+- if (!sd) {
+- pr_err("%s: svm_data is NULL on %d\n", __func__, me);
+- return -EINVAL;
+- }
+-
++ sd = per_cpu_ptr(&svm_data, me);
+ sd->asid_generation = 1;
+ sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
+ sd->next_asid = sd->max_asid + 1;
+@@ -599,7 +594,7 @@ static int svm_hardware_enable(void)
+
+ wrmsrl(MSR_EFER, efer | EFER_SVME);
+
+- wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area));
++ wrmsrl(MSR_VM_HSAVE_PA, sd->save_area_pa);
+
+ if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+ /*
+@@ -648,42 +643,37 @@ static int svm_hardware_enable(void)
+
+ static void svm_cpu_uninit(int cpu)
+ {
+- struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+
+- if (!sd)
++ if (!sd->save_area)
+ return;
+
+- per_cpu(svm_data, cpu) = NULL;
+ kfree(sd->sev_vmcbs);
+ __free_page(sd->save_area);
+- kfree(sd);
++ sd->save_area_pa = 0;
++ sd->save_area = NULL;
+ }
+
+ static int svm_cpu_init(int cpu)
+ {
+- struct svm_cpu_data *sd;
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ int ret = -ENOMEM;
+
+- sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
+- if (!sd)
+- return ret;
+- sd->cpu = cpu;
++ memset(sd, 0, sizeof(struct svm_cpu_data));
+ sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!sd->save_area)
+- goto free_cpu_data;
++ return ret;
+
+ ret = sev_cpu_init(sd);
+ if (ret)
+ goto free_save_area;
+
+- per_cpu(svm_data, cpu) = sd;
+-
++ sd->save_area_pa = __sme_page_pa(sd->save_area);
+ return 0;
+
+ free_save_area:
+ __free_page(sd->save_area);
+-free_cpu_data:
+- kfree(sd);
++ sd->save_area = NULL;
+ return ret;
+
+ }
+@@ -732,6 +722,15 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
+ u32 offset;
+ u32 *msrpm;
+
++ /*
++ * For non-nested case:
++ * If the L01 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ *
++ * For nested case:
++ * If the L02 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ */
+ msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm:
+ to_svm(vcpu)->msrpm;
+
+@@ -1427,7 +1426,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb)
+ int i;
+
+ for_each_online_cpu(i)
+- cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
++ cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL);
+ }
+
+ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+@@ -1452,7 +1451,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+- struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+
+ if (sev_es_guest(vcpu->kvm))
+ sev_es_unmap_ghcb(svm);
+@@ -1464,7 +1463,7 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ * Save additional host state that will be restored on VMEXIT (sev-es)
+ * or subsequent vmload of host save area.
+ */
+- vmsave(__sme_page_pa(sd->save_area));
++ vmsave(sd->save_area_pa);
+ if (sev_es_guest(vcpu->kvm)) {
+ struct sev_es_save_area *hostsa;
+ hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
+@@ -1489,7 +1488,7 @@ static void svm_prepare_host_switch(struct kvm_vcpu *vcpu)
+ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+- struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+
+ if (sd->current_vmcb != svm->vmcb) {
+ sd->current_vmcb = svm->vmcb;
+@@ -3444,7 +3443,7 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+
+ static void reload_tss(struct kvm_vcpu *vcpu)
+ {
+- struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+
+ sd->tss_desc->type = 9; /* available 32/64-bit TSS */
+ load_TR_desc();
+@@ -3452,7 +3451,7 @@ static void reload_tss(struct kvm_vcpu *vcpu)
+
+ static void pre_svm_run(struct kvm_vcpu *vcpu)
+ {
+- struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++ struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ /*
+@@ -3912,20 +3911,16 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
+ return EXIT_FASTPATH_NONE;
+ }
+
+-static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
++static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_intercepted)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ guest_state_enter_irqoff();
+
+- if (sev_es_guest(vcpu->kvm)) {
+- __svm_sev_es_vcpu_run(svm);
+- } else {
+- struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+-
+- __svm_vcpu_run(svm);
+- vmload(__sme_page_pa(sd->save_area));
+- }
++ if (sev_es_guest(vcpu->kvm))
++ __svm_sev_es_vcpu_run(svm, spec_ctrl_intercepted);
++ else
++ __svm_vcpu_run(svm, spec_ctrl_intercepted);
+
+ guest_state_exit_irqoff();
+ }
+@@ -3933,6 +3928,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
++ bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL);
+
+ trace_kvm_entry(vcpu);
+
+@@ -3991,26 +3987,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
+ if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL))
+ x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
+
+- svm_vcpu_enter_exit(vcpu);
+-
+- /*
+- * We do not use IBRS in the kernel. If this vCPU has used the
+- * SPEC_CTRL MSR it may have left it on; save the value and
+- * turn it off. This is much more efficient than blindly adding
+- * it to the atomic save/restore list. Especially as the former
+- * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
+- *
+- * For non-nested case:
+- * If the L01 MSR bitmap does not intercept the MSR, then we need to
+- * save it.
+- *
+- * For nested case:
+- * If the L02 MSR bitmap does not intercept the MSR, then we need to
+- * save it.
+- */
+- if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL) &&
+- unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
+- svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
++ svm_vcpu_enter_exit(vcpu, spec_ctrl_intercepted);
+
+ if (!sev_es_guest(vcpu->kvm))
+ reload_tss(vcpu);
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index 7ff1879e73c56..ea3049b978eab 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -281,8 +281,6 @@ struct vcpu_svm {
+ };
+
+ struct svm_cpu_data {
+- int cpu;
+-
+ u64 asid_generation;
+ u32 max_asid;
+ u32 next_asid;
+@@ -290,13 +288,15 @@ struct svm_cpu_data {
+ struct kvm_ldttss_desc *tss_desc;
+
+ struct page *save_area;
++ unsigned long save_area_pa;
++
+ struct vmcb *current_vmcb;
+
+ /* index = sev_asid, value = vmcb pointer */
+ struct vmcb **sev_vmcbs;
+ };
+
+-DECLARE_PER_CPU(struct svm_cpu_data *, svm_data);
++DECLARE_PER_CPU(struct svm_cpu_data, svm_data);
+
+ void recalc_intercepts(struct vcpu_svm *svm);
+
+@@ -683,7 +683,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm);
+
+ /* vmenter.S */
+
+-void __svm_sev_es_vcpu_run(struct vcpu_svm *svm);
+-void __svm_vcpu_run(struct vcpu_svm *svm);
++void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted);
++void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted);
+
+ #endif
+diff --git a/arch/x86/kvm/svm/svm_ops.h b/arch/x86/kvm/svm/svm_ops.h
+index 9430d6437c9f6..36c8af87a707a 100644
+--- a/arch/x86/kvm/svm/svm_ops.h
++++ b/arch/x86/kvm/svm/svm_ops.h
+@@ -61,9 +61,4 @@ static __always_inline void vmsave(unsigned long pa)
+ svm_asm1(vmsave, "a" (pa), "memory");
+ }
+
+-static __always_inline void vmload(unsigned long pa)
+-{
+- svm_asm1(vmload, "a" (pa), "memory");
+-}
+-
+ #endif /* __KVM_X86_SVM_OPS_H */
+diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
+index 5bc2ed7d79c07..34367dc203f21 100644
+--- a/arch/x86/kvm/svm/vmenter.S
++++ b/arch/x86/kvm/svm/vmenter.S
+@@ -32,9 +32,69 @@
+
+ .section .noinstr.text, "ax"
+
++.macro RESTORE_GUEST_SPEC_CTRL
++ /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */
++ ALTERNATIVE_2 "", \
++ "jmp 800f", X86_FEATURE_MSR_SPEC_CTRL, \
++ "", X86_FEATURE_V_SPEC_CTRL
++801:
++.endm
++.macro RESTORE_GUEST_SPEC_CTRL_BODY
++800:
++ /*
++ * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the
++ * host's, write the MSR. This is kept out-of-line so that the common
++ * case does not have to jump.
++ *
++ * IMPORTANT: To avoid RSB underflow attacks and any other nastiness,
++ * there must not be any returns or indirect branches between this code
++ * and vmentry.
++ */
++ movl SVM_spec_ctrl(%_ASM_DI), %eax
++ cmp PER_CPU_VAR(x86_spec_ctrl_current), %eax
++ je 801b
++ mov $MSR_IA32_SPEC_CTRL, %ecx
++ xor %edx, %edx
++ wrmsr
++ jmp 801b
++.endm
++
++.macro RESTORE_HOST_SPEC_CTRL
++ /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */
++ ALTERNATIVE_2 "", \
++ "jmp 900f", X86_FEATURE_MSR_SPEC_CTRL, \
++ "", X86_FEATURE_V_SPEC_CTRL
++901:
++.endm
++.macro RESTORE_HOST_SPEC_CTRL_BODY
++900:
++ /* Same for after vmexit. */
++ mov $MSR_IA32_SPEC_CTRL, %ecx
++
++ /*
++ * Load the value that the guest had written into MSR_IA32_SPEC_CTRL,
++ * if it was not intercepted during guest execution.
++ */
++ cmpb $0, (%_ASM_SP)
++ jnz 998f
++ rdmsr
++ movl %eax, SVM_spec_ctrl(%_ASM_DI)
++998:
++
++ /* Now restore the host value of the MSR if different from the guest's. */
++ movl PER_CPU_VAR(x86_spec_ctrl_current), %eax
++ cmp SVM_spec_ctrl(%_ASM_DI), %eax
++ je 901b
++ xor %edx, %edx
++ wrmsr
++ jmp 901b
++.endm
++
++
+ /**
+ * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
+ * @svm: struct vcpu_svm *
++ * @spec_ctrl_intercepted: bool
+ */
+ SYM_FUNC_START(__svm_vcpu_run)
+ push %_ASM_BP
+@@ -49,14 +109,31 @@ SYM_FUNC_START(__svm_vcpu_run)
+ #endif
+ push %_ASM_BX
+
+- /* Save @svm. */
++ /*
++ * Save variables needed after vmexit on the stack, in inverse
++ * order compared to when they are needed.
++ */
++
++ /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */
++ push %_ASM_ARG2
++
++ /* Needed to restore access to percpu variables. */
++ __ASM_SIZE(push) PER_CPU_VAR(svm_data + SD_save_area_pa)
++
++ /* Finally save @svm. */
+ push %_ASM_ARG1
+
+ .ifnc _ASM_ARG1, _ASM_DI
+- /* Move @svm to RDI. */
++ /*
++ * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX
++ * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL.
++ */
+ mov %_ASM_ARG1, %_ASM_DI
+ .endif
+
++ /* Clobbers RAX, RCX, RDX. */
++ RESTORE_GUEST_SPEC_CTRL
++
+ /*
+ * Use a single vmcb (vmcb01 because it's always valid) for
+ * context switching guest state via VMLOAD/VMSAVE, that way
+@@ -124,11 +201,19 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 5: vmsave %_ASM_AX
+ 6:
+
++ /* Restores GSBASE among other things, allowing access to percpu data. */
++ pop %_ASM_AX
++7: vmload %_ASM_AX
++8:
++
+ #ifdef CONFIG_RETPOLINE
+ /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+ #endif
+
++ /* Clobbers RAX, RCX, RDX. */
++ RESTORE_HOST_SPEC_CTRL
++
+ /*
+ * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ * untrained as soon as we exit the VM and are back to the
+@@ -164,6 +249,9 @@ SYM_FUNC_START(__svm_vcpu_run)
+ xor %r15d, %r15d
+ #endif
+
++ /* "Pop" @spec_ctrl_intercepted. */
++ pop %_ASM_BX
++
+ pop %_ASM_BX
+
+ #ifdef CONFIG_X86_64
+@@ -178,6 +266,9 @@ SYM_FUNC_START(__svm_vcpu_run)
+ pop %_ASM_BP
+ RET
+
++ RESTORE_GUEST_SPEC_CTRL_BODY
++ RESTORE_HOST_SPEC_CTRL_BODY
++
+ 10: cmpb $0, kvm_rebooting
+ jne 2b
+ ud2
+@@ -187,16 +278,21 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 50: cmpb $0, kvm_rebooting
+ jne 6b
+ ud2
++70: cmpb $0, kvm_rebooting
++ jne 8b
++ ud2
+
+ _ASM_EXTABLE(1b, 10b)
+ _ASM_EXTABLE(3b, 30b)
+ _ASM_EXTABLE(5b, 50b)
++ _ASM_EXTABLE(7b, 70b)
+
+ SYM_FUNC_END(__svm_vcpu_run)
+
+ /**
+ * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
+ * @svm: struct vcpu_svm *
++ * @spec_ctrl_intercepted: bool
+ */
+ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ push %_ASM_BP
+@@ -211,8 +307,30 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ #endif
+ push %_ASM_BX
+
++ /*
++ * Save variables needed after vmexit on the stack, in inverse
++ * order compared to when they are needed.
++ */
++
++ /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */
++ push %_ASM_ARG2
++
++ /* Save @svm. */
++ push %_ASM_ARG1
++
++.ifnc _ASM_ARG1, _ASM_DI
++ /*
++ * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX
++ * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL.
++ */
++ mov %_ASM_ARG1, %_ASM_DI
++.endif
++
++ /* Clobbers RAX, RCX, RDX. */
++ RESTORE_GUEST_SPEC_CTRL
++
+ /* Get svm->current_vmcb->pa into RAX. */
+- mov SVM_current_vmcb(%_ASM_ARG1), %_ASM_AX
++ mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX
+ mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+
+ /* Enter guest mode */
+@@ -222,11 +340,17 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+
+ 2: cli
+
++ /* Pop @svm to RDI, guest registers have been saved already. */
++ pop %_ASM_DI
++
+ #ifdef CONFIG_RETPOLINE
+ /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+ #endif
+
++ /* Clobbers RAX, RCX, RDX. */
++ RESTORE_HOST_SPEC_CTRL
++
+ /*
+ * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ * untrained as soon as we exit the VM and are back to the
+@@ -236,6 +360,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ */
+ UNTRAIN_RET
+
++ /* "Pop" @spec_ctrl_intercepted. */
++ pop %_ASM_BX
++
+ pop %_ASM_BX
+
+ #ifdef CONFIG_X86_64
+@@ -250,6 +377,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ pop %_ASM_BP
+ RET
+
++ RESTORE_GUEST_SPEC_CTRL_BODY
++ RESTORE_HOST_SPEC_CTRL_BODY
++
+ 3: cmpb $0, kvm_rebooting
+ jne 2b
+ ud2
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index cecf8299b187b..9a1950879fc44 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -1667,18 +1667,18 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm,
+ case EVTCHNSTAT_ipi:
+ /* IPI must map back to the same port# */
+ if (data->u.evtchn.deliver.port.port != data->u.evtchn.send_port)
+- goto out; /* -EINVAL */
++ goto out_noeventfd; /* -EINVAL */
+ break;
+
+ case EVTCHNSTAT_interdomain:
+ if (data->u.evtchn.deliver.port.port) {
+ if (data->u.evtchn.deliver.port.port >= max_evtchn_port(kvm))
+- goto out; /* -EINVAL */
++ goto out_noeventfd; /* -EINVAL */
+ } else {
+ eventfd = eventfd_ctx_fdget(data->u.evtchn.deliver.eventfd.fd);
+ if (IS_ERR(eventfd)) {
+ ret = PTR_ERR(eventfd);
+- goto out;
++ goto out_noeventfd;
+ }
+ }
+ break;
+@@ -1718,6 +1718,7 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm,
+ out:
+ if (eventfd)
+ eventfd_ctx_put(eventfd);
++out_noeventfd:
+ kfree(evtchnfd);
+ return ret;
+ }
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 869af9d72bcf8..c8f0c865bf4ed 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -1251,7 +1251,7 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
+ * parent so that offline always happens towards the root.
+ */
+ if (parent)
+- blkcg_pin_online(css);
++ blkcg_pin_online(&parent->css);
+ return 0;
+ }
+
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 651057c4146b2..2fbdf17f2206e 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -426,7 +426,6 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu)
+ PERCPU_REF_INIT_ATOMIC, GFP_KERNEL))
+ goto fail_stats;
+
+- blk_queue_dma_alignment(q, 511);
+ blk_set_default_limits(&q->limits);
+ q->nr_requests = BLKDEV_DEFAULT_RQ;
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index edf41959a705f..4402e4ecb8b11 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1183,6 +1183,7 @@ static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq)
+ (!blk_queue_nomerges(rq->q) &&
+ blk_rq_bytes(last) >= BLK_PLUG_FLUSH_SIZE)) {
+ blk_mq_flush_plug_list(plug, false);
++ last = NULL;
+ trace_block_plug(rq->q);
+ }
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 8bb9eef5310eb..4949ed3ce7c95 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -57,6 +57,7 @@ void blk_set_default_limits(struct queue_limits *lim)
+ lim->misaligned = 0;
+ lim->zoned = BLK_ZONED_NONE;
+ lim->zone_write_granularity = 0;
++ lim->dma_alignment = 511;
+ }
+ EXPORT_SYMBOL(blk_set_default_limits);
+
+@@ -600,6 +601,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+
+ t->io_min = max(t->io_min, b->io_min);
+ t->io_opt = lcm_not_zero(t->io_opt, b->io_opt);
++ t->dma_alignment = max(t->dma_alignment, b->dma_alignment);
+
+ /* Set non-power-of-2 compatible chunk_sectors boundary */
+ if (b->chunk_sectors)
+@@ -773,7 +775,7 @@ EXPORT_SYMBOL(blk_queue_virt_boundary);
+ **/
+ void blk_queue_dma_alignment(struct request_queue *q, int mask)
+ {
+- q->dma_alignment = mask;
++ q->limits.dma_alignment = mask;
+ }
+ EXPORT_SYMBOL(blk_queue_dma_alignment);
+
+@@ -795,8 +797,8 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
+ {
+ BUG_ON(mask > PAGE_SIZE);
+
+- if (mask > q->dma_alignment)
+- q->dma_alignment = mask;
++ if (mask > q->limits.dma_alignment)
++ q->limits.dma_alignment = mask;
+ }
+ EXPORT_SYMBOL(blk_queue_update_dma_alignment);
+
+diff --git a/block/sed-opal.c b/block/sed-opal.c
+index 9700197000f20..55cd37e868c0e 100644
+--- a/block/sed-opal.c
++++ b/block/sed-opal.c
+@@ -88,8 +88,8 @@ struct opal_dev {
+ u64 lowest_lba;
+
+ size_t pos;
+- u8 cmd[IO_BUFFER_LENGTH];
+- u8 resp[IO_BUFFER_LENGTH];
++ u8 *cmd;
++ u8 *resp;
+
+ struct parsed_resp parsed;
+ size_t prev_d_len;
+@@ -2134,6 +2134,8 @@ void free_opal_dev(struct opal_dev *dev)
+ return;
+
+ clean_opal_dev(dev);
++ kfree(dev->resp);
++ kfree(dev->cmd);
+ kfree(dev);
+ }
+ EXPORT_SYMBOL(free_opal_dev);
+@@ -2146,17 +2148,39 @@ struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
+ if (!dev)
+ return NULL;
+
++ /*
++ * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes
++ * sure the allocated buffer is DMA-safe in that regard.
++ */
++ dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
++ if (!dev->cmd)
++ goto err_free_dev;
++
++ dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
++ if (!dev->resp)
++ goto err_free_cmd;
++
+ INIT_LIST_HEAD(&dev->unlk_lst);
+ mutex_init(&dev->dev_lock);
+ dev->data = data;
+ dev->send_recv = send_recv;
+ if (check_opal_support(dev) != 0) {
+ pr_debug("Opal is not supported on this device\n");
+- kfree(dev);
+- return NULL;
++ goto err_free_resp;
+ }
+
+ return dev;
++
++err_free_resp:
++ kfree(dev->resp);
++
++err_free_cmd:
++ kfree(dev->cmd);
++
++err_free_dev:
++ kfree(dev);
++
++ return NULL;
+ }
+ EXPORT_SYMBOL(init_opal_dev);
+
+diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c
+index f52265293482e..73db0cb44fc7b 100644
+--- a/drivers/accessibility/speakup/main.c
++++ b/drivers/accessibility/speakup/main.c
+@@ -1778,7 +1778,7 @@ static void speakup_con_update(struct vc_data *vc)
+ {
+ unsigned long flags;
+
+- if (!speakup_console[vc->vc_num] || spk_parked)
++ if (!speakup_console[vc->vc_num] || spk_parked || !synth)
+ return;
+ if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
+ /* Speakup output, discard */
+diff --git a/drivers/accessibility/speakup/utils.h b/drivers/accessibility/speakup/utils.h
+index 4bf2ee8ac246a..4ce9a12f7664d 100644
+--- a/drivers/accessibility/speakup/utils.h
++++ b/drivers/accessibility/speakup/utils.h
+@@ -54,7 +54,7 @@ static inline int oops(const char *msg, const char *info)
+
+ static inline struct st_key *hash_name(char *name)
+ {
+- u_char *pn = (u_char *)name;
++ unsigned char *pn = (unsigned char *)name;
+ int hash = 0;
+
+ while (*pn) {
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index 42cec8120f18e..adfeb5770efde 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -796,6 +796,7 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info,
+ static const char * const acpi_ignore_dep_ids[] = {
+ "PNP0D80", /* Windows-compatible System Power Management Controller */
+ "INT33BD", /* Intel Baytrail Mailbox Device */
++ "LATT2021", /* Lattice FW Update Client Driver */
+ NULL
+ };
+
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index d7cdd8406c84f..950a93922ca8f 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -219,6 +219,12 @@ static const struct dmi_system_id force_storage_d3_dmi[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
+ }
+ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5625"),
++ }
++ },
+ {}
+ };
+
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index b0e442a75690a..d86e32b71efa8 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -3966,9 +3966,19 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
+
+ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
+ {
++ struct ata_port *ap = dev->link->ap;
+ u8 scsi_op = scmd->cmnd[0];
+ ata_xlat_func_t xlat_func;
+
++ /*
++ * scsi_queue_rq() will defer commands if scsi_host_in_recovery().
++ * However, this check is done without holding the ap->lock (a libata
++ * specific lock), so we can have received an error irq since then,
++ * therefore we must check if EH is pending, while holding ap->lock.
++ */
++ if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS))
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++
+ if (unlikely(!scmd->cmd_len))
+ goto bad_cdb_len;
+
+diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
+index a7e9a75410a35..e4fb9d1b9b398 100644
+--- a/drivers/ata/libata-transport.c
++++ b/drivers/ata/libata-transport.c
+@@ -301,7 +301,9 @@ int ata_tport_add(struct device *parent,
+ pm_runtime_enable(dev);
+ pm_runtime_forbid(dev);
+
+- transport_add_device(dev);
++ error = transport_add_device(dev);
++ if (error)
++ goto tport_transport_add_err;
+ transport_configure_device(dev);
+
+ error = ata_tlink_add(&ap->link);
+@@ -312,12 +314,12 @@ int ata_tport_add(struct device *parent,
+
+ tport_link_err:
+ transport_remove_device(dev);
++ tport_transport_add_err:
+ device_del(dev);
+
+ tport_err:
+ transport_destroy_device(dev);
+ put_device(dev);
+- ata_host_put(ap->host);
+ return error;
+ }
+
+@@ -456,7 +458,9 @@ int ata_tlink_add(struct ata_link *link)
+ goto tlink_err;
+ }
+
+- transport_add_device(dev);
++ error = transport_add_device(dev);
++ if (error)
++ goto tlink_transport_err;
+ transport_configure_device(dev);
+
+ ata_for_each_dev(ata_dev, link, ALL) {
+@@ -471,6 +475,7 @@ int ata_tlink_add(struct ata_link *link)
+ ata_tdev_delete(ata_dev);
+ }
+ transport_remove_device(dev);
++ tlink_transport_err:
+ device_del(dev);
+ tlink_err:
+ transport_destroy_device(dev);
+@@ -708,7 +713,13 @@ static int ata_tdev_add(struct ata_device *ata_dev)
+ return error;
+ }
+
+- transport_add_device(dev);
++ error = transport_add_device(dev);
++ if (error) {
++ device_del(dev);
++ ata_tdev_free(ata_dev);
++ return error;
++ }
++
+ transport_configure_device(dev);
+ return 0;
+ }
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index f3e4db16fd07b..8532b839a3435 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -2672,7 +2672,7 @@ static int init_submitter(struct drbd_device *device)
+ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor)
+ {
+ struct drbd_resource *resource = adm_ctx->resource;
+- struct drbd_connection *connection;
++ struct drbd_connection *connection, *n;
+ struct drbd_device *device;
+ struct drbd_peer_device *peer_device, *tmp_peer_device;
+ struct gendisk *disk;
+@@ -2789,7 +2789,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+ return NO_ERROR;
+
+ out_idr_remove_from_resource:
+- for_each_connection(connection, resource) {
++ for_each_connection_safe(connection, n, resource) {
+ peer_device = idr_remove(&connection->peer_devices, vnr);
+ if (peer_device)
+ kref_put(&connection->kref, drbd_destroy_connection);
+diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
+index 16176b9278b4e..0c90f13870a43 100644
+--- a/drivers/cxl/core/mbox.c
++++ b/drivers/cxl/core/mbox.c
+@@ -174,7 +174,7 @@ int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
+ };
+ int rc;
+
+- if (out_size > cxlds->payload_size)
++ if (in_size > cxlds->payload_size || out_size > cxlds->payload_size)
+ return -E2BIG;
+
+ rc = cxlds->mbox_send(cxlds, &mbox_cmd);
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
+index faade12279f02..e0646097a3d4b 100644
+--- a/drivers/cxl/pmem.c
++++ b/drivers/cxl/pmem.c
+@@ -151,7 +151,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
+ return -EINVAL;
+
+ /* 4-byte status follows the input data in the payload */
+- if (struct_size(cmd, in_buf, cmd->in_length) + 4 > buf_len)
++ if (size_add(struct_size(cmd, in_buf, cmd->in_length), 4) > buf_len)
+ return -EINVAL;
+
+ set_lsa =
+diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
+index d4e23101448ae..35bb70724d44b 100644
+--- a/drivers/firmware/arm_scmi/bus.c
++++ b/drivers/firmware/arm_scmi/bus.c
+@@ -216,9 +216,20 @@ void scmi_device_destroy(struct scmi_device *scmi_dev)
+ device_unregister(&scmi_dev->dev);
+ }
+
++void scmi_device_link_add(struct device *consumer, struct device *supplier)
++{
++ struct device_link *link;
++
++ link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER);
++
++ WARN_ON(!link);
++}
++
+ void scmi_set_handle(struct scmi_device *scmi_dev)
+ {
+ scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
++ if (scmi_dev->handle)
++ scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
+ }
+
+ int scmi_protocol_register(const struct scmi_protocol *proto)
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 61aba7447c32a..a1c0154c31c6f 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -97,6 +97,7 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
+ struct scmi_revision_info *
+ scmi_revision_area_get(const struct scmi_protocol_handle *ph);
+ int scmi_handle_put(const struct scmi_handle *handle);
++void scmi_device_link_add(struct device *consumer, struct device *supplier);
+ struct scmi_handle *scmi_handle_get(struct device *dev);
+ void scmi_set_handle(struct scmi_device *scmi_dev);
+ void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
+@@ -117,6 +118,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+ *
+ * @dev: Reference to device in the SCMI hierarchy corresponding to this
+ * channel
++ * @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
+ * interrupt mechanism for synchronous commands.
+@@ -126,6 +128,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+ */
+ struct scmi_chan_info {
+ struct device *dev;
++ unsigned int rx_timeout_ms;
+ struct scmi_handle *handle;
+ bool no_completion_irq;
+ void *transport_info;
+@@ -232,7 +235,7 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
+ struct scmi_shared_mem;
+
+ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
+- struct scmi_xfer *xfer);
++ struct scmi_xfer *xfer, struct scmi_chan_info *cinfo);
+ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
+ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
+ struct scmi_xfer *xfer);
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 9022f5ee29aa8..f818d00bb2c69 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -2013,6 +2013,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
+ return -ENOMEM;
+
+ cinfo->dev = dev;
++ cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
+
+ ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
+ if (ret)
+@@ -2277,10 +2278,16 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table)
+ sdev = scmi_get_protocol_device(child, info,
+ id_table->protocol_id,
+ id_table->name);
+- /* Set handle if not already set: device existed */
+- if (sdev && !sdev->handle)
+- sdev->handle =
+- scmi_handle_get_from_info_unlocked(info);
++ if (sdev) {
++ /* Set handle if not already set: device existed */
++ if (!sdev->handle)
++ sdev->handle =
++ scmi_handle_get_from_info_unlocked(info);
++ /* Relink consumer and suppliers */
++ if (sdev->handle)
++ scmi_device_link_add(&sdev->dev,
++ sdev->handle->dev);
++ }
+ } else {
+ dev_err(info->dev,
+ "Failed. SCMI protocol %d not active.\n",
+@@ -2479,20 +2486,17 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
+
+ static int scmi_remove(struct platform_device *pdev)
+ {
+- int ret = 0, id;
++ int ret, id;
+ struct scmi_info *info = platform_get_drvdata(pdev);
+ struct device_node *child;
+
+ mutex_lock(&scmi_list_mutex);
+ if (info->users)
+- ret = -EBUSY;
+- else
+- list_del(&info->node);
++ dev_warn(&pdev->dev,
++ "Still active SCMI users will be forcibly unbound.\n");
++ list_del(&info->node);
+ mutex_unlock(&scmi_list_mutex);
+
+- if (ret)
+- return ret;
+-
+ scmi_notification_exit(&info->handle);
+
+ mutex_lock(&info->protocols_mtx);
+@@ -2504,7 +2508,11 @@ static int scmi_remove(struct platform_device *pdev)
+ idr_destroy(&info->active_protocols);
+
+ /* Safe to free channels since no more users */
+- return scmi_cleanup_txrx_channels(info);
++ ret = scmi_cleanup_txrx_channels(info);
++ if (ret)
++ dev_warn(&pdev->dev, "Failed to cleanup SCMI channels.\n");
++
++ return 0;
+ }
+
+ static ssize_t protocol_version_show(struct device *dev,
+diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
+index 08ff4d110beb4..1e40cb035044d 100644
+--- a/drivers/firmware/arm_scmi/mailbox.c
++++ b/drivers/firmware/arm_scmi/mailbox.c
+@@ -36,7 +36,7 @@ static void tx_prepare(struct mbox_client *cl, void *m)
+ {
+ struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
+
+- shmem_tx_prepare(smbox->shmem, m);
++ shmem_tx_prepare(smbox->shmem, m, smbox->cinfo);
+ }
+
+ static void rx_callback(struct mbox_client *cl, void *m)
+diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
+index f42dad997ac9a..2a7aeab40e543 100644
+--- a/drivers/firmware/arm_scmi/optee.c
++++ b/drivers/firmware/arm_scmi/optee.c
+@@ -498,7 +498,7 @@ static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
+ msg_tx_prepare(channel->req.msg, xfer);
+ ret = invoke_process_msg_channel(channel, msg_command_size(xfer));
+ } else {
+- shmem_tx_prepare(channel->req.shmem, xfer);
++ shmem_tx_prepare(channel->req.shmem, xfer, cinfo);
+ ret = invoke_process_smt_channel(channel);
+ }
+
+diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c
+index 0e3eaea5d8526..1dfe534b85184 100644
+--- a/drivers/firmware/arm_scmi/shmem.c
++++ b/drivers/firmware/arm_scmi/shmem.c
+@@ -5,10 +5,13 @@
+ * Copyright (C) 2019 ARM Ltd.
+ */
+
++#include <linux/ktime.h>
+ #include <linux/io.h>
+ #include <linux/processor.h>
+ #include <linux/types.h>
+
++#include <asm-generic/bug.h>
++
+ #include "common.h"
+
+ /*
+@@ -30,16 +33,36 @@ struct scmi_shared_mem {
+ };
+
+ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
+- struct scmi_xfer *xfer)
++ struct scmi_xfer *xfer, struct scmi_chan_info *cinfo)
+ {
++ ktime_t stop;
++
+ /*
+ * Ideally channel must be free by now unless OS timeout last
+ * request and platform continued to process the same, wait
+ * until it releases the shared memory, otherwise we may endup
+- * overwriting its response with new message payload or vice-versa
++ * overwriting its response with new message payload or vice-versa.
++ * Giving up anyway after twice the expected channel timeout so as
++ * not to bail-out on intermittent issues where the platform is
++ * occasionally a bit slower to answer.
++ *
++ * Note that after a timeout is detected we bail-out and carry on but
++ * the transport functionality is probably permanently compromised:
++ * this is just to ease debugging and avoid complete hangs on boot
++ * due to a misbehaving SCMI firmware.
+ */
+- spin_until_cond(ioread32(&shmem->channel_status) &
+- SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
++ stop = ktime_add_ms(ktime_get(), 2 * cinfo->rx_timeout_ms);
++ spin_until_cond((ioread32(&shmem->channel_status) &
++ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) ||
++ ktime_after(ktime_get(), stop));
++ if (!(ioread32(&shmem->channel_status) &
++ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) {
++ WARN_ON_ONCE(1);
++ dev_err(cinfo->dev,
++ "Timeout waiting for a free TX channel !\n");
++ return;
++ }
++
+ /* Mark channel busy + clear error */
+ iowrite32(0x0, &shmem->channel_status);
+ iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
+diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
+index 745acfdd0b3df..87a7b13cf868b 100644
+--- a/drivers/firmware/arm_scmi/smc.c
++++ b/drivers/firmware/arm_scmi/smc.c
+@@ -188,7 +188,7 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
+ */
+ smc_channel_lock_acquire(scmi_info, xfer);
+
+- shmem_tx_prepare(scmi_info->shmem, xfer);
++ shmem_tx_prepare(scmi_info->shmem, xfer, cinfo);
+
+ arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
+
+diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
+index c52bcaa9def60..9ca21feb9d454 100644
+--- a/drivers/firmware/google/coreboot_table.c
++++ b/drivers/firmware/google/coreboot_table.c
+@@ -149,12 +149,8 @@ static int coreboot_table_probe(struct platform_device *pdev)
+ if (!ptr)
+ return -ENOMEM;
+
+- ret = bus_register(&coreboot_bus_type);
+- if (!ret) {
+- ret = coreboot_table_populate(dev, ptr);
+- if (ret)
+- bus_unregister(&coreboot_bus_type);
+- }
++ ret = coreboot_table_populate(dev, ptr);
++
+ memunmap(ptr);
+
+ return ret;
+@@ -169,7 +165,6 @@ static int __cb_dev_unregister(struct device *dev, void *dummy)
+ static int coreboot_table_remove(struct platform_device *pdev)
+ {
+ bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister);
+- bus_unregister(&coreboot_bus_type);
+ return 0;
+ }
+
+@@ -199,6 +194,32 @@ static struct platform_driver coreboot_table_driver = {
+ .of_match_table = of_match_ptr(coreboot_of_match),
+ },
+ };
+-module_platform_driver(coreboot_table_driver);
++
++static int __init coreboot_table_driver_init(void)
++{
++ int ret;
++
++ ret = bus_register(&coreboot_bus_type);
++ if (ret)
++ return ret;
++
++ ret = platform_driver_register(&coreboot_table_driver);
++ if (ret) {
++ bus_unregister(&coreboot_bus_type);
++ return ret;
++ }
++
++ return 0;
++}
++
++static void __exit coreboot_table_driver_exit(void)
++{
++ platform_driver_unregister(&coreboot_table_driver);
++ bus_unregister(&coreboot_bus_type);
++}
++
++module_init(coreboot_table_driver_init);
++module_exit(coreboot_table_driver_exit);
++
+ MODULE_AUTHOR("Google, Inc.");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 9170aeaad93e7..e0c960cc1d2e1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4055,15 +4055,18 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
+ * at suspend time.
+ *
+ */
+-static void amdgpu_device_evict_resources(struct amdgpu_device *adev)
++static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
+ {
++ int ret;
++
+ /* No need to evict vram on APUs for suspend to ram or s2idle */
+ if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU))
+- return;
++ return 0;
+
+- if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM))
++ ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
++ if (ret)
+ DRM_WARN("evicting device resources failed\n");
+-
++ return ret;
+ }
+
+ /*
+@@ -4113,7 +4116,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
+ if (!adev->in_s0ix)
+ amdgpu_amdkfd_suspend(adev, adev->in_runpm);
+
+- amdgpu_device_evict_resources(adev);
++ r = amdgpu_device_evict_resources(adev);
++ if (r)
++ return r;
+
+ amdgpu_fence_driver_hw_fini(adev);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+index 576849e952964..f69827aefb571 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+@@ -500,6 +500,8 @@ static int amdgpu_vkms_sw_init(void *handle)
+
+ adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
+
++ adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
++
+ r = amdgpu_display_modeset_create_props(adev);
+ if (r)
+ return r;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 2dd827472d6e4..3bff0ae15e64e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -96,7 +96,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
+ struct amdgpu_device *adev = mes->adev;
+ struct amdgpu_ring *ring = &mes->ring;
+ unsigned long flags;
++ signed long timeout = adev->usec_timeout;
+
++ if (amdgpu_emu_mode) {
++ timeout *= 100;
++ } else if (amdgpu_sriov_vf(adev)) {
++ /* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
++ timeout = 15 * 600 * 1000;
++ }
+ BUG_ON(size % 4 != 0);
+
+ spin_lock_irqsave(&mes->ring_lock, flags);
+@@ -116,7 +123,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
+ DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
+
+ r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
+- adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1));
++ timeout);
+ if (r < 1) {
+ DRM_ERROR("MES failed to response msg=%d\n",
+ x_pkt->header.opcode);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 3be70848b2020..7f8eb09b0b7cb 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -146,6 +146,14 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU);
+ /* Number of bytes in PSP footer for firmware. */
+ #define PSP_FOOTER_BYTES 0x100
+
++/*
++ * DMUB Async to Sync Mechanism Status
++ */
++#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
++#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
++#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
++#define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4
++
+ /**
+ * DOC: overview
+ *
+@@ -1549,6 +1557,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+
+ adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm;
+
++ /* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */
++ adev->dm.dc->debug.ignore_cable_id = true;
++
+ r = dm_dmub_hw_init(adev);
+ if (r) {
+ DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
+@@ -1634,12 +1645,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ }
+ }
+
+- if (amdgpu_dm_initialize_drm_device(adev)) {
+- DRM_ERROR(
+- "amdgpu: failed to initialize sw for display support.\n");
+- goto error;
+- }
+-
+ /* Enable outbox notification only after IRQ handlers are registered and DMUB is alive.
+ * It is expected that DMUB will resend any pending notifications at this point, for
+ * example HPD from DPIA.
+@@ -1647,6 +1652,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ if (dc_is_dmub_outbox_supported(adev->dm.dc))
+ dc_enable_dmub_outbox(adev->dm.dc);
+
++ if (amdgpu_dm_initialize_drm_device(adev)) {
++ DRM_ERROR(
++ "amdgpu: failed to initialize sw for display support.\n");
++ goto error;
++ }
++
+ /* create fake encoders for MST */
+ dm_dp_create_fake_mst_encoders(adev);
+
+@@ -10146,6 +10157,8 @@ static int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux,
+ *operation_result = AUX_RET_ERROR_TIMEOUT;
+ } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) {
+ *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
++ } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID) {
++ *operation_result = AUX_RET_ERROR_INVALID_REPLY;
+ } else {
+ *operation_result = AUX_RET_ERROR_UNKNOWN;
+ }
+@@ -10193,6 +10206,16 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
+ payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
+ if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
+ payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) {
++
++ if (payload->length != adev->dm.dmub_notify->aux_reply.length) {
++ DRM_WARN("invalid read from DPIA AUX %x(%d) got length %d!\n",
++ payload->address, payload->length,
++ adev->dm.dmub_notify->aux_reply.length);
++ return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, ctx,
++ DMUB_ASYNC_TO_SYNC_ACCESS_INVALID,
++ (uint32_t *)operation_result);
++ }
++
+ memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
+ adev->dm.dmub_notify->aux_reply.length);
+ }
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 90b306a1dd687..4f2228d742f44 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -50,12 +50,6 @@
+
+ #define AMDGPU_DMUB_NOTIFICATION_MAX 5
+
+-/*
+- * DMUB Async to Sync Mechanism Status
+- */
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
+ /*
+ #include "include/amdgpu_dal_power_if.h"
+ #include "amdgpu_dm_irq.h"
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+index 594fe8a4d02b0..64dd029702926 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+@@ -412,7 +412,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+ {
+ struct amdgpu_crtc *acrtc = NULL;
+ struct drm_plane *cursor_plane;
+-
++ bool is_dcn;
+ int res = -ENOMEM;
+
+ cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL);
+@@ -450,8 +450,14 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+ acrtc->otg_inst = -1;
+
+ dm->adev->mode_info.crtcs[crtc_index] = acrtc;
+- drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES,
++
++ /* Don't enable DRM CRTC degamma property for DCE since it doesn't
++ * support programmable degamma anywhere.
++ */
++ is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
++ drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
+ true, MAX_COLOR_LUT_ENTRIES);
++
+ drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
+
+ return 0;
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index 09fbb7ad53629..de3a1f3fd4f1a 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -2392,6 +2392,26 @@ static enum bp_result get_vram_info_v25(
+ return result;
+ }
+
++static enum bp_result get_vram_info_v30(
++ struct bios_parser *bp,
++ struct dc_vram_info *info)
++{
++ struct atom_vram_info_header_v3_0 *info_v30;
++ enum bp_result result = BP_RESULT_OK;
++
++ info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0,
++ DATA_TABLES(vram_info));
++
++ if (info_v30 == NULL)
++ return BP_RESULT_BADBIOSTABLE;
++
++ info->num_chans = info_v30->channel_num;
++ info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8;
++
++ return result;
++}
++
++
+ /*
+ * get_integrated_info_v11
+ *
+@@ -3025,6 +3045,16 @@ static enum bp_result bios_parser_get_vram_info(
+ }
+ break;
+
++ case 3:
++ switch (revision.minor) {
++ case 0:
++ result = get_vram_info_v30(bp, info);
++ break;
++ default:
++ break;
++ }
++ break;
++
+ default:
+ return result;
+ }
+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 598ce872a8d7b..0f30df523fdf5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -1262,16 +1262,6 @@ void dcn20_pipe_control_lock(
+ lock,
+ &hw_locks,
+ &inst_flags);
+- } else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+- union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+- hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+- hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+- hw_lock_cmd.bits.lock_pipe = 1;
+- hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
+- hw_lock_cmd.bits.lock = lock;
+- if (!lock)
+- hw_lock_cmd.bits.should_release = 1;
+- dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+ } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
+ if (lock)
+ pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+@@ -1848,7 +1838,7 @@ void dcn20_post_unlock_program_front_end(
+
+ for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
+ && hubp->funcs->hubp_is_flip_pending(hubp); j++)
+- mdelay(1);
++ udelay(1);
+ }
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
+index 84e1486f3d515..39a57bcd78667 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
+@@ -87,6 +87,7 @@ static struct hubp_funcs dcn31_hubp_funcs = {
+ .hubp_init = hubp3_init,
+ .set_unbounded_requesting = hubp31_set_unbounded_requesting,
+ .hubp_soft_reset = hubp31_soft_reset,
++ .hubp_set_flip_int = hubp1_set_flip_int,
+ .hubp_in_blank = hubp1_in_blank,
+ .program_extended_blank = hubp31_program_extended_blank,
+ };
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
+index 38aa28ec6b130..9c95ad1454205 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
+@@ -237,7 +237,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = {
+ .clear_optc_underflow = optc1_clear_optc_underflow,
+ .setup_global_swap_lock = NULL,
+ .get_crc = optc1_get_crc,
+- .configure_crc = optc2_configure_crc,
++ .configure_crc = optc1_configure_crc,
+ .set_dsc_config = optc3_set_dsc_config,
+ .get_dsc_status = optc2_get_dsc_status,
+ .set_dwb_source = NULL,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 1f195c5b3377d..13cd1f2e50ca3 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -187,7 +187,7 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe->stream)
+- return false;
++ continue;
+
+ if (!pipe->plane_state)
+ return false;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+index d34e0f1314d91..bc4f48ea8d4cc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+@@ -1228,6 +1228,7 @@ int dcn20_populate_dml_pipes_from_context(
+ pipes[pipe_cnt].pipe.src.dcc = false;
+ pipes[pipe_cnt].pipe.src.dcc_rate = 1;
+ pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
++ pipes[pipe_cnt].pipe.dest.synchronize_timings = synchronized_vblank;
+ pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
+ pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
+ - timing->h_addressable
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 52525833a99b9..bea380407151a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -364,7 +364,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
+ v->DSCDelay[k] = dml32_DSCDelayRequirement(mode_lib->vba.DSCEnabled[k],
+ mode_lib->vba.ODMCombineEnabled[k], mode_lib->vba.DSCInputBitPerComponent[k],
+- mode_lib->vba.OutputBpp[k], mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k],
++ mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k],
++ mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k],
+ mode_lib->vba.NumberOfDSCSlices[k], mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.Output[k], mode_lib->vba.PixelClock[k],
+ mode_lib->vba.PixelClockBackEnd[k]);
+@@ -717,6 +718,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+
+ do {
+ MaxTotalRDBandwidth = 0;
++ DestinationLineTimesForPrefetchLessThan2 = false;
++ VRatioPrefetchMoreThanMax = false;
+ #ifdef __DML_VBA_DEBUG__
+ dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, mode_lib->vba.VStartupLines);
+ #endif
+@@ -1627,7 +1630,7 @@ static void mode_support_configuration(struct vba_vars_st *v,
+ && !mode_lib->vba.MSOOrODMSplitWithNonDPLink
+ && !mode_lib->vba.NotEnoughLanesForMSO
+ && mode_lib->vba.LinkCapacitySupport[i] == true && !mode_lib->vba.P2IWith420
+- && !mode_lib->vba.DSCOnlyIfNecessaryWithBPP
++ //&& !mode_lib->vba.DSCOnlyIfNecessaryWithBPP
+ && !mode_lib->vba.DSC422NativeNotSupported
+ && !mode_lib->vba.MPCCombineMethodIncompatible
+ && mode_lib->vba.ODMCombine2To1SupportCheckOK[i] == true
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 365d290bba99e..67af8f4df8b8f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -1746,7 +1746,7 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled,
+ }
+
+ DSCDelayRequirement_val = DSCDelayRequirement_val + (HTotal - HActive) *
+- dml_ceil(DSCDelayRequirement_val / HActive, 1);
++ dml_ceil((double)DSCDelayRequirement_val / HActive, 1);
+
+ DSCDelayRequirement_val = DSCDelayRequirement_val * PixelClock / PixelClockBackEnd;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
+index a1276f6b9581b..395ae8761980f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
+@@ -291,8 +291,8 @@ void dml32_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
+
+ dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, dlg_regs->vready_after_vcount0);
+
+- dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+- dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
++ dst_x_after_scaler = dml_ceil(get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
++ dst_y_after_scaler = dml_ceil(get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
+
+ // do some adjustment on the dst_after scaler to account for odm combine mode
+ dml_print("DML_DLG: %s: input dst_x_after_scaler = %d\n", __func__, dst_x_after_scaler);
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+index 503e7d984ff03..cb34ac0af349f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+@@ -624,7 +624,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
+ mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
+ dout->is_virtual;
+
+- if (!dout->dsc_enable)
++ if (dout->dsc_enable)
+ mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
+ else
+ mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index 7510d470b8643..2347f7bb73d76 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -1131,22 +1131,21 @@ static int smu_smc_hw_setup(struct smu_context *smu)
+ uint64_t features_supported;
+ int ret = 0;
+
+- if (adev->in_suspend && smu_is_dpm_running(smu)) {
+- dev_info(adev->dev, "dpm has been enabled\n");
+- /* this is needed specifically */
+- switch (adev->ip_versions[MP1_HWIP][0]) {
+- case IP_VERSION(11, 0, 7):
+- case IP_VERSION(11, 0, 11):
+- case IP_VERSION(11, 5, 0):
+- case IP_VERSION(11, 0, 12):
++ switch (adev->ip_versions[MP1_HWIP][0]) {
++ case IP_VERSION(11, 0, 7):
++ case IP_VERSION(11, 0, 11):
++ case IP_VERSION(11, 5, 0):
++ case IP_VERSION(11, 0, 12):
++ if (adev->in_suspend && smu_is_dpm_running(smu)) {
++ dev_info(adev->dev, "dpm has been enabled\n");
+ ret = smu_system_features_control(smu, true);
+ if (ret)
+ dev_err(adev->dev, "Failed system features control!\n");
+- break;
+- default:
+- break;
++ return ret;
+ }
+- return ret;
++ break;
++ default:
++ break;
+ }
+
+ ret = smu_init_display_count(smu, 0);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+index b81c657c73860..d63cf9e3676d4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+@@ -1372,6 +1372,14 @@ enum smu_cmn2asic_mapping_type {
+ CMN2ASIC_MAPPING_WORKLOAD,
+ };
+
++enum smu_baco_seq {
++ BACO_SEQ_BACO = 0,
++ BACO_SEQ_MSR,
++ BACO_SEQ_BAMACO,
++ BACO_SEQ_ULPS,
++ BACO_SEQ_COUNT,
++};
++
+ #define MSG_MAP(msg, index, valid_in_vf) \
+ [SMU_MSG_##msg] = {1, (index), (valid_in_vf)}
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
+index a9215494dcddb..d466db6f0ad4f 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
+@@ -147,14 +147,6 @@ struct smu_11_5_power_context {
+ uint32_t max_fast_ppt_limit;
+ };
+
+-enum smu_v11_0_baco_seq {
+- BACO_SEQ_BACO = 0,
+- BACO_SEQ_MSR,
+- BACO_SEQ_BAMACO,
+- BACO_SEQ_ULPS,
+- BACO_SEQ_COUNT,
+-};
+-
+ #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3)
+
+ int smu_v11_0_init_microcode(struct smu_context *smu);
+@@ -257,7 +249,7 @@ int smu_v11_0_baco_enter(struct smu_context *smu);
+ int smu_v11_0_baco_exit(struct smu_context *smu);
+
+ int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+- enum smu_v11_0_baco_seq baco_seq);
++ enum smu_baco_seq baco_seq);
+
+ int smu_v11_0_mode1_reset(struct smu_context *smu);
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index f75b9688f5129..3e29fe4cc4ae4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -123,14 +123,6 @@ struct smu_13_0_power_context {
+ enum smu_13_0_power_state power_state;
+ };
+
+-enum smu_v13_0_baco_seq {
+- BACO_SEQ_BACO = 0,
+- BACO_SEQ_MSR,
+- BACO_SEQ_BAMACO,
+- BACO_SEQ_ULPS,
+- BACO_SEQ_COUNT,
+-};
+-
+ #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3)
+
+ int smu_v13_0_init_microcode(struct smu_context *smu);
+@@ -217,6 +209,9 @@ int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu);
+ int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
+ struct pp_smu_nv_clock_table *max_clocks);
+
++int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu,
++ enum smu_baco_seq baco_seq);
++
+ bool smu_v13_0_baco_is_support(struct smu_context *smu);
+
+ enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index dccbd9f707238..70b560737687e 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -1576,7 +1576,7 @@ int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
+ }
+
+ int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+- enum smu_v11_0_baco_seq baco_seq)
++ enum smu_baco_seq baco_seq)
+ {
+ return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL);
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 750d8da84fac4..33710dcf1eb16 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -2219,6 +2219,15 @@ int smu_v13_0_gfx_ulv_control(struct smu_context *smu,
+ return ret;
+ }
+
++int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu,
++ enum smu_baco_seq baco_seq)
++{
++ return smu_cmn_send_smc_msg_with_param(smu,
++ SMU_MSG_ArmD3,
++ baco_seq,
++ NULL);
++}
++
+ bool smu_v13_0_baco_is_support(struct smu_context *smu)
+ {
+ struct smu_baco_context *smu_baco = &smu->smu_baco;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index 29529328152d0..f0121d1716301 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -120,6 +120,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
+ MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0),
+ MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
+ MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
++ MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
+@@ -1566,6 +1567,31 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
+ NULL);
+ }
+
++static int smu_v13_0_0_baco_enter(struct smu_context *smu)
++{
++ struct smu_baco_context *smu_baco = &smu->smu_baco;
++ struct amdgpu_device *adev = smu->adev;
++
++ if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
++ return smu_v13_0_baco_set_armd3_sequence(smu,
++ smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
++ else
++ return smu_v13_0_baco_enter(smu);
++}
++
++static int smu_v13_0_0_baco_exit(struct smu_context *smu)
++{
++ struct amdgpu_device *adev = smu->adev;
++
++ if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
++ /* Wait for PMFW handling for the Dstate change */
++ usleep_range(10000, 11000);
++ return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
++ } else {
++ return smu_v13_0_baco_exit(smu);
++ }
++}
++
+ static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu)
+ {
+ struct amdgpu_device *adev = smu->adev;
+@@ -1827,8 +1853,8 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ .baco_is_support = smu_v13_0_baco_is_support,
+ .baco_get_state = smu_v13_0_baco_get_state,
+ .baco_set_state = smu_v13_0_baco_set_state,
+- .baco_enter = smu_v13_0_baco_enter,
+- .baco_exit = smu_v13_0_baco_exit,
++ .baco_enter = smu_v13_0_0_baco_enter,
++ .baco_exit = smu_v13_0_0_baco_exit,
+ .mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported,
+ .mode1_reset = smu_v13_0_mode1_reset,
+ .set_mp1_state = smu_v13_0_0_set_mp1_state,
+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 c4102cfb734c2..d74debc584f89 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
+@@ -122,6 +122,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =
+ MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
+ MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0),
+ MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
++ MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
+@@ -1578,6 +1579,31 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
+ return ret;
+ }
+
++static int smu_v13_0_7_baco_enter(struct smu_context *smu)
++{
++ struct smu_baco_context *smu_baco = &smu->smu_baco;
++ struct amdgpu_device *adev = smu->adev;
++
++ if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
++ return smu_v13_0_baco_set_armd3_sequence(smu,
++ smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
++ else
++ return smu_v13_0_baco_enter(smu);
++}
++
++static int smu_v13_0_7_baco_exit(struct smu_context *smu)
++{
++ struct amdgpu_device *adev = smu->adev;
++
++ if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
++ /* Wait for PMFW handling for the Dstate change */
++ usleep_range(10000, 11000);
++ return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
++ } else {
++ return smu_v13_0_baco_exit(smu);
++ }
++}
++
+ static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
+ {
+ struct amdgpu_device *adev = smu->adev;
+@@ -1655,8 +1681,8 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ .baco_is_support = smu_v13_0_baco_is_support,
+ .baco_get_state = smu_v13_0_baco_get_state,
+ .baco_set_state = smu_v13_0_baco_set_state,
+- .baco_enter = smu_v13_0_baco_enter,
+- .baco_exit = smu_v13_0_baco_exit,
++ .baco_enter = smu_v13_0_7_baco_enter,
++ .baco_exit = smu_v13_0_7_baco_exit,
+ .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
+ .mode1_reset = smu_v13_0_mode1_reset,
+ .set_mp1_state = smu_v13_0_7_set_mp1_state,
+diff --git a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
+index 3ea53bb67d3bd..bd61e20770a5b 100644
+--- a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
+@@ -63,23 +63,45 @@
+ ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
+ u8 offset, void *buffer, size_t size)
+ {
++ u8 zero = 0;
++ char *tmpbuf = NULL;
++ /*
++ * As sub-addressing is not supported by all adaptors,
++ * always explicitly read from the start and discard
++ * any bytes that come before the requested offset.
++ * This way, no matter whether the adaptor supports it
++ * or not, we'll end up reading the proper data.
++ */
+ struct i2c_msg msgs[] = {
+ {
+ .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+ .flags = 0,
+ .len = 1,
+- .buf = &offset,
++ .buf = &zero,
+ },
+ {
+ .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+ .flags = I2C_M_RD,
+- .len = size,
++ .len = size + offset,
+ .buf = buffer,
+ },
+ };
+ int ret;
+
++ if (offset) {
++ tmpbuf = kmalloc(size + offset, GFP_KERNEL);
++ if (!tmpbuf)
++ return -ENOMEM;
++
++ msgs[1].buf = tmpbuf;
++ }
++
+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
++ if (tmpbuf)
++ memcpy(buffer, tmpbuf + offset, size);
++
++ kfree(tmpbuf);
++
+ if (ret < 0)
+ return ret;
+ if (ret != ARRAY_SIZE(msgs))
+@@ -208,18 +230,6 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
+ if (ret)
+ return DRM_DP_DUAL_MODE_UNKNOWN;
+
+- /*
+- * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
+- * the offset but ignore it, and instead they just always return
+- * data from the start of the HDMI ID buffer. So for a broken
+- * type 1 HDMI adaptor a single byte read will always give us
+- * 0x44, and for a type 1 DVI adaptor it should give 0x00
+- * (assuming it implements any registers). Fortunately neither
+- * of those values will match the type 2 signature of the
+- * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
+- * the type 2 adaptor detection safely even in the presence
+- * of broken type 1 adaptors.
+- */
+ ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
+ &adaptor_id, sizeof(adaptor_id));
+ drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret);
+@@ -233,11 +243,10 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
+ return DRM_DP_DUAL_MODE_TYPE2_DVI;
+ }
+ /*
+- * If neither a proper type 1 ID nor a broken type 1 adaptor
+- * as described above, assume type 1, but let the user know
+- * that we may have misdetected the type.
++ * If not a proper type 1 ID, still assume type 1, but let
++ * the user know that we may have misdetected the type.
+ */
+- if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0])
++ if (!is_type1_adaptor(adaptor_id))
+ drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id);
+
+ }
+@@ -343,10 +352,8 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
+ * @enable: enable (as opposed to disable) the TMDS output buffers
+ *
+ * Set the state of the TMDS output buffers in the adaptor. For
+- * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As
+- * some type 1 adaptors have problems with registers (see comments
+- * in drm_dp_dual_mode_detect()) we avoid touching the register,
+- * making this function a no-op on type 1 adaptors.
++ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register.
++ * Type1 adaptors do not support any register writes.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure
+diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
+index 8214a0b1ab7f1..203bf8d6c34c4 100644
+--- a/drivers/gpu/drm/drm_drv.c
++++ b/drivers/gpu/drm/drm_drv.c
+@@ -615,7 +615,7 @@ static int drm_dev_init(struct drm_device *dev,
+ mutex_init(&dev->clientlist_mutex);
+ mutex_init(&dev->master_mutex);
+
+- ret = drmm_add_action(dev, drm_dev_init_release, NULL);
++ ret = drmm_add_action_or_reset(dev, drm_dev_init_release, NULL);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
+index 7bb98e6a446d0..5ea5e260118c2 100644
+--- a/drivers/gpu/drm/drm_internal.h
++++ b/drivers/gpu/drm/drm_internal.h
+@@ -104,7 +104,8 @@ static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
+
+ static inline void drm_vblank_destroy_worker(struct drm_vblank_crtc *vblank)
+ {
+- kthread_destroy_worker(vblank->worker);
++ if (vblank->worker)
++ kthread_destroy_worker(vblank->worker);
+ }
+
+ int drm_vblank_worker_init(struct drm_vblank_crtc *vblank);
+diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
+index 6b34fac3f73a0..ab4d1c878fda3 100644
+--- a/drivers/gpu/drm/imx/imx-tve.c
++++ b/drivers/gpu/drm/imx/imx-tve.c
+@@ -218,8 +218,9 @@ static int imx_tve_connector_get_modes(struct drm_connector *connector)
+ return ret;
+ }
+
+-static int imx_tve_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++imx_tve_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ struct imx_tve *tve = con_to_tve(connector);
+ unsigned long rate;
+diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c
+index 011be7ff51e1a..bc8fb4e38d0a7 100644
+--- a/drivers/gpu/drm/lima/lima_devfreq.c
++++ b/drivers/gpu/drm/lima/lima_devfreq.c
+@@ -112,11 +112,6 @@ int lima_devfreq_init(struct lima_device *ldev)
+ unsigned long cur_freq;
+ int ret;
+ const char *regulator_names[] = { "mali", NULL };
+- const char *clk_names[] = { "core", NULL };
+- struct dev_pm_opp_config config = {
+- .regulator_names = regulator_names,
+- .clk_names = clk_names,
+- };
+
+ if (!device_property_present(dev, "operating-points-v2"))
+ /* Optional, continue without devfreq */
+@@ -124,7 +119,15 @@ int lima_devfreq_init(struct lima_device *ldev)
+
+ spin_lock_init(&ldevfreq->lock);
+
+- ret = devm_pm_opp_set_config(dev, &config);
++ /*
++ * clkname is set separately so it is not affected by the optional
++ * regulator setting which may return error.
++ */
++ ret = devm_pm_opp_set_clkname(dev, "core");
++ if (ret)
++ return ret;
++
++ ret = devm_pm_opp_set_regulators(dev, regulator_names);
+ if (ret) {
+ /* Continue if the optional regulator is missing */
+ if (ret != -ENODEV)
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
+index 24b489b6129a0..628806423f7d2 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
+@@ -679,6 +679,9 @@ static int adreno_system_suspend(struct device *dev)
+ struct msm_gpu *gpu = dev_to_gpu(dev);
+ int remaining, ret;
+
++ if (!gpu)
++ return 0;
++
+ suspend_scheduler(gpu);
+
+ remaining = wait_event_timeout(gpu->retire_event,
+@@ -700,7 +703,12 @@ out:
+
+ static int adreno_system_resume(struct device *dev)
+ {
+- resume_scheduler(dev_to_gpu(dev));
++ struct msm_gpu *gpu = dev_to_gpu(dev);
++
++ if (!gpu)
++ return 0;
++
++ resume_scheduler(gpu);
+ return pm_runtime_force_resume(dev);
+ }
+
+diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
+index c2bfcf3f1f403..01aae792ffa98 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.c
++++ b/drivers/gpu/drm/msm/msm_gpu.c
+@@ -993,4 +993,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
+ }
+
+ msm_devfreq_cleanup(gpu);
++
++ platform_set_drvdata(gpu->pdev, NULL);
+ }
+diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
+index 4d935fedd2acc..fd22cf4041af5 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.h
++++ b/drivers/gpu/drm/msm/msm_gpu.h
+@@ -282,6 +282,10 @@ struct msm_gpu {
+ static inline struct msm_gpu *dev_to_gpu(struct device *dev)
+ {
+ struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
++
++ if (!adreno_smmu)
++ return NULL;
++
+ return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
+ }
+
+diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
+index 1e716c23019a1..eb938bfb0573c 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -2505,6 +2505,7 @@ static const struct display_timing logictechno_lt161010_2nh_timing = {
+ static const struct panel_desc logictechno_lt161010_2nh = {
+ .timings = &logictechno_lt161010_2nh_timing,
+ .num_timings = 1,
++ .bpc = 6,
+ .size = {
+ .width = 154,
+ .height = 86,
+@@ -2534,6 +2535,7 @@ static const struct display_timing logictechno_lt170410_2whc_timing = {
+ static const struct panel_desc logictechno_lt170410_2whc = {
+ .timings = &logictechno_lt170410_2whc_timing,
+ .num_timings = 1,
++ .bpc = 8,
+ .size = {
+ .width = 217,
+ .height = 136,
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+index f9aa8b96c6952..1fc04019dfd83 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+@@ -878,10 +878,14 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
+ {
+ struct vop2_video_port *vp = to_vop2_video_port(crtc);
+ struct vop2 *vop2 = vp->vop2;
++ struct drm_crtc_state *old_crtc_state;
+ int ret;
+
+ vop2_lock(vop2);
+
++ old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
++ drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
++
+ drm_crtc_vblank_off(crtc);
+
+ /*
+@@ -997,13 +1001,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
+ static void vop2_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+ {
+- struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane);
++ struct drm_plane_state *old_pstate = NULL;
+ struct vop2_win *win = to_vop2_win(plane);
+ struct vop2 *vop2 = win->vop2;
+
+ drm_dbg(vop2->drm, "%s disable\n", win->data->name);
+
+- if (!old_pstate->crtc)
++ if (state)
++ old_pstate = drm_atomic_get_old_plane_state(state, plane);
++ if (old_pstate && !old_pstate->crtc)
+ return;
+
+ vop2_win_disable(win);
+diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
+index 6b25b2f4f5a30..7ef1a086a6fb9 100644
+--- a/drivers/gpu/drm/scheduler/sched_entity.c
++++ b/drivers/gpu/drm/scheduler/sched_entity.c
+@@ -207,6 +207,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
+ struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
+ finish_cb);
+
++ dma_fence_put(f);
+ INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
+ schedule_work(&job->work);
+ }
+@@ -234,8 +235,10 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
+ struct drm_sched_fence *s_fence = job->s_fence;
+
+ /* Wait for all dependencies to avoid data corruptions */
+- while ((f = drm_sched_job_dependency(job, entity)))
++ while ((f = drm_sched_job_dependency(job, entity))) {
+ dma_fence_wait(f, false);
++ dma_fence_put(f);
++ }
+
+ drm_sched_fence_scheduled(s_fence);
+ dma_fence_set_error(&s_fence->finished, -ESRCH);
+@@ -250,6 +253,7 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
+ continue;
+ }
+
++ dma_fence_get(entity->last_scheduled);
+ r = dma_fence_add_callback(entity->last_scheduled,
+ &job->finish_cb,
+ drm_sched_entity_kill_jobs_cb);
+diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
+index b45dcdfd73064..a3678178b022c 100644
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -198,8 +198,8 @@ vc4_hvs_get_new_global_state(struct drm_atomic_state *state)
+ struct drm_private_state *priv_state;
+
+ priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels);
+- if (IS_ERR(priv_state))
+- return ERR_CAST(priv_state);
++ if (!priv_state)
++ return ERR_PTR(-EINVAL);
+
+ return to_vc4_hvs_state(priv_state);
+ }
+@@ -211,8 +211,8 @@ vc4_hvs_get_old_global_state(struct drm_atomic_state *state)
+ struct drm_private_state *priv_state;
+
+ priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels);
+- if (IS_ERR(priv_state))
+- return ERR_CAST(priv_state);
++ if (!priv_state)
++ return ERR_PTR(-EINVAL);
+
+ return to_vc4_hvs_state(priv_state);
+ }
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index a176296f4fff1..e46561e095c62 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -1243,6 +1243,7 @@ static const struct {
+ */
+ { "Latitude 5480", 0x29 },
+ { "Vostro V131", 0x1d },
++ { "Vostro 5568", 0x29 },
+ };
+
+ static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)
+diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
+index 031c78ac42e67..a24cc413c89b3 100644
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -284,6 +284,7 @@ struct tegra_i2c_dev {
+ struct dma_chan *tx_dma_chan;
+ struct dma_chan *rx_dma_chan;
+ unsigned int dma_buf_size;
++ struct device *dma_dev;
+ dma_addr_t dma_phys;
+ void *dma_buf;
+
+@@ -420,7 +421,7 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
+ static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev)
+ {
+ if (i2c_dev->dma_buf) {
+- dma_free_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
++ dma_free_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
+ i2c_dev->dma_buf, i2c_dev->dma_phys);
+ i2c_dev->dma_buf = NULL;
+ }
+@@ -467,10 +468,13 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
+
+ i2c_dev->tx_dma_chan = chan;
+
++ WARN_ON(i2c_dev->tx_dma_chan->device != i2c_dev->rx_dma_chan->device);
++ i2c_dev->dma_dev = chan->device->dev;
++
+ i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
+ I2C_PACKET_HEADER_SIZE;
+
+- dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
++ dma_buf = dma_alloc_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
+ &dma_phys, GFP_KERNEL | __GFP_NOWARN);
+ if (!dma_buf) {
+ dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n");
+@@ -1267,7 +1271,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+
+ if (i2c_dev->dma_mode) {
+ if (i2c_dev->msg_read) {
+- dma_sync_single_for_device(i2c_dev->dev,
++ dma_sync_single_for_device(i2c_dev->dma_dev,
+ i2c_dev->dma_phys,
+ xfer_size, DMA_FROM_DEVICE);
+
+@@ -1275,7 +1279,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ if (err)
+ return err;
+ } else {
+- dma_sync_single_for_cpu(i2c_dev->dev,
++ dma_sync_single_for_cpu(i2c_dev->dma_dev,
+ i2c_dev->dma_phys,
+ xfer_size, DMA_TO_DEVICE);
+ }
+@@ -1288,7 +1292,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
+ msg->buf, msg->len);
+
+- dma_sync_single_for_device(i2c_dev->dev,
++ dma_sync_single_for_device(i2c_dev->dma_dev,
+ i2c_dev->dma_phys,
+ xfer_size, DMA_TO_DEVICE);
+
+@@ -1339,7 +1343,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ }
+
+ if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
+- dma_sync_single_for_cpu(i2c_dev->dev,
++ dma_sync_single_for_cpu(i2c_dev->dma_dev,
+ i2c_dev->dma_phys,
+ xfer_size, DMA_FROM_DEVICE);
+
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index c31bdd9b168e9..29c9fa99c2bd3 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -737,18 +737,6 @@ static int bma400_init(struct bma400_data *data)
+ unsigned int val;
+ int ret;
+
+- /* Try to read chip_id register. It must return 0x90. */
+- ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
+- if (ret) {
+- dev_err(data->dev, "Failed to read chip id register\n");
+- return ret;
+- }
+-
+- if (val != BMA400_ID_REG_VAL) {
+- dev_err(data->dev, "Chip ID mismatch\n");
+- return -ENODEV;
+- }
+-
+ data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
+ data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio";
+ ret = devm_regulator_bulk_get(data->dev,
+@@ -774,6 +762,18 @@ static int bma400_init(struct bma400_data *data)
+ if (ret)
+ return ret;
+
++ /* Try to read chip_id register. It must return 0x90. */
++ ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
++ if (ret) {
++ dev_err(data->dev, "Failed to read chip id register\n");
++ return ret;
++ }
++
++ if (val != BMA400_ID_REG_VAL) {
++ dev_err(data->dev, "Chip ID mismatch\n");
++ return -ENODEV;
++ }
++
+ ret = bma400_get_power_mode(data);
+ if (ret) {
+ dev_err(data->dev, "Failed to get the initial power-mode\n");
+diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
+index 532daaa6f943c..366e252ebeb07 100644
+--- a/drivers/iio/adc/at91_adc.c
++++ b/drivers/iio/adc/at91_adc.c
+@@ -634,8 +634,10 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev,
+ trig->ops = &at91_adc_trigger_ops;
+
+ ret = iio_trigger_register(trig);
+- if (ret)
++ if (ret) {
++ iio_trigger_free(trig);
+ return NULL;
++ }
+
+ return trig;
+ }
+diff --git a/drivers/iio/adc/mp2629_adc.c b/drivers/iio/adc/mp2629_adc.c
+index 30a31f185d08d..88e947f300cfd 100644
+--- a/drivers/iio/adc/mp2629_adc.c
++++ b/drivers/iio/adc/mp2629_adc.c
+@@ -57,7 +57,8 @@ static struct iio_map mp2629_adc_maps[] = {
+ MP2629_MAP(SYSTEM_VOLT, "system-volt"),
+ MP2629_MAP(INPUT_VOLT, "input-volt"),
+ MP2629_MAP(BATT_CURRENT, "batt-current"),
+- MP2629_MAP(INPUT_CURRENT, "input-current")
++ MP2629_MAP(INPUT_CURRENT, "input-current"),
++ { }
+ };
+
+ static int mp2629_read_raw(struct iio_dev *indio_dev,
+@@ -74,7 +75,7 @@ static int mp2629_read_raw(struct iio_dev *indio_dev,
+ if (ret)
+ return ret;
+
+- if (chan->address == MP2629_INPUT_VOLT)
++ if (chan->channel == MP2629_INPUT_VOLT)
+ rval &= GENMASK(6, 0);
+ *val = rval;
+ return IIO_VAL_INT;
+diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h
+index cbc9349c342a9..550b75b7186fb 100644
+--- a/drivers/iio/pressure/ms5611.h
++++ b/drivers/iio/pressure/ms5611.h
+@@ -25,13 +25,6 @@ enum {
+ MS5607,
+ };
+
+-struct ms5611_chip_info {
+- u16 prom[MS5611_PROM_WORDS_NB];
+-
+- int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
+- s32 *temp, s32 *pressure);
+-};
+-
+ /*
+ * OverSampling Rate descriptor.
+ * Warning: cmd MUST be kept aligned on a word boundary (see
+@@ -50,12 +43,15 @@ struct ms5611_state {
+ const struct ms5611_osr *pressure_osr;
+ const struct ms5611_osr *temp_osr;
+
++ u16 prom[MS5611_PROM_WORDS_NB];
++
+ int (*reset)(struct ms5611_state *st);
+ int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word);
+ int (*read_adc_temp_and_pressure)(struct ms5611_state *st,
+ s32 *temp, s32 *pressure);
+
+- struct ms5611_chip_info *chip_info;
++ int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp,
++ s32 *pressure);
+ struct regulator *vdd;
+ };
+
+diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
+index 717521de66c47..c564a1d6cafe8 100644
+--- a/drivers/iio/pressure/ms5611_core.c
++++ b/drivers/iio/pressure/ms5611_core.c
+@@ -85,7 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+ struct ms5611_state *st = iio_priv(indio_dev);
+
+ for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
+- ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
++ ret = st->read_prom_word(st, i, &st->prom[i]);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev,
+ "failed to read prom at %d\n", i);
+@@ -93,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+ }
+ }
+
+- if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
++ if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
+ dev_err(&indio_dev->dev, "PROM integrity check failed\n");
+ return -ENODEV;
+ }
+@@ -114,21 +114,20 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
+ return ret;
+ }
+
+- return st->chip_info->temp_and_pressure_compensate(st->chip_info,
+- temp, pressure);
++ return st->compensate_temp_and_pressure(st, temp, pressure);
+ }
+
+-static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st,
+ s32 *temp, s32 *pressure)
+ {
+ s32 t = *temp, p = *pressure;
+ s64 off, sens, dt;
+
+- dt = t - (chip_info->prom[5] << 8);
+- off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
+- sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
++ dt = t - (st->prom[5] << 8);
++ off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
++ sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
+
+- t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++ t = 2000 + ((st->prom[6] * dt) >> 23);
+ if (t < 2000) {
+ s64 off2, sens2, t2;
+
+@@ -154,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf
+ return 0;
+ }
+
+-static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st,
+ s32 *temp, s32 *pressure)
+ {
+ s32 t = *temp, p = *pressure;
+ s64 off, sens, dt;
+
+- dt = t - (chip_info->prom[5] << 8);
+- off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
+- sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
++ dt = t - (st->prom[5] << 8);
++ off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6);
++ sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7);
+
+- t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++ t = 2000 + ((st->prom[6] * dt) >> 23);
+ if (t < 2000) {
+ s64 off2, sens2, t2, tmp;
+
+@@ -342,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
+
+ static const unsigned long ms5611_scan_masks[] = {0x3, 0};
+
+-static struct ms5611_chip_info chip_info_tbl[] = {
+- [MS5611] = {
+- .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
+- },
+- [MS5607] = {
+- .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
+- }
+-};
+-
+ static const struct iio_chan_spec ms5611_channels[] = {
+ {
+ .type = IIO_PRESSURE,
+@@ -433,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
+ struct ms5611_state *st = iio_priv(indio_dev);
+
+ mutex_init(&st->lock);
+- st->chip_info = &chip_info_tbl[type];
++
++ switch (type) {
++ case MS5611:
++ st->compensate_temp_and_pressure =
++ ms5611_temp_and_pressure_compensate;
++ break;
++ case MS5607:
++ st->compensate_temp_and_pressure =
++ ms5607_temp_and_pressure_compensate;
++ break;
++ default:
++ return -EINVAL;
++ }
++
+ st->temp_osr =
+ &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
+ st->pressure_osr =
+diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c
+index 432e912096f42..a0a7205c9c3a4 100644
+--- a/drivers/iio/pressure/ms5611_spi.c
++++ b/drivers/iio/pressure/ms5611_spi.c
+@@ -91,7 +91,7 @@ static int ms5611_spi_probe(struct spi_device *spi)
+ spi_set_drvdata(spi, indio_dev);
+
+ spi->mode = SPI_MODE_0;
+- spi->max_speed_hz = 20000000;
++ spi->max_speed_hz = min(spi->max_speed_hz, 20000000U);
+ spi->bits_per_word = 8;
+ ret = spi_setup(spi);
+ if (ret < 0)
+diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
+index d6c5e96447383..6b05eed41612b 100644
+--- a/drivers/iio/trigger/iio-trig-sysfs.c
++++ b/drivers/iio/trigger/iio-trig-sysfs.c
+@@ -203,9 +203,13 @@ static int iio_sysfs_trigger_remove(int id)
+
+ static int __init iio_sysfs_trig_init(void)
+ {
++ int ret;
+ device_initialize(&iio_sysfs_trig_dev);
+ dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
+- return device_add(&iio_sysfs_trig_dev);
++ ret = device_add(&iio_sysfs_trig_dev);
++ if (ret)
++ put_device(&iio_sysfs_trig_dev);
++ return ret;
+ }
+ module_init(iio_sysfs_trig_init);
+
+diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
+index 94b94cca48709..15ee920811187 100644
+--- a/drivers/infiniband/hw/efa/efa_main.c
++++ b/drivers/infiniband/hw/efa/efa_main.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+ /*
+- * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
++ * Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved.
+ */
+
+ #include <linux/module.h>
+@@ -14,10 +14,12 @@
+
+ #define PCI_DEV_ID_EFA0_VF 0xefa0
+ #define PCI_DEV_ID_EFA1_VF 0xefa1
++#define PCI_DEV_ID_EFA2_VF 0xefa2
+
+ static const struct pci_device_id efa_pci_tbl[] = {
+ { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
+ { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
++ { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
+ { }
+ };
+
+diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
+index b86de1312512b..84b87526b7ba3 100644
+--- a/drivers/input/joystick/iforce/iforce-main.c
++++ b/drivers/input/joystick/iforce/iforce-main.c
+@@ -273,22 +273,22 @@ int iforce_init_device(struct device *parent, u16 bustype,
+ * Get device info.
+ */
+
+- if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3)
++ if (!iforce_get_id_packet(iforce, 'M', buf, &len) && len >= 3)
+ input_dev->id.vendor = get_unaligned_le16(buf + 1);
+ else
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
+
+- if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3)
++ if (!iforce_get_id_packet(iforce, 'P', buf, &len) && len >= 3)
+ input_dev->id.product = get_unaligned_le16(buf + 1);
+ else
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
+
+- if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3)
++ if (!iforce_get_id_packet(iforce, 'B', buf, &len) && len >= 3)
+ iforce->device_memory.end = get_unaligned_le16(buf + 1);
+ else
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
+
+- if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2)
++ if (!iforce_get_id_packet(iforce, 'N', buf, &len) && len >= 2)
+ ff_effects = buf[1];
+ else
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index 3fc0a89cc785c..f132d6dfc25eb 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -1543,8 +1543,6 @@ static int i8042_probe(struct platform_device *dev)
+ {
+ int error;
+
+- i8042_platform_device = dev;
+-
+ if (i8042_reset == I8042_RESET_ALWAYS) {
+ error = i8042_controller_selftest();
+ if (error)
+@@ -1582,7 +1580,6 @@ static int i8042_probe(struct platform_device *dev)
+ i8042_free_aux_ports(); /* in case KBD failed but AUX not */
+ i8042_free_irqs();
+ i8042_controller_reset(false);
+- i8042_platform_device = NULL;
+
+ return error;
+ }
+@@ -1592,7 +1589,6 @@ static int i8042_remove(struct platform_device *dev)
+ i8042_unregister_ports();
+ i8042_free_irqs();
+ i8042_controller_reset(false);
+- i8042_platform_device = NULL;
+
+ return 0;
+ }
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index ecc0b05b2796c..e47700674978c 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -954,11 +954,9 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
+
+ domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
+ pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
+- if (domain_use_first_level(domain)) {
+- pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
+- if (iommu_is_dma_domain(&domain->domain))
+- pteval |= DMA_FL_PTE_ACCESS;
+- }
++ if (domain_use_first_level(domain))
++ pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
++
+ if (cmpxchg64(&pte->val, 0ULL, pteval))
+ /* Someone else set it while we were thinking; use theirs. */
+ free_pgtable_page(tmp_page);
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index c5e7e8b020a57..12584c7981ac4 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -652,7 +652,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
+ * Since it is a second level only translation setup, we should
+ * set SRE bit as well (addresses are expected to be GPAs).
+ */
+- if (pasid != PASID_RID2PASID)
++ if (pasid != PASID_RID2PASID && ecap_srs(iommu->ecap))
+ pasid_set_sre(pte);
+ pasid_set_present(pte);
+ spin_unlock(&iommu->lock);
+@@ -695,7 +695,8 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
+ * We should set SRE bit as well since the addresses are expected
+ * to be GPAs.
+ */
+- pasid_set_sre(pte);
++ if (ecap_srs(iommu->ecap))
++ pasid_set_sre(pte);
+ pasid_set_present(pte);
+ spin_unlock(&iommu->lock);
+
+diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
+index 7ea0100f218a0..90ee56d07a6e9 100644
+--- a/drivers/isdn/mISDN/core.c
++++ b/drivers/isdn/mISDN/core.c
+@@ -222,7 +222,7 @@ mISDN_register_device(struct mISDNdevice *dev,
+
+ err = get_free_devid();
+ if (err < 0)
+- goto error1;
++ return err;
+ dev->id = err;
+
+ device_initialize(&dev->dev);
+diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
+index c3b2c99b5cd5c..cfbcd9e973c2e 100644
+--- a/drivers/isdn/mISDN/dsp_pipeline.c
++++ b/drivers/isdn/mISDN/dsp_pipeline.c
+@@ -77,6 +77,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
+ if (!entry)
+ return -ENOMEM;
+
++ INIT_LIST_HEAD(&entry->list);
+ entry->elem = elem;
+
+ entry->dev.class = elements_class;
+@@ -107,7 +108,7 @@ err2:
+ device_unregister(&entry->dev);
+ return ret;
+ err1:
+- kfree(entry);
++ put_device(&entry->dev);
+ return ret;
+ }
+ EXPORT_SYMBOL(mISDN_dsp_element_register);
+diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
+index 9c5ef818ca365..bb786c39545ec 100644
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -1858,6 +1858,8 @@ bad:
+ dm_io_client_destroy(c->dm_io);
+ bad_dm_io:
+ mutex_destroy(&c->lock);
++ if (c->no_sleep)
++ static_branch_dec(&no_sleep_enabled);
+ kfree(c);
+ bad_client:
+ return ERR_PTR(r);
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 159c6806c19b8..2653516bcdef5 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -3630,6 +3630,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
+ limits->physical_block_size =
+ max_t(unsigned, limits->physical_block_size, cc->sector_size);
+ limits->io_min = max_t(unsigned, limits->io_min, cc->sector_size);
++ limits->dma_alignment = limits->logical_block_size - 1;
+ }
+
+ static struct target_type crypt_target = {
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 98976aaa9db9a..9cd410d8fbeb4 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -655,7 +655,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param)
+ size_t *needed = needed_param;
+
+ *needed += sizeof(struct dm_target_versions);
+- *needed += strlen(tt->name);
++ *needed += strlen(tt->name) + 1;
+ *needed += ALIGN_MASK;
+ }
+
+@@ -720,7 +720,7 @@ static int __list_versions(struct dm_ioctl *param, size_t param_size, const char
+ iter_info.old_vers = NULL;
+ iter_info.vers = vers;
+ iter_info.flags = 0;
+- iter_info.end = (char *)vers+len;
++ iter_info.end = (char *)vers + needed;
+
+ /*
+ * Now loop through filling out the names & versions.
+diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
+index 8f2de1893245a..8f970fe9bb6e4 100644
+--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
++++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
+@@ -854,6 +854,7 @@ static int qp_notify_peer_local(bool attach, struct vmci_handle handle)
+ u32 context_id = vmci_get_context_id();
+ struct vmci_event_qp ev;
+
++ memset(&ev, 0, sizeof(ev));
+ ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER);
+ ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
+ VMCI_CONTEXT_RESOURCE_ID);
+@@ -1467,6 +1468,7 @@ static int qp_notify_peer(bool attach,
+ * kernel.
+ */
+
++ memset(&ev, 0, sizeof(ev));
+ ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER);
+ ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
+ VMCI_CONTEXT_RESOURCE_ID);
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index ef53a25788248..3d96493257257 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1134,7 +1134,13 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
+ mmc_power_cycle(host, ocr);
+ } else {
+ bit = fls(ocr) - 1;
+- ocr &= 3 << bit;
++ /*
++ * The bit variable represents the highest voltage bit set in
++ * the OCR register.
++ * To keep a range of 2 values (e.g. 3.2V/3.3V and 3.3V/3.4V),
++ * we must shift the mask '3' with (bit - 1).
++ */
++ ocr &= 3 << (bit - 1);
+ if (bit != host->ios.vdd)
+ dev_warn(mmc_dev(host), "exceeding card's volts\n");
+ }
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index b6f4bd3d93cd8..c55a77a10c632 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -1728,6 +1728,8 @@ static int amd_probe(struct sdhci_pci_chip *chip)
+ }
+ }
+
++ pci_dev_put(smbus_dev);
++
+ if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ)
+ chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD;
+
+diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
+index 0d4d343dbb77d..7a7cce6bc44d2 100644
+--- a/drivers/mmc/host/sdhci-pci-o2micro.c
++++ b/drivers/mmc/host/sdhci-pci-o2micro.c
+@@ -32,6 +32,7 @@
+ #define O2_SD_CAPS 0xE0
+ #define O2_SD_ADMA1 0xE2
+ #define O2_SD_ADMA2 0xE7
++#define O2_SD_MISC_CTRL2 0xF0
+ #define O2_SD_INF_MOD 0xF1
+ #define O2_SD_MISC_CTRL4 0xFC
+ #define O2_SD_MISC_CTRL 0x1C0
+@@ -874,6 +875,12 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
+ /* Set Tuning Windows to 5 */
+ pci_write_config_byte(chip->pdev,
+ O2_SD_TUNING_CTRL, 0x55);
++ //Adjust 1st and 2nd CD debounce time
++ pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32);
++ scratch_32 &= 0xFFE7FFFF;
++ scratch_32 |= 0x00180000;
++ pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32);
++ pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1);
+ /* Lock WP */
+ ret = pci_read_config_byte(chip->pdev,
+ O2_SD_LOCK_WP, &scratch);
+diff --git a/drivers/mtd/nand/onenand/Kconfig b/drivers/mtd/nand/onenand/Kconfig
+index 34d9a7a82ad4e..c94bf483541e1 100644
+--- a/drivers/mtd/nand/onenand/Kconfig
++++ b/drivers/mtd/nand/onenand/Kconfig
+@@ -26,6 +26,7 @@ config MTD_ONENAND_OMAP2
+ tristate "OneNAND on OMAP2/OMAP3 support"
+ depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM)
+ depends on OF || COMPILE_TEST
++ depends on OMAP_GPMC
+ help
+ Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC
+ via the GPMC memory controller.
+diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
+index 8f80019a9f016..198a44794d2dc 100644
+--- a/drivers/mtd/nand/raw/qcom_nandc.c
++++ b/drivers/mtd/nand/raw/qcom_nandc.c
+@@ -3167,16 +3167,18 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
+
+ ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
+ if (ret)
+- nand_cleanup(chip);
++ goto err;
+
+ if (nandc->props->use_codeword_fixup) {
+ ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn);
+- if (ret) {
+- nand_cleanup(chip);
+- return ret;
+- }
++ if (ret)
++ goto err;
+ }
+
++ return 0;
++
++err:
++ nand_cleanup(chip);
+ return ret;
+ }
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 6a356a6cee15a..41c8213484769 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -4545,13 +4545,19 @@ static struct pci_driver ena_pci_driver = {
+
+ static int __init ena_init(void)
+ {
++ int ret;
++
+ ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME);
+ if (!ena_wq) {
+ pr_err("Failed to create workqueue\n");
+ return -ENOMEM;
+ }
+
+- return pci_register_driver(&ena_pci_driver);
++ ret = pci_register_driver(&ena_pci_driver);
++ if (ret)
++ destroy_workqueue(ena_wq);
++
++ return ret;
+ }
+
+ static void __exit ena_cleanup(void)
+diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
+index e461f47640660..e23d8734d4e44 100644
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1427,7 +1427,7 @@ static int ag71xx_open(struct net_device *ndev)
+ if (ret) {
+ netif_err(ag, link, ndev, "phylink_of_phy_connect filed with err: %i\n",
+ ret);
+- goto err;
++ return ret;
+ }
+
+ max_frame_len = ag71xx_max_frame_len(ndev->mtu);
+@@ -1448,6 +1448,7 @@ static int ag71xx_open(struct net_device *ndev)
+
+ err:
+ ag71xx_rings_cleanup(ag);
++ phylink_disconnect_phy(ag->phylink);
+ return ret;
+ }
+
+diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
+index 93580484a3f4e..91c054eef7018 100644
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -1568,7 +1568,6 @@ void bgmac_enet_remove(struct bgmac *bgmac)
+ phy_disconnect(bgmac->net_dev->phydev);
+ netif_napi_del(&bgmac->napi);
+ bgmac_dma_free(bgmac);
+- free_netdev(bgmac->net_dev);
+ }
+ EXPORT_SYMBOL_GPL(bgmac_enet_remove);
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index be5df8fca264e..57cabe20aa122 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
+ return -ENODEV;
+ }
+
+-int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
++static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset)
+ {
+ struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
+- int rc;
+
+ if (!BNXT_NEW_RM(bp))
+- return 0; /* no resource reservations required */
+-
+- rc = bnxt_hwrm_func_resc_qcaps(bp, true);
+- if (rc)
+- netdev_err(bp->dev, "resc_qcaps failed\n");
++ return; /* no resource reservations required */
+
+ hw_resc->resv_cp_rings = 0;
+ hw_resc->resv_stat_ctxs = 0;
+@@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
+ bp->tx_nr_rings = 0;
+ bp->rx_nr_rings = 0;
+ }
++}
++
++int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
++{
++ int rc;
++
++ if (!BNXT_NEW_RM(bp))
++ return 0; /* no resource reservations required */
++
++ rc = bnxt_hwrm_func_resc_qcaps(bp, true);
++ if (rc)
++ netdev_err(bp->dev, "resc_qcaps failed\n");
++
++ bnxt_clear_reservations(bp, fw_reset);
+
+ return rc;
+ }
+@@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
+ pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct bnxt *bp = netdev_priv(netdev);
+- int err = 0, off;
++ int retry = 0;
++ int err = 0;
++ int off;
+
+ netdev_info(bp->dev, "PCI Slot Reset\n");
+
+@@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+
++ bnxt_inv_fw_health_reg(bp);
++ bnxt_try_map_fw_health_reg(bp);
++
++ /* In some PCIe AER scenarios, firmware may take up to
++ * 10 seconds to become ready in the worst case.
++ */
++ do {
++ err = bnxt_try_recover_fw(bp);
++ if (!err)
++ break;
++ retry++;
++ } while (retry < BNXT_FW_SLOT_RESET_RETRY);
++
++ if (err) {
++ dev_err(&pdev->dev, "Firmware not ready\n");
++ goto reset_exit;
++ }
++
+ err = bnxt_hwrm_func_reset(bp);
+ if (!err)
+ result = PCI_ERS_RESULT_RECOVERED;
++
++ bnxt_ulp_irq_stop(bp);
++ bnxt_clear_int_mode(bp);
++ err = bnxt_init_int_mode(bp);
++ bnxt_ulp_irq_restart(bp, err);
+ }
+
++reset_exit:
++ bnxt_clear_reservations(bp, true);
+ rtnl_unlock();
+
+ return result;
+@@ -14001,8 +14037,16 @@ static struct pci_driver bnxt_pci_driver = {
+
+ static int __init bnxt_init(void)
+ {
++ int err;
++
+ bnxt_debug_init();
+- return pci_register_driver(&bnxt_pci_driver);
++ err = pci_register_driver(&bnxt_pci_driver);
++ if (err) {
++ bnxt_debug_exit();
++ return err;
++ }
++
++ return 0;
+ }
+
+ static void __exit bnxt_exit(void)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index b1b17f9113006..d5fa43cfe5248 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -1621,6 +1621,7 @@ struct bnxt_fw_health {
+
+ #define BNXT_FW_RETRY 5
+ #define BNXT_FW_IF_RETRY 10
++#define BNXT_FW_SLOT_RESET_RETRY 4
+
+ enum board_idx {
+ BCM57301,
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+index b01d42928a53c..132442f16fe67 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
+ memset(ctx->resp, 0, PAGE_SIZE);
+
+ req_type = le16_to_cpu(ctx->req->req_type);
+- if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) {
++ if (BNXT_NO_FW_ACCESS(bp) &&
++ (req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) {
+ netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n",
+ req_type);
+ goto exit;
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index bee35ce601710..bf6a721430400 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1799,13 +1799,10 @@ static int liquidio_open(struct net_device *netdev)
+
+ ifstate_set(lio, LIO_IFSTATE_RUNNING);
+
+- if (OCTEON_CN23XX_PF(oct)) {
+- if (!oct->msix_on)
+- if (setup_tx_poll_fn(netdev))
+- return -1;
+- } else {
+- if (setup_tx_poll_fn(netdev))
+- return -1;
++ if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++ ret = setup_tx_poll_fn(netdev);
++ if (ret)
++ goto err_poll;
+ }
+
+ netif_tx_start_all_queues(netdev);
+@@ -1818,7 +1815,7 @@ static int liquidio_open(struct net_device *netdev)
+ /* tell Octeon to start forwarding packets to host */
+ ret = send_rx_ctrl_cmd(lio, 1);
+ if (ret)
+- return ret;
++ goto err_rx_ctrl;
+
+ /* start periodical statistics fetch */
+ INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats);
+@@ -1829,6 +1826,27 @@ static int liquidio_open(struct net_device *netdev)
+ dev_info(&oct->pci_dev->dev, "%s interface is opened\n",
+ netdev->name);
+
++ return 0;
++
++err_rx_ctrl:
++ if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++ cleanup_tx_poll_fn(netdev);
++err_poll:
++ if (lio->ptp_clock) {
++ ptp_clock_unregister(lio->ptp_clock);
++ lio->ptp_clock = NULL;
++ }
++
++ if (oct->props[lio->ifidx].napi_enabled == 1) {
++ list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
++ napi_disable(napi);
++
++ oct->props[lio->ifidx].napi_enabled = 0;
++
++ if (OCTEON_CN23XX_PF(oct))
++ oct->droq[0]->ops.poll_mode = 0;
++ }
++
+ return ret;
+ }
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+index 94f80e1c4020c..bf7daab886895 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+@@ -790,7 +790,6 @@ struct hnae3_knic_private_info {
+ const struct hnae3_dcb_ops *dcb_ops;
+
+ u16 int_rl_setting;
+- enum pkt_hash_types rss_type;
+ void __iomem *io_base;
+ };
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
+index e23729ac3bb85..ae2736549526b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
+@@ -191,23 +191,6 @@ u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)
+ return HCLGE_COMM_RSS_KEY_SIZE;
+ }
+
+-void hclge_comm_get_rss_type(struct hnae3_handle *nic,
+- struct hclge_comm_rss_tuple_cfg *rss_tuple_sets)
+-{
+- if (rss_tuple_sets->ipv4_tcp_en ||
+- rss_tuple_sets->ipv4_udp_en ||
+- rss_tuple_sets->ipv4_sctp_en ||
+- rss_tuple_sets->ipv6_tcp_en ||
+- rss_tuple_sets->ipv6_udp_en ||
+- rss_tuple_sets->ipv6_sctp_en)
+- nic->kinfo.rss_type = PKT_HASH_TYPE_L4;
+- else if (rss_tuple_sets->ipv4_fragment_en ||
+- rss_tuple_sets->ipv6_fragment_en)
+- nic->kinfo.rss_type = PKT_HASH_TYPE_L3;
+- else
+- nic->kinfo.rss_type = PKT_HASH_TYPE_NONE;
+-}
+-
+ int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,
+ const u8 hfunc, u8 *hash_algo)
+ {
+@@ -344,9 +327,6 @@ int hclge_comm_set_rss_input_tuple(struct hnae3_handle *nic,
+ req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
+ req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;
+
+- if (is_pf)
+- hclge_comm_get_rss_type(nic, &rss_cfg->rss_tuple_sets);
+-
+ ret = hclge_comm_cmd_send(hw, &desc, 1);
+ if (ret)
+ dev_err(&hw->cmq.csq.pdev->dev,
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
+index 946d166a452db..92af3d2980d3c 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
+@@ -95,8 +95,6 @@ struct hclge_comm_rss_tc_mode_cmd {
+ };
+
+ u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle);
+-void hclge_comm_get_rss_type(struct hnae3_handle *nic,
+- struct hclge_comm_rss_tuple_cfg *rss_tuple_sets);
+ void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev,
+ struct hclge_comm_rss_cfg *rss_cfg);
+ int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 35d70041b9e84..44d4265f109a8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -105,26 +105,28 @@ static const struct pci_device_id hns3_pci_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(pci, hns3_pci_tbl);
+
+-#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t) \
++#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t, h) \
+ { ptype, \
+ l, \
+ CHECKSUM_##s, \
+ HNS3_L3_TYPE_##t, \
+- 1 }
++ 1, \
++ h}
+
+ #define HNS3_RX_PTYPE_UNUSED_ENTRY(ptype) \
+- { ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0 }
++ { ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0, \
++ PKT_HASH_TYPE_NONE }
+
+ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ HNS3_RX_PTYPE_UNUSED_ENTRY(0),
+- HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP),
+- HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP),
+- HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP),
+- HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM),
+- HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL),
++ HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(9),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(10),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(11),
+@@ -132,36 +134,36 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ HNS3_RX_PTYPE_UNUSED_ENTRY(13),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(14),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(15),
+- HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4),
++ HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(26),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(27),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(28),
+- HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4),
++ HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(38),
+- HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6),
++ HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(46),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(47),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(48),
+@@ -227,35 +229,35 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ HNS3_RX_PTYPE_UNUSED_ENTRY(108),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(109),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(110),
+- HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6),
++ HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(120),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(121),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(122),
+- HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL),
+- HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4),
+- HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4),
+- HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4),
++ HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++ HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(132),
+- HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6),
+- HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6),
+- HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6),
++ HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++ HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++ HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(140),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(141),
+ HNS3_RX_PTYPE_UNUSED_ENTRY(142),
+@@ -3734,8 +3736,8 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
+ desc_cb->reuse_flag = 1;
+ } else if (frag_size <= ring->rx_copybreak) {
+ ret = hns3_handle_rx_copybreak(skb, i, ring, pull_len, desc_cb);
+- if (ret)
+- goto out;
++ if (!ret)
++ return;
+ }
+
+ out:
+@@ -4129,15 +4131,35 @@ static int hns3_set_gro_and_checksum(struct hns3_enet_ring *ring,
+ }
+
+ static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring,
+- struct sk_buff *skb, u32 rss_hash)
++ struct sk_buff *skb, u32 rss_hash,
++ u32 l234info, u32 ol_info)
+ {
+- struct hnae3_handle *handle = ring->tqp->handle;
+- enum pkt_hash_types rss_type;
++ enum pkt_hash_types rss_type = PKT_HASH_TYPE_NONE;
++ struct net_device *netdev = ring_to_netdev(ring);
++ struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+- if (rss_hash)
+- rss_type = handle->kinfo.rss_type;
+- else
+- rss_type = PKT_HASH_TYPE_NONE;
++ if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
++ u32 ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
++ HNS3_RXD_PTYPE_S);
++
++ rss_type = hns3_rx_ptype_tbl[ptype].hash_type;
++ } else {
++ int l3_type = hnae3_get_field(l234info, HNS3_RXD_L3ID_M,
++ HNS3_RXD_L3ID_S);
++ int l4_type = hnae3_get_field(l234info, HNS3_RXD_L4ID_M,
++ HNS3_RXD_L4ID_S);
++
++ if (l3_type == HNS3_L3_TYPE_IPV4 ||
++ l3_type == HNS3_L3_TYPE_IPV6) {
++ if (l4_type == HNS3_L4_TYPE_UDP ||
++ l4_type == HNS3_L4_TYPE_TCP ||
++ l4_type == HNS3_L4_TYPE_SCTP)
++ rss_type = PKT_HASH_TYPE_L4;
++ else if (l4_type == HNS3_L4_TYPE_IGMP ||
++ l4_type == HNS3_L4_TYPE_ICMP)
++ rss_type = PKT_HASH_TYPE_L3;
++ }
++ }
+
+ skb_set_hash(skb, rss_hash, rss_type);
+ }
+@@ -4240,7 +4262,8 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb)
+
+ ring->tqp_vector->rx_group.total_bytes += len;
+
+- hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash));
++ hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash),
++ l234info, ol_info);
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index 4a3253692dcc8..408635d11a24d 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -404,6 +404,7 @@ struct hns3_rx_ptype {
+ u32 ip_summed : 2;
+ u32 l3_type : 4;
+ u32 valid : 1;
++ u32 hash_type: 3;
+ };
+
+ struct ring_stats {
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index fae79764dc442..7e8a60f2401c9 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -3246,6 +3246,7 @@ static int hclge_update_tp_port_info(struct hclge_dev *hdev)
+ hdev->hw.mac.autoneg = cmd.base.autoneg;
+ hdev->hw.mac.speed = cmd.base.speed;
+ hdev->hw.mac.duplex = cmd.base.duplex;
++ linkmode_copy(hdev->hw.mac.advertising, cmd.link_modes.advertising);
+
+ return 0;
+ }
+@@ -4662,7 +4663,6 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
+ return ret;
+ }
+
+- hclge_comm_get_rss_type(&vport->nic, &hdev->rss_cfg.rss_tuple_sets);
+ return 0;
+ }
+
+@@ -11374,9 +11374,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
+ if (ret)
+ goto err_msi_irq_uninit;
+
+- if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER &&
+- !hnae3_dev_phy_imp_supported(hdev)) {
+- ret = hclge_mac_mdio_config(hdev);
++ if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) {
++ if (hnae3_dev_phy_imp_supported(hdev))
++ ret = hclge_update_tp_port_info(hdev);
++ else
++ ret = hclge_mac_mdio_config(hdev);
++
+ if (ret)
+ goto err_msi_irq_uninit;
+ }
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index c23ee2ddbce3e..1a6534c35ef30 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -1478,8 +1478,15 @@ static struct pci_driver hinic_driver = {
+
+ static int __init hinic_module_init(void)
+ {
++ int ret;
++
+ hinic_dbg_register_debugfs(HINIC_DRV_NAME);
+- return pci_register_driver(&hinic_driver);
++
++ ret = pci_register_driver(&hinic_driver);
++ if (ret)
++ hinic_dbg_unregister_debugfs();
++
++ return ret;
+ }
+
+ static void __exit hinic_module_exit(void)
+diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+index 97f080c66dd47..8a6a81bcec5cc 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+@@ -521,14 +521,12 @@ static int octep_open(struct net_device *netdev)
+ octep_oq_dbell_init(oct);
+
+ ret = octep_get_link_status(oct);
+- if (ret)
++ if (ret > 0)
+ octep_link_up(netdev);
+
+ return 0;
+
+ set_queues_err:
+- octep_napi_disable(oct);
+- octep_napi_delete(oct);
+ octep_clean_irqs(oct);
+ setup_irq_err:
+ octep_free_oqs(oct);
+@@ -958,7 +956,7 @@ int octep_device_setup(struct octep_device *oct)
+ ret = octep_ctrl_mbox_init(ctrl_mbox);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize control mbox\n");
+- return -1;
++ goto unsupported_dev;
+ }
+ oct->ctrl_mbox_ifstats_offset = OCTEP_CTRL_MBOX_SZ(ctrl_mbox->h2fq.elem_sz,
+ ctrl_mbox->h2fq.elem_cnt,
+@@ -968,6 +966,10 @@ int octep_device_setup(struct octep_device *oct)
+ return 0;
+
+ unsupported_dev:
++ for (i = 0; i < OCTEP_MMIO_REGIONS; i++)
++ iounmap(oct->mmio[i].hw_addr);
++
++ kfree(oct->conf);
+ return -1;
+ }
+
+@@ -1070,7 +1072,11 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ netdev->max_mtu = OCTEP_MAX_MTU;
+ netdev->mtu = OCTEP_DEFAULT_MTU;
+
+- octep_get_mac_addr(octep_dev, octep_dev->mac_addr);
++ err = octep_get_mac_addr(octep_dev, octep_dev->mac_addr);
++ if (err) {
++ dev_err(&pdev->dev, "Failed to get mac address\n");
++ goto register_dev_err;
++ }
+ eth_hw_addr_set(netdev, octep_dev->mac_addr);
+
+ err = register_netdev(netdev);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+index 4efccd942fb89..1290b2d3eae6b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+@@ -3470,6 +3470,8 @@ mlxsw_sp_switchdev_vxlan_fdb_del(struct mlxsw_sp *mlxsw_sp,
+ u16 vid;
+
+ vxlan_fdb_info = &switchdev_work->vxlan_fdb_info;
++ if (!vxlan_fdb_info->offloaded)
++ return;
+
+ bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
+ if (!bridge_device)
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+index fea42542be280..06811c60d598e 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+@@ -716,6 +716,9 @@ int lan966x_stats_init(struct lan966x *lan966x)
+ snprintf(queue_name, sizeof(queue_name), "%s-stats",
+ dev_name(lan966x->dev));
+ lan966x->stats_queue = create_singlethread_workqueue(queue_name);
++ if (!lan966x->stats_queue)
++ return -ENOMEM;
++
+ INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
+ queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
+ LAN966X_STATS_CHECK_DELAY);
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
+index 6b0febcb7fa99..01f3a3a41cdb3 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
+@@ -1253,6 +1253,9 @@ int sparx_stats_init(struct sparx5 *sparx5)
+ snprintf(queue_name, sizeof(queue_name), "%s-stats",
+ dev_name(sparx5->dev));
+ sparx5->stats_queue = create_singlethread_workqueue(queue_name);
++ if (!sparx5->stats_queue)
++ return -ENOMEM;
++
+ INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
+ queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
+ SPX5_STATS_CHECK_DELAY);
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index 01be7bd841813..30815c0e3f76a 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -657,6 +657,9 @@ static int sparx5_start(struct sparx5 *sparx5)
+ snprintf(queue_name, sizeof(queue_name), "%s-mact",
+ dev_name(sparx5->dev));
+ sparx5->mact_queue = create_singlethread_workqueue(queue_name);
++ if (!sparx5->mact_queue)
++ return -ENOMEM;
++
+ INIT_DELAYED_WORK(&sparx5->mact_work, sparx5_mact_pull_work);
+ queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work,
+ SPX5_MACT_PULL_DELAY);
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index b1b1b648e40cb..b19bff0db1fdc 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1440,15 +1440,15 @@ nfp_port_get_module_info(struct net_device *netdev,
+
+ if (data < 0x3) {
+ modinfo->type = ETH_MODULE_SFF_8436;
+- modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
+ } else {
+ modinfo->type = ETH_MODULE_SFF_8636;
+- modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ }
+ break;
+ case NFP_INTERFACE_QSFP28:
+ modinfo->type = ETH_MODULE_SFF_8636;
+- modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ default:
+ netdev_err(netdev, "Unsupported module 0x%x detected\n",
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
+index 56f93b0305519..5456c2b15d9bd 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
+@@ -687,8 +687,14 @@ int ionic_port_reset(struct ionic *ionic)
+
+ static int __init ionic_init_module(void)
+ {
++ int ret;
++
+ ionic_debugfs_create();
+- return ionic_bus_register_driver();
++ ret = ionic_bus_register_driver();
++ if (ret)
++ ionic_debugfs_destroy();
++
++ return ret;
+ }
+
+ static void __exit ionic_cleanup_module(void)
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index bc060ef558d37..02827829463f6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -6564,6 +6564,9 @@ void stmmac_xdp_release(struct net_device *dev)
+ struct stmmac_priv *priv = netdev_priv(dev);
+ u32 chan;
+
++ /* Ensure tx function is not running */
++ netif_tx_disable(dev);
++
+ /* Disable NAPI process */
+ stmmac_disable_all_queues(priv);
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 9983d37ee87d9..0a0c4d0ffc198 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -141,7 +141,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source(
+ u32 idx = macvlan_eth_hash(addr);
+ struct hlist_head *h = &vlan->port->vlan_source_hash[idx];
+
+- hlist_for_each_entry_rcu(entry, h, hlist) {
++ hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
+ if (ether_addr_equal_64bits(entry->addr, addr) &&
+ entry->vlan == vlan)
+ return entry;
+@@ -1192,7 +1192,7 @@ void macvlan_common_setup(struct net_device *dev)
+ {
+ ether_setup(dev);
+
+- dev->min_mtu = 0;
++ /* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */
+ dev->max_mtu = ETH_MAX_MTU;
+ dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ netif_keep_dst(dev);
+@@ -1647,7 +1647,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb,
+ struct hlist_head *h = &vlan->port->vlan_source_hash[i];
+ struct macvlan_source_entry *entry;
+
+- hlist_for_each_entry_rcu(entry, h, hlist) {
++ hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
+ if (entry->vlan != vlan)
+ continue;
+ if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
+diff --git a/drivers/net/mctp/mctp-i2c.c b/drivers/net/mctp/mctp-i2c.c
+index 53846c6b56ca2..aca3697b09620 100644
+--- a/drivers/net/mctp/mctp-i2c.c
++++ b/drivers/net/mctp/mctp-i2c.c
+@@ -43,6 +43,7 @@
+ enum {
+ MCTP_I2C_FLOW_STATE_NEW = 0,
+ MCTP_I2C_FLOW_STATE_ACTIVE,
++ MCTP_I2C_FLOW_STATE_INVALID,
+ };
+
+ /* List of all struct mctp_i2c_client
+@@ -374,12 +375,18 @@ mctp_i2c_get_tx_flow_state(struct mctp_i2c_dev *midev, struct sk_buff *skb)
+ */
+ if (!key->valid) {
+ state = MCTP_I2C_TX_FLOW_INVALID;
+-
+- } else if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_NEW) {
+- key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE;
+- state = MCTP_I2C_TX_FLOW_NEW;
+ } else {
+- state = MCTP_I2C_TX_FLOW_EXISTING;
++ switch (key->dev_flow_state) {
++ case MCTP_I2C_FLOW_STATE_NEW:
++ key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE;
++ state = MCTP_I2C_TX_FLOW_NEW;
++ break;
++ case MCTP_I2C_FLOW_STATE_ACTIVE:
++ state = MCTP_I2C_TX_FLOW_EXISTING;
++ break;
++ default:
++ state = MCTP_I2C_TX_FLOW_INVALID;
++ }
+ }
+
+ spin_unlock_irqrestore(&key->lock, flags);
+@@ -617,21 +624,31 @@ static void mctp_i2c_release_flow(struct mctp_dev *mdev,
+
+ {
+ struct mctp_i2c_dev *midev = netdev_priv(mdev->dev);
++ bool queue_release = false;
+ unsigned long flags;
+
+ spin_lock_irqsave(&midev->lock, flags);
+- midev->release_count++;
+- spin_unlock_irqrestore(&midev->lock, flags);
+-
+- /* Ensure we have a release operation queued, through the fake
+- * marker skb
++ /* if we have seen the flow/key previously, we need to pair the
++ * original lock with a release
+ */
+- spin_lock(&midev->tx_queue.lock);
+- if (!midev->unlock_marker.next)
+- __skb_queue_tail(&midev->tx_queue, &midev->unlock_marker);
+- spin_unlock(&midev->tx_queue.lock);
++ if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE) {
++ midev->release_count++;
++ queue_release = true;
++ }
++ key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID;
++ spin_unlock_irqrestore(&midev->lock, flags);
+
+- wake_up(&midev->tx_wq);
++ if (queue_release) {
++ /* Ensure we have a release operation queued, through the fake
++ * marker skb
++ */
++ spin_lock(&midev->tx_queue.lock);
++ if (!midev->unlock_marker.next)
++ __skb_queue_tail(&midev->tx_queue,
++ &midev->unlock_marker);
++ spin_unlock(&midev->tx_queue.lock);
++ wake_up(&midev->tx_wq);
++ }
+ }
+
+ static const struct net_device_ops mctp_i2c_ops = {
+diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c
+index 0b1b6f650104b..0b9d379791332 100644
+--- a/drivers/net/mhi_net.c
++++ b/drivers/net/mhi_net.c
+@@ -343,6 +343,8 @@ static void mhi_net_dellink(struct mhi_device *mhi_dev, struct net_device *ndev)
+
+ kfree_skb(mhi_netdev->skbagg_head);
+
++ free_netdev(ndev);
++
+ dev_set_drvdata(&mhi_dev->dev, NULL);
+ }
+
+diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
+index b17e4e94a060e..38562ed833dae 100644
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -1675,6 +1675,7 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev)
+ ARRAY_SIZE(nsim_devlink_params));
+ devl_resources_unregister(devlink);
+ kfree(nsim_dev->vfconfigs);
++ kfree(nsim_dev->fa_cookie);
+ devl_unlock(devlink);
+ devlink_free(devlink);
+ dev_set_drvdata(&nsim_bus_dev->dev, NULL);
+diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
+index 417527f8bbf55..7446d5c6c7146 100644
+--- a/drivers/net/phy/dp83867.c
++++ b/drivers/net/phy/dp83867.c
+@@ -682,6 +682,13 @@ static int dp83867_of_init(struct phy_device *phydev)
+ */
+ dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN / 2;
+
++ /* For non-OF device, the RX and TX FIFO depths are taken from
++ * default value. So, we init RX & TX FIFO depths here
++ * so that it is configured correctly later in dp83867_config_init();
++ */
++ dp83867->tx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
++ dp83867->rx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
++
+ return 0;
+ }
+ #endif /* CONFIG_OF_MDIO */
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
+index a714150f5e8cd..7c292a3d83d49 100644
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2015,14 +2015,16 @@ static int m88e1510_loopback(struct phy_device *phydev, bool enable)
+ if (err < 0)
+ return err;
+
+- /* FIXME: Based on trial and error test, it seem 1G need to have
+- * delay between soft reset and loopback enablement.
+- */
+- if (phydev->speed == SPEED_1000)
+- msleep(1000);
++ err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
++ BMCR_LOOPBACK);
+
+- return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
+- BMCR_LOOPBACK);
++ if (!err) {
++ /* It takes some time for PHY device to switch
++ * into/out-of loopback mode.
++ */
++ msleep(1000);
++ }
++ return err;
+ } else {
+ err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0);
+ if (err < 0)
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index ab3f045629802..8391f83034992 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -1379,12 +1379,21 @@ static int __init tbnet_init(void)
+ TBNET_MATCH_FRAGS_ID | TBNET_64K_FRAMES);
+
+ ret = tb_register_property_dir("network", tbnet_dir);
+- if (ret) {
+- tb_property_free_dir(tbnet_dir);
+- return ret;
+- }
++ if (ret)
++ goto err_free_dir;
++
++ ret = tb_register_service_driver(&tbnet_driver);
++ if (ret)
++ goto err_unregister;
+
+- return tb_register_service_driver(&tbnet_driver);
++ return 0;
++
++err_unregister:
++ tb_unregister_property_dir("network", tbnet_dir);
++err_free_dir:
++ tb_property_free_dir(tbnet_dir);
++
++ return ret;
+ }
+ module_init(tbnet_init);
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index bfb58c91db047..32d2c60d334dc 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -66,6 +66,7 @@ struct smsc95xx_priv {
+ spinlock_t mac_cr_lock;
+ u8 features;
+ u8 suspend_flags;
++ bool is_internal_phy;
+ struct irq_chip irqchip;
+ struct irq_domain *irqdomain;
+ struct fwnode_handle *irqfwnode;
+@@ -252,6 +253,43 @@ done:
+ mutex_unlock(&dev->phy_mutex);
+ }
+
++static int smsc95xx_mdiobus_reset(struct mii_bus *bus)
++{
++ struct smsc95xx_priv *pdata;
++ struct usbnet *dev;
++ u32 val;
++ int ret;
++
++ dev = bus->priv;
++ pdata = dev->driver_priv;
++
++ if (pdata->is_internal_phy)
++ return 0;
++
++ mutex_lock(&dev->phy_mutex);
++
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ if (ret < 0)
++ goto reset_out;
++
++ val |= PM_CTL_PHY_RST_;
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ if (ret < 0)
++ goto reset_out;
++
++ /* Driver has no knowledge at this point about the external PHY.
++ * The 802.3 specifies that the reset process shall
++ * be completed within 0.5 s.
++ */
++ fsleep(500000);
++
++reset_out:
++ mutex_unlock(&dev->phy_mutex);
++
++ return 0;
++}
++
+ static int smsc95xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)
+ {
+ struct usbnet *dev = bus->priv;
+@@ -1052,7 +1090,6 @@ static void smsc95xx_handle_link_change(struct net_device *net)
+ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+ struct smsc95xx_priv *pdata;
+- bool is_internal_phy;
+ char usb_path[64];
+ int ret, phy_irq;
+ u32 val;
+@@ -1133,13 +1170,14 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ if (ret < 0)
+ goto free_mdio;
+
+- is_internal_phy = !(val & HW_CFG_PSEL_);
+- if (is_internal_phy)
++ pdata->is_internal_phy = !(val & HW_CFG_PSEL_);
++ if (pdata->is_internal_phy)
+ pdata->mdiobus->phy_mask = ~(1u << SMSC95XX_INTERNAL_PHY_ID);
+
+ pdata->mdiobus->priv = dev;
+ pdata->mdiobus->read = smsc95xx_mdiobus_read;
+ pdata->mdiobus->write = smsc95xx_mdiobus_write;
++ pdata->mdiobus->reset = smsc95xx_mdiobus_reset;
+ pdata->mdiobus->name = "smsc95xx-mdiobus";
+ pdata->mdiobus->parent = &dev->udev->dev;
+
+@@ -1160,7 +1198,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ }
+
+ pdata->phydev->irq = phy_irq;
+- pdata->phydev->is_internal = is_internal_phy;
++ pdata->phydev->is_internal = pdata->is_internal_phy;
+
+ /* detect device revision as different features may be available */
+ ret = smsc95xx_read_reg(dev, ID_REV, &val);
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index d3281f87cd6e4..a48a79ed5c4c5 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -764,11 +764,17 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+ case NVME_IOCTL_IO_CMD:
+ return nvme_dev_user_cmd(ctrl, argp);
+ case NVME_IOCTL_RESET:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
+ dev_warn(ctrl->device, "resetting controller\n");
+ return nvme_reset_ctrl_sync(ctrl);
+ case NVME_IOCTL_SUBSYS_RESET:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
+ return nvme_reset_subsystem(ctrl);
+ case NVME_IOCTL_RESCAN:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
+ nvme_queue_scan(ctrl);
+ return 0;
+ default:
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index a0bf9560cf678..70555022cb445 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -602,11 +602,23 @@ static inline void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inj)
+ static inline void nvme_should_fail(struct request *req) {}
+ #endif
+
++bool nvme_wait_reset(struct nvme_ctrl *ctrl);
++int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
++
+ static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
+ {
++ int ret;
++
+ if (!ctrl->subsystem)
+ return -ENOTTY;
+- return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
++ if (!nvme_wait_reset(ctrl))
++ return -EBUSY;
++
++ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
++ if (ret)
++ return ret;
++
++ return nvme_try_sched_reset(ctrl);
+ }
+
+ /*
+@@ -712,7 +724,6 @@ void nvme_cancel_tagset(struct nvme_ctrl *ctrl);
+ void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl);
+ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
+ enum nvme_ctrl_state new_state);
+-bool nvme_wait_reset(struct nvme_ctrl *ctrl);
+ int nvme_disable_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_enable_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
+@@ -802,7 +813,6 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
+ void nvme_stop_keep_alive(struct nvme_ctrl *ctrl);
+ int nvme_reset_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl);
+-int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
+ int nvme_delete_ctrl(struct nvme_ctrl *ctrl);
+ void nvme_queue_scan(struct nvme_ctrl *ctrl);
+ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi,
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 554468ea5a2a9..1a6423e94eb30 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3488,6 +3488,8 @@ static const struct pci_device_id nvme_id_table[] = {
+ NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+ { PCI_DEVICE(0x1344, 0x5407), /* Micron Technology Inc NVMe SSD */
+ .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN },
++ { PCI_DEVICE(0x1344, 0x6001), /* Micron Nitro NVMe */
++ .driver_data = NVME_QUIRK_BOGUS_NID, },
+ { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */
+ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ { PCI_DEVICE(0x1c5c, 0x174a), /* SK Hynix P31 SSD */
+@@ -3518,6 +3520,8 @@ static const struct pci_device_id nvme_id_table[] = {
+ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ { PCI_DEVICE(0x2646, 0x501E), /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
+ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++ { PCI_DEVICE(0x1f40, 0x5236), /* Netac Technologies Co. NV7000 NVMe SSD */
++ .driver_data = NVME_QUIRK_BOGUS_NID, },
+ { PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */
+ .driver_data = NVME_QUIRK_BOGUS_NID, },
+ { PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */
+diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c
+index c4113b43dbfee..4dcddcf95279b 100644
+--- a/drivers/nvme/target/auth.c
++++ b/drivers/nvme/target/auth.c
+@@ -45,9 +45,11 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
+ if (!dhchap_secret)
+ return -ENOMEM;
+ if (set_ctrl) {
++ kfree(host->dhchap_ctrl_secret);
+ host->dhchap_ctrl_secret = strim(dhchap_secret);
+ host->dhchap_ctrl_key_hash = key_hash;
+ } else {
++ kfree(host->dhchap_secret);
+ host->dhchap_secret = strim(dhchap_secret);
+ host->dhchap_key_hash = key_hash;
+ }
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 2bcd60758919b..7f52d9dac4432 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1811,6 +1811,7 @@ static void nvmet_host_release(struct config_item *item)
+
+ #ifdef CONFIG_NVME_TARGET_AUTH
+ kfree(host->dhchap_secret);
++ kfree(host->dhchap_ctrl_secret);
+ #endif
+ kfree(host);
+ }
+diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
+index eda4ded4d5e52..925be41eeebec 100644
+--- a/drivers/parport/parport_pc.c
++++ b/drivers/parport/parport_pc.c
+@@ -468,7 +468,7 @@ static size_t parport_pc_fifo_write_block_pio(struct parport *port,
+ const unsigned char *bufp = buf;
+ size_t left = length;
+ unsigned long expire = jiffies + port->physport->cad->timeout;
+- const int fifo = FIFO(port);
++ const unsigned long fifo = FIFO(port);
+ int poll_for = 8; /* 80 usecs */
+ const struct parport_pc_private *priv = port->physport->private_data;
+ const int fifo_depth = priv->fifo_depth;
+diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
+index ef898ee8ca6bd..6e0a40962f384 100644
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -220,6 +220,8 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
+ for (state = 0; ; state++) {
+ /* Retrieve the pinctrl-* property */
+ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
++ if (!propname)
++ return -ENOMEM;
+ prop = of_find_property(np, propname, &size);
+ kfree(propname);
+ if (!prop) {
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index e1ae3beb9f72b..b7921b59eb7b1 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -709,6 +709,9 @@ static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
+ {
+ int err, rsel_val;
+
++ if (!pullup && arg == MTK_DISABLE)
++ return 0;
++
+ if (hw->rsel_si_unit) {
+ /* find pin rsel_index from pin_rsel array*/
+ err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index c84bd0e1ce5a6..f4d2b64c06709 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -632,14 +632,54 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
+ }
+
+ static struct rockchip_mux_route_data px30_mux_route_data[] = {
++ RK_MUXROUTE_SAME(2, RK_PB4, 1, 0x184, BIT(16 + 7)), /* cif-d0m0 */
++ RK_MUXROUTE_SAME(3, RK_PA1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d0m1 */
++ RK_MUXROUTE_SAME(2, RK_PB6, 1, 0x184, BIT(16 + 7)), /* cif-d1m0 */
++ RK_MUXROUTE_SAME(3, RK_PA2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d1m1 */
+ RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
+ RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
++ RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x184, BIT(16 + 7)), /* cif-d3m0 */
++ RK_MUXROUTE_SAME(3, RK_PA5, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d3m1 */
++ RK_MUXROUTE_SAME(2, RK_PA2, 1, 0x184, BIT(16 + 7)), /* cif-d4m0 */
++ RK_MUXROUTE_SAME(3, RK_PA7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d4m1 */
++ RK_MUXROUTE_SAME(2, RK_PA3, 1, 0x184, BIT(16 + 7)), /* cif-d5m0 */
++ RK_MUXROUTE_SAME(3, RK_PB0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d5m1 */
++ RK_MUXROUTE_SAME(2, RK_PA4, 1, 0x184, BIT(16 + 7)), /* cif-d6m0 */
++ RK_MUXROUTE_SAME(3, RK_PB1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d6m1 */
++ RK_MUXROUTE_SAME(2, RK_PA5, 1, 0x184, BIT(16 + 7)), /* cif-d7m0 */
++ RK_MUXROUTE_SAME(3, RK_PB4, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d7m1 */
++ RK_MUXROUTE_SAME(2, RK_PA6, 1, 0x184, BIT(16 + 7)), /* cif-d8m0 */
++ RK_MUXROUTE_SAME(3, RK_PB6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d8m1 */
++ RK_MUXROUTE_SAME(2, RK_PA7, 1, 0x184, BIT(16 + 7)), /* cif-d9m0 */
++ RK_MUXROUTE_SAME(3, RK_PB7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d9m1 */
++ RK_MUXROUTE_SAME(2, RK_PB7, 1, 0x184, BIT(16 + 7)), /* cif-d10m0 */
++ RK_MUXROUTE_SAME(3, RK_PC6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d10m1 */
++ RK_MUXROUTE_SAME(2, RK_PC0, 1, 0x184, BIT(16 + 7)), /* cif-d11m0 */
++ RK_MUXROUTE_SAME(3, RK_PC7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d11m1 */
++ RK_MUXROUTE_SAME(2, RK_PB0, 1, 0x184, BIT(16 + 7)), /* cif-vsyncm0 */
++ RK_MUXROUTE_SAME(3, RK_PD1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-vsyncm1 */
++ RK_MUXROUTE_SAME(2, RK_PB1, 1, 0x184, BIT(16 + 7)), /* cif-hrefm0 */
++ RK_MUXROUTE_SAME(3, RK_PD2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-hrefm1 */
++ RK_MUXROUTE_SAME(2, RK_PB2, 1, 0x184, BIT(16 + 7)), /* cif-clkinm0 */
++ RK_MUXROUTE_SAME(3, RK_PD3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkinm1 */
++ RK_MUXROUTE_SAME(2, RK_PB3, 1, 0x184, BIT(16 + 7)), /* cif-clkoutm0 */
++ RK_MUXROUTE_SAME(3, RK_PD0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkoutm1 */
+ RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
+ RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
++ RK_MUXROUTE_SAME(3, RK_PD3, 2, 0x184, BIT(16 + 8)), /* pdm-sdi0m0 */
++ RK_MUXROUTE_SAME(2, RK_PC5, 2, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-sdi0m1 */
+ RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
+ RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
++ RK_MUXROUTE_SAME(1, RK_PD2, 2, 0x184, BIT(16 + 10)), /* uart2-txm0 */
++ RK_MUXROUTE_SAME(2, RK_PB4, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-txm1 */
+ RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
+ RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
++ RK_MUXROUTE_SAME(0, RK_PC0, 2, 0x184, BIT(16 + 9)), /* uart3-txm0 */
++ RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-txm1 */
++ RK_MUXROUTE_SAME(0, RK_PC2, 2, 0x184, BIT(16 + 9)), /* uart3-ctsm0 */
++ RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-ctsm1 */
++ RK_MUXROUTE_SAME(0, RK_PC3, 2, 0x184, BIT(16 + 9)), /* uart3-rtsm0 */
++ RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rtsm1 */
+ };
+
+ static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
+diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+index 6748fe4ac5d5f..def8d7ac541f7 100644
+--- a/drivers/platform/surface/aggregator/ssh_packet_layer.c
++++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+@@ -1596,16 +1596,32 @@ static void ssh_ptl_timeout_reap(struct work_struct *work)
+ ssh_ptl_tx_wakeup_packet(ptl);
+ }
+
+-static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, u8 seq)
++static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, const struct ssh_frame *frame)
+ {
+ int i;
+
++ /*
++ * Ignore unsequenced packets. On some devices (notably Surface Pro 9),
++ * unsequenced events will always be sent with SEQ=0x00. Attempting to
++ * detect retransmission would thus just block all events.
++ *
++ * While sequence numbers would also allow detection of retransmitted
++ * packets in unsequenced communication, they have only ever been used
++ * to cover edge-cases in sequenced transmission. In particular, the
++ * only instance of packets being retransmitted (that we are aware of)
++ * is due to an ACK timeout. As this does not happen in unsequenced
++ * communication, skip the retransmission check for those packets
++ * entirely.
++ */
++ if (frame->type == SSH_FRAME_TYPE_DATA_NSQ)
++ return false;
++
+ /*
+ * Check if SEQ has been seen recently (i.e. packet was
+ * re-transmitted and we should ignore it).
+ */
+ for (i = 0; i < ARRAY_SIZE(ptl->rx.blocked.seqs); i++) {
+- if (likely(ptl->rx.blocked.seqs[i] != seq))
++ if (likely(ptl->rx.blocked.seqs[i] != frame->seq))
+ continue;
+
+ ptl_dbg(ptl, "ptl: ignoring repeated data packet\n");
+@@ -1613,7 +1629,7 @@ static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, u8 seq)
+ }
+
+ /* Update list of blocked sequence IDs. */
+- ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = seq;
++ ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = frame->seq;
+ ptl->rx.blocked.offset = (ptl->rx.blocked.offset + 1)
+ % ARRAY_SIZE(ptl->rx.blocked.seqs);
+
+@@ -1624,7 +1640,7 @@ static void ssh_ptl_rx_dataframe(struct ssh_ptl *ptl,
+ const struct ssh_frame *frame,
+ const struct ssam_span *payload)
+ {
+- if (ssh_ptl_rx_retransmit_check(ptl, frame->seq))
++ if (ssh_ptl_rx_retransmit_check(ptl, frame))
+ return;
+
+ ptl->ops.data_received(ptl, payload);
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 6ccb9b38483ca..a838197f88962 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -274,7 +274,6 @@ static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
+ .release = amd_pmc_stb_debugfs_release_v2,
+ };
+
+-#if defined(CONFIG_SUSPEND) || defined(CONFIG_DEBUG_FS)
+ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
+ {
+ if (dev->cpu_id == AMD_CPU_ID_PCO) {
+@@ -349,7 +348,6 @@ static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table
+ memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
+ return 0;
+ }
+-#endif /* CONFIG_SUSPEND || CONFIG_DEBUG_FS */
+
+ #ifdef CONFIG_SUSPEND
+ static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
+@@ -920,6 +918,7 @@ static const struct acpi_device_id amd_pmc_acpi_ids[] = {
+ {"AMDI0006", 0},
+ {"AMDI0007", 0},
+ {"AMDI0008", 0},
++ {"AMDI0009", 0},
+ {"AMD0004", 0},
+ {"AMD0005", 0},
+ { }
+diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
+index a1fe1e0dcf4a5..17ec5825d13d7 100644
+--- a/drivers/platform/x86/intel/pmc/core.c
++++ b/drivers/platform/x86/intel/pmc/core.c
+@@ -1914,6 +1914,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
+ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &tgl_reg_map),
+ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map),
+ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map),
++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_reg_map),
++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_reg_map),
+ {}
+ };
+
+diff --git a/drivers/platform/x86/intel/pmc/pltdrv.c b/drivers/platform/x86/intel/pmc/pltdrv.c
+index 15ca8afdd973d..ddfba38c21044 100644
+--- a/drivers/platform/x86/intel/pmc/pltdrv.c
++++ b/drivers/platform/x86/intel/pmc/pltdrv.c
+@@ -18,6 +18,8 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/intel-family.h>
+
++#include <xen/xen.h>
++
+ static void intel_pmc_core_release(struct device *dev)
+ {
+ kfree(dev);
+@@ -53,6 +55,13 @@ static int __init pmc_core_platform_init(void)
+ if (acpi_dev_present("INT33A1", NULL, -1))
+ return -ENODEV;
+
++ /*
++ * Skip forcefully attaching the device for VMs. Make an exception for
++ * Xen dom0, which does have full hardware access.
++ */
++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR) && !xen_initial_domain())
++ return -ENODEV;
++
+ if (!x86_match_cpu(intel_pmc_core_platform_ids))
+ return -ENODEV;
+
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 2dbb9fc011a7a..353507d18e11c 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -263,6 +263,8 @@ enum tpacpi_hkey_event_t {
+ #define TPACPI_DBG_BRGHT 0x0020
+ #define TPACPI_DBG_MIXER 0x0040
+
++#define FAN_NOT_PRESENT 65535
++
+ #define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
+
+
+@@ -8876,7 +8878,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
+ /* Try and probe the 2nd fan */
+ tp_features.second_fan = 1; /* needed for get_speed to work */
+ res = fan2_get_speed(&speed);
+- if (res >= 0) {
++ if (res >= 0 && speed != FAN_NOT_PRESENT) {
+ /* It responded - so let's assume it's there */
+ tp_features.second_fan = 1;
+ tp_features.second_fan_ctl = 1;
+diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
+index 5187705bd0f39..d961f80c0e362 100644
+--- a/drivers/s390/block/dcssblk.c
++++ b/drivers/s390/block/dcssblk.c
+@@ -636,6 +636,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
+ dev_info->gd->minors = DCSSBLK_MINORS_PER_DISK;
+ dev_info->gd->fops = &dcssblk_devops;
+ dev_info->gd->private_data = dev_info;
++ dev_info->gd->flags |= GENHD_FL_NO_PART;
+ blk_queue_logical_block_size(dev_info->gd->queue, 4096);
+ blk_queue_flag_set(QUEUE_FLAG_DAX, dev_info->gd->queue);
+
+diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
+index 19223b0755686..ab3ea529cca70 100644
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -884,7 +884,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
+ const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req);
+ struct zfcp_adapter *adapter = req->adapter;
+ struct zfcp_qdio *qdio = adapter->qdio;
+- int req_id = req->req_id;
++ unsigned long req_id = req->req_id;
+
+ zfcp_reqlist_add(adapter->req_list, req);
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index b8a76b89f85a3..95f940f5c996d 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -7316,8 +7316,12 @@ static int sdebug_add_host_helper(int per_host_idx)
+ dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts);
+
+ error = device_register(&sdbg_host->dev);
+- if (error)
++ if (error) {
++ spin_lock(&sdebug_host_list_lock);
++ list_del(&sdbg_host->host_list);
++ spin_unlock(&sdebug_host_list_lock);
+ goto clean;
++ }
+
+ ++sdebug_num_hosts;
+ return 0;
+diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
+index 2f88c61216eea..74b99f2b0b74a 100644
+--- a/drivers/scsi/scsi_transport_sas.c
++++ b/drivers/scsi/scsi_transport_sas.c
+@@ -722,12 +722,17 @@ int sas_phy_add(struct sas_phy *phy)
+ int error;
+
+ error = device_add(&phy->dev);
+- if (!error) {
+- transport_add_device(&phy->dev);
+- transport_configure_device(&phy->dev);
++ if (error)
++ return error;
++
++ error = transport_add_device(&phy->dev);
++ if (error) {
++ device_del(&phy->dev);
++ return error;
+ }
++ transport_configure_device(&phy->dev);
+
+- return error;
++ return 0;
+ }
+ EXPORT_SYMBOL(sas_phy_add);
+
+diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c
+index 7c4f32d769666..561408583b2bf 100644
+--- a/drivers/siox/siox-core.c
++++ b/drivers/siox/siox-core.c
+@@ -839,6 +839,8 @@ static struct siox_device *siox_device_add(struct siox_master *smaster,
+
+ err_device_register:
+ /* don't care to make the buffer smaller again */
++ put_device(&sdevice->dev);
++ sdevice = NULL;
+
+ err_buf_alloc:
+ siox_master_unlock(smaster);
+diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig
+index 1235b7dc8496c..e25d280a68eee 100644
+--- a/drivers/slimbus/Kconfig
++++ b/drivers/slimbus/Kconfig
+@@ -23,7 +23,7 @@ config SLIM_QCOM_CTRL
+ config SLIM_QCOM_NGD_CTRL
+ tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component"
+ depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON
+- depends on ARCH_QCOM || COMPILE_TEST
++ depends on ARCH_QCOM || (COMPILE_TEST && !QCOM_RPROC_COMMON)
+ select QCOM_QMI_HELPERS
+ select QCOM_PDR_HELPERS
+ help
+diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c
+index 75f87b3d8b953..73a2aa3629572 100644
+--- a/drivers/slimbus/stream.c
++++ b/drivers/slimbus/stream.c
+@@ -67,10 +67,10 @@ static const int slim_presence_rate_table[] = {
+ 384000,
+ 768000,
+ 0, /* Reserved */
+- 110250,
+- 220500,
+- 441000,
+- 882000,
++ 11025,
++ 22050,
++ 44100,
++ 88200,
+ 176400,
+ 352800,
+ 705600,
+diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
+index cc57a384d74d2..28144c699b0c3 100644
+--- a/drivers/soc/imx/soc-imx8m.c
++++ b/drivers/soc/imx/soc-imx8m.c
+@@ -11,6 +11,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/arm-smccc.h>
+ #include <linux/of.h>
++#include <linux/clk.h>
+
+ #define REV_B1 0x21
+
+@@ -56,6 +57,7 @@ static u32 __init imx8mq_soc_revision(void)
+ void __iomem *ocotp_base;
+ u32 magic;
+ u32 rev;
++ struct clk *clk;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np)
+@@ -63,6 +65,13 @@ static u32 __init imx8mq_soc_revision(void)
+
+ ocotp_base = of_iomap(np, 0);
+ WARN_ON(!ocotp_base);
++ clk = of_clk_get_by_name(np, NULL);
++ if (!clk) {
++ WARN_ON(!clk);
++ return 0;
++ }
++
++ clk_prepare_enable(clk);
+
+ /*
+ * SOC revision on older imx8mq is not available in fuses so query
+@@ -79,6 +88,8 @@ static u32 __init imx8mq_soc_revision(void)
+ soc_uid <<= 32;
+ soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
+
++ clk_disable_unprepare(clk);
++ clk_put(clk);
+ iounmap(ocotp_base);
+ of_node_put(np);
+
+diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
+index 3f6db482b6c71..a1dbd71bf83ef 100644
+--- a/drivers/spi/spi-intel.c
++++ b/drivers/spi/spi-intel.c
+@@ -114,7 +114,7 @@
+ #define ERASE_OPCODE_SHIFT 8
+ #define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT)
+ #define ERASE_64K_OPCODE_SHIFT 16
+-#define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT)
++#define ERASE_64K_OPCODE_MASK (0xff << ERASE_64K_OPCODE_SHIFT)
+
+ #define INTEL_SPI_TIMEOUT 5000 /* ms */
+ #define INTEL_SPI_FIFO_SZ 64
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 6fe617b445a59..3c2fa2e2f94a3 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -886,6 +886,7 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
+ static DEFINE_RATELIMIT_STATE(rs,
+ DEFAULT_RATELIMIT_INTERVAL * 10,
+ 1);
++ ratelimit_set_flags(&rs, RATELIMIT_MSG_ON_RELEASE);
+ if (__ratelimit(&rs))
+ dev_dbg_ratelimited(spi->dev, "Communication suspended\n");
+ if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index c89592b21ffc5..904972606bd45 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1157,6 +1157,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+ msg->actual_length += xfer->len;
+ transfer_phase++;
+ }
++ if (!xfer->cs_change) {
++ tegra_qspi_transfer_end(spi);
++ spi_transfer_delay_exec(xfer);
++ }
++ ret = 0;
+
+ exit:
+ msg->status = ret;
+diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
+index 4407b56aa6d1a..139031ccb700a 100644
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -397,6 +397,7 @@ static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host
+ ret = device_register(&tl_hba->dev);
+ if (ret) {
+ pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
++ put_device(&tl_hba->dev);
+ return -ENODEV;
+ }
+
+@@ -1073,7 +1074,7 @@ check_len:
+ */
+ ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
+ if (ret)
+- goto out;
++ return ERR_PTR(ret);
+
+ sh = tl_hba->sh;
+ tcm_loop_hba_no_cnt++;
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 01c112e2e2142..2a0de70e0be41 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1670,7 +1670,7 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
+ unsigned int command, u8 *data, int clen)
+ {
+ struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control),
+- GFP_KERNEL);
++ GFP_ATOMIC);
+ unsigned long flags;
+ if (ctrl == NULL)
+ return NULL;
+diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
+index 4ba43bef99336..93643fe6fd9c6 100644
+--- a/drivers/tty/serial/8250/8250_lpss.c
++++ b/drivers/tty/serial/8250/8250_lpss.c
+@@ -174,6 +174,8 @@ static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
+ */
+ up->dma = dma;
+
++ lpss->dma_maxburst = 16;
++
+ port->set_termios = dw8250_do_set_termios;
+
+ return 0;
+@@ -277,8 +279,13 @@ static int lpss8250_dma_setup(struct lpss8250 *lpss, struct uart_8250_port *port
+ struct dw_dma_slave *rx_param, *tx_param;
+ struct device *dev = port->port.dev;
+
+- if (!lpss->dma_param.dma_dev)
++ if (!lpss->dma_param.dma_dev) {
++ dma = port->dma;
++ if (dma)
++ goto out_configuration_only;
++
+ return 0;
++ }
+
+ rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
+ if (!rx_param)
+@@ -289,16 +296,18 @@ static int lpss8250_dma_setup(struct lpss8250 *lpss, struct uart_8250_port *port
+ return -ENOMEM;
+
+ *rx_param = lpss->dma_param;
+- dma->rxconf.src_maxburst = lpss->dma_maxburst;
+-
+ *tx_param = lpss->dma_param;
+- dma->txconf.dst_maxburst = lpss->dma_maxburst;
+
+ dma->fn = lpss8250_dma_filter;
+ dma->rx_param = rx_param;
+ dma->tx_param = tx_param;
+
+ port->dma = dma;
++
++out_configuration_only:
++ dma->rxconf.src_maxburst = lpss->dma_maxburst;
++ dma->txconf.dst_maxburst = lpss->dma_maxburst;
++
+ return 0;
+ }
+
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 38ee3e42251af..b96fbf8d31df7 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -157,7 +157,11 @@ static u32 uart_read(struct uart_8250_port *up, u32 reg)
+ return readl(up->port.membase + (reg << up->port.regshift));
+ }
+
+-static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++/*
++ * Called on runtime PM resume path from omap8250_restore_regs(), and
++ * omap8250_set_mctrl().
++ */
++static void __omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+ struct uart_8250_port *up = up_to_u8250p(port);
+ struct omap8250_priv *priv = up->port.private_data;
+@@ -181,6 +185,20 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ }
+ }
+
++static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ int err;
++
++ err = pm_runtime_resume_and_get(port->dev);
++ if (err)
++ return;
++
++ __omap8250_set_mctrl(port, mctrl);
++
++ pm_runtime_mark_last_busy(port->dev);
++ pm_runtime_put_autosuspend(port->dev);
++}
++
+ /*
+ * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
+ * The access to uart register after MDR1 Access
+@@ -193,27 +211,10 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ static void omap_8250_mdr1_errataset(struct uart_8250_port *up,
+ struct omap8250_priv *priv)
+ {
+- u8 timeout = 255;
+-
+ serial_out(up, UART_OMAP_MDR1, priv->mdr1);
+ udelay(2);
+ serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
+ UART_FCR_CLEAR_RCVR);
+- /*
+- * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+- * TX_FIFO_E bit is 1.
+- */
+- while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
+- (UART_LSR_THRE | UART_LSR_DR))) {
+- timeout--;
+- if (!timeout) {
+- /* Should *never* happen. we warn and carry on */
+- dev_crit(up->port.dev, "Errata i202: timedout %x\n",
+- serial_in(up, UART_LSR));
+- break;
+- }
+- udelay(1);
+- }
+ }
+
+ static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud,
+@@ -341,7 +342,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+
+ omap8250_update_mdr1(up, priv);
+
+- up->port.ops->set_mctrl(&up->port, up->port.mctrl);
++ __omap8250_set_mctrl(&up->port, up->port.mctrl);
+
+ if (up->port.rs485.flags & SER_RS485_ENABLED)
+ serial8250_em485_stop_tx(up);
+@@ -1460,9 +1461,15 @@ err:
+ static int omap8250_remove(struct platform_device *pdev)
+ {
+ struct omap8250_priv *priv = platform_get_drvdata(pdev);
++ int err;
++
++ err = pm_runtime_resume_and_get(&pdev->dev);
++ if (err)
++ return err;
+
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_sync(&pdev->dev);
++ flush_work(&priv->qos_work);
+ pm_runtime_disable(&pdev->dev);
+ serial8250_unregister_port(priv->line);
+ cpu_latency_qos_remove_request(&priv->pm_qos_request);
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 2030a92ac66e7..ca7415360f106 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -1892,10 +1892,13 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
+ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
+ {
+ switch (iir & 0x3f) {
+- case UART_IIR_RX_TIMEOUT:
+- serial8250_rx_dma_flush(up);
++ case UART_IIR_RDI:
++ if (!up->dma->rx_running)
++ break;
+ fallthrough;
+ case UART_IIR_RLSI:
++ case UART_IIR_RX_TIMEOUT:
++ serial8250_rx_dma_flush(up);
+ return true;
+ }
+ return up->dma->rx_dma(up);
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 34990901c805e..c8297102e087a 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -12,6 +12,7 @@
+ #include <linux/dmaengine.h>
+ #include <linux/dmapool.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+@@ -404,33 +405,6 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
+ #define lpuart_enable_clks(x) __lpuart_enable_clks(x, true)
+ #define lpuart_disable_clks(x) __lpuart_enable_clks(x, false)
+
+-static int lpuart_global_reset(struct lpuart_port *sport)
+-{
+- struct uart_port *port = &sport->port;
+- void __iomem *global_addr;
+- int ret;
+-
+- if (uart_console(port))
+- return 0;
+-
+- ret = clk_prepare_enable(sport->ipg_clk);
+- if (ret) {
+- dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
+- return ret;
+- }
+-
+- if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) {
+- global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF;
+- writel(UART_GLOBAL_RST, global_addr);
+- usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
+- writel(0, global_addr);
+- usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
+- }
+-
+- clk_disable_unprepare(sport->ipg_clk);
+- return 0;
+-}
+-
+ static void lpuart_stop_tx(struct uart_port *port)
+ {
+ unsigned char temp;
+@@ -2641,6 +2615,54 @@ static const struct serial_rs485 lpuart_rs485_supported = {
+ /* delay_rts_* and RX_DURING_TX are not supported */
+ };
+
++static int lpuart_global_reset(struct lpuart_port *sport)
++{
++ struct uart_port *port = &sport->port;
++ void __iomem *global_addr;
++ unsigned long ctrl, bd;
++ unsigned int val = 0;
++ int ret;
++
++ ret = clk_prepare_enable(sport->ipg_clk);
++ if (ret) {
++ dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
++ return ret;
++ }
++
++ if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) {
++ /*
++ * If the transmitter is used by earlycon, wait for transmit engine to
++ * complete and then reset.
++ */
++ ctrl = lpuart32_read(port, UARTCTRL);
++ if (ctrl & UARTCTRL_TE) {
++ bd = lpuart32_read(&sport->port, UARTBAUD);
++ if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false,
++ port)) {
++ dev_warn(sport->port.dev,
++ "timeout waiting for transmit engine to complete\n");
++ clk_disable_unprepare(sport->ipg_clk);
++ return 0;
++ }
++ }
++
++ global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF;
++ writel(UART_GLOBAL_RST, global_addr);
++ usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
++ writel(0, global_addr);
++ usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
++
++ /* Recover the transmitter for earlycon. */
++ if (ctrl & UARTCTRL_TE) {
++ lpuart32_write(port, bd, UARTBAUD);
++ lpuart32_write(port, ctrl, UARTCTRL);
++ }
++ }
++
++ clk_disable_unprepare(sport->ipg_clk);
++ return 0;
++}
++
+ static int lpuart_probe(struct platform_device *pdev)
+ {
+ const struct lpuart_soc_data *sdata = of_device_get_match_data(&pdev->dev);
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 278b4033a3cce..57e3fda979eae 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2594,6 +2594,7 @@ static const struct dev_pm_ops imx_uart_pm_ops = {
+ .suspend_noirq = imx_uart_suspend_noirq,
+ .resume_noirq = imx_uart_resume_noirq,
+ .freeze_noirq = imx_uart_suspend_noirq,
++ .thaw_noirq = imx_uart_resume_noirq,
+ .restore_noirq = imx_uart_resume_noirq,
+ .suspend = imx_uart_suspend,
+ .resume = imx_uart_resume,
+diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
+index 9643b905e2d8b..6164fc4c96a49 100644
+--- a/drivers/usb/cdns3/host.c
++++ b/drivers/usb/cdns3/host.c
+@@ -24,11 +24,37 @@
+ #define CFG_RXDET_P3_EN BIT(15)
+ #define LPM_2_STB_SWITCH_EN BIT(25)
+
+-static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd);
++static void xhci_cdns3_plat_start(struct usb_hcd *hcd)
++{
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ u32 value;
++
++ /* set usbcmd.EU3S */
++ value = readl(&xhci->op_regs->command);
++ value |= CMD_PM_INDEX;
++ writel(value, &xhci->op_regs->command);
++
++ if (hcd->regs) {
++ value = readl(hcd->regs + XECP_AUX_CTRL_REG1);
++ value |= CFG_RXDET_P3_EN;
++ writel(value, hcd->regs + XECP_AUX_CTRL_REG1);
++
++ value = readl(hcd->regs + XECP_PORT_CAP_REG);
++ value |= LPM_2_STB_SWITCH_EN;
++ writel(value, hcd->regs + XECP_PORT_CAP_REG);
++ }
++}
++
++static int xhci_cdns3_resume_quirk(struct usb_hcd *hcd)
++{
++ xhci_cdns3_plat_start(hcd);
++ return 0;
++}
+
+ static const struct xhci_plat_priv xhci_plat_cdns3_xhci = {
+ .quirks = XHCI_SKIP_PHY_INIT | XHCI_AVOID_BEI,
+- .suspend_quirk = xhci_cdns3_suspend_quirk,
++ .plat_start = xhci_cdns3_plat_start,
++ .resume_quirk = xhci_cdns3_resume_quirk,
+ };
+
+ static int __cdns_host_init(struct cdns *cdns)
+@@ -90,32 +116,6 @@ err1:
+ return ret;
+ }
+
+-static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd)
+-{
+- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+- u32 value;
+-
+- if (pm_runtime_status_suspended(hcd->self.controller))
+- return 0;
+-
+- /* set usbcmd.EU3S */
+- value = readl(&xhci->op_regs->command);
+- value |= CMD_PM_INDEX;
+- writel(value, &xhci->op_regs->command);
+-
+- if (hcd->regs) {
+- value = readl(hcd->regs + XECP_AUX_CTRL_REG1);
+- value |= CFG_RXDET_P3_EN;
+- writel(value, hcd->regs + XECP_AUX_CTRL_REG1);
+-
+- value = readl(hcd->regs + XECP_PORT_CAP_REG);
+- value |= LPM_2_STB_SWITCH_EN;
+- writel(value, hcd->regs + XECP_PORT_CAP_REG);
+- }
+-
+- return 0;
+-}
+-
+ static void cdns_host_exit(struct cdns *cdns)
+ {
+ kfree(cdns->xhci_plat_data);
+diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
+index 61b157b9c6626..a78584624288a 100644
+--- a/drivers/usb/chipidea/otg_fsm.c
++++ b/drivers/usb/chipidea/otg_fsm.c
+@@ -256,8 +256,10 @@ static void ci_otg_del_timer(struct ci_hdrc *ci, enum otg_fsm_timer t)
+ ci->enabled_otg_timer_bits &= ~(1 << t);
+ if (ci->next_otg_timer == t) {
+ if (ci->enabled_otg_timer_bits == 0) {
++ spin_unlock_irqrestore(&ci->lock, flags);
+ /* No enabled timers after delete it */
+ hrtimer_cancel(&ci->otg_fsm_hrtimer);
++ spin_lock_irqsave(&ci->lock, flags);
+ ci->next_otg_timer = NUM_OTG_FSM_TIMERS;
+ } else {
+ /* Find the next timer */
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 0722d21313055..079e183cf3bff 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -362,6 +362,9 @@ static const struct usb_device_id usb_quirk_list[] = {
+ { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
+ { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
+
++ /* Realforce 87U Keyboard */
++ { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
++
+ /* M-Systems Flash Disk Pioneers */
+ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index d03e1a9c144c1..038140b1de37b 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1710,6 +1710,16 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+ if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
+ return extcon_get_extcon_dev(name);
+
++ /*
++ * Check explicitly if "usb-role-switch" is used since
++ * extcon_find_edev_by_node() can not be used to check the absence of
++ * an extcon device. In the absence of an device it will always return
++ * EPROBE_DEFER.
++ */
++ if (IS_ENABLED(CONFIG_USB_ROLE_SWITCH) &&
++ device_property_read_bool(dev, "usb-role-switch"))
++ return NULL;
++
+ /*
+ * Try to get an extcon device from the USB PHY controller's "port"
+ * node. Check if it has the "port" node first, to avoid printing the
+diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
+index a7154fe8206d1..f6f13e7f1ba14 100644
+--- a/drivers/usb/dwc3/host.c
++++ b/drivers/usb/dwc3/host.c
+@@ -11,13 +11,8 @@
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+
+-#include "../host/xhci-plat.h"
+ #include "core.h"
+
+-static const struct xhci_plat_priv dwc3_xhci_plat_priv = {
+- .quirks = XHCI_SKIP_PHY_INIT,
+-};
+-
+ static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc,
+ int irq, char *name)
+ {
+@@ -97,11 +92,6 @@ int dwc3_host_init(struct dwc3 *dwc)
+ goto err;
+ }
+
+- ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv,
+- sizeof(dwc3_xhci_plat_priv));
+- if (ret)
+- goto err;
+-
+ memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
+
+ if (dwc->usb3_lpm_capable)
+diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
+index 2df52f75f6b3c..7558cc4d90cc6 100644
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -285,7 +285,7 @@ static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+ {
+ struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+
+- if (IS_ERR_OR_NULL(usb_dev->gpio_desc))
++ if (!usb_dev->gpio_desc)
+ return;
+
+ gpiod_set_value(usb_dev->gpio_desc, val);
+@@ -406,9 +406,11 @@ static int bcma_hcd_probe(struct bcma_device *core)
+ return -ENOMEM;
+ usb_dev->core = core;
+
+- if (core->dev.of_node)
+- usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+- GPIOD_OUT_HIGH);
++ usb_dev->gpio_desc = devm_gpiod_get_optional(&core->dev, "vcc",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(usb_dev->gpio_desc))
++ return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc),
++ "error obtaining VCC GPIO");
+
+ switch (core->id.id) {
+ case BCMA_CORE_USB20_HOST:
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 697683e3fbffa..c3b7f1d98e781 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -162,6 +162,8 @@ static void option_instat_callback(struct urb *urb);
+ #define NOVATELWIRELESS_PRODUCT_G2 0xA010
+ #define NOVATELWIRELESS_PRODUCT_MC551 0xB001
+
++#define UBLOX_VENDOR_ID 0x1546
++
+ /* AMOI PRODUCTS */
+ #define AMOI_VENDOR_ID 0x1614
+ #define AMOI_PRODUCT_H01 0x0800
+@@ -240,7 +242,6 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_UC15 0x9090
+ /* These u-blox products use Qualcomm's vendor ID */
+ #define UBLOX_PRODUCT_R410M 0x90b2
+-#define UBLOX_PRODUCT_R6XX 0x90fa
+ /* These Yuga products use Qualcomm's vendor ID */
+ #define YUGA_PRODUCT_CLM920_NC5 0x9625
+
+@@ -581,6 +582,9 @@ static void option_instat_callback(struct urb *urb);
+ #define OPPO_VENDOR_ID 0x22d9
+ #define OPPO_PRODUCT_R11 0x276c
+
++/* Sierra Wireless products */
++#define SIERRA_VENDOR_ID 0x1199
++#define SIERRA_PRODUCT_EM9191 0x90d3
+
+ /* Device flags */
+
+@@ -1124,8 +1128,16 @@ static const struct usb_device_id option_ids[] = {
+ /* u-blox products using Qualcomm vendor ID */
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M),
+ .driver_info = RSVD(1) | RSVD(3) },
+- { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX),
++ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x908b), /* u-blox LARA-R6 00B */
++ .driver_info = RSVD(4) },
++ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa),
+ .driver_info = RSVD(3) },
++ /* u-blox products */
++ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) }, /* u-blox LARA-L6 */
++ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1342), /* u-blox LARA-L6 (RMNET) */
++ .driver_info = RSVD(4) },
++ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1343), /* u-blox LARA-L6 (ECM) */
++ .driver_info = RSVD(4) },
+ /* Quectel products using Quectel vendor ID */
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff),
+ .driver_info = NUMEP2 },
+@@ -2167,6 +2179,7 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */
++ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */
+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */
+@@ -2176,6 +2189,8 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
+ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
+ { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
++ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c
+index a8e273fe204ab..795829ffe7768 100644
+--- a/drivers/usb/typec/mux/intel_pmc_mux.c
++++ b/drivers/usb/typec/mux/intel_pmc_mux.c
+@@ -369,13 +369,24 @@ pmc_usb_mux_usb4(struct pmc_usb_port *port, struct typec_mux_state *state)
+ return pmc_usb_command(port, (void *)&req, sizeof(req));
+ }
+
+-static int pmc_usb_mux_safe_state(struct pmc_usb_port *port)
++static int pmc_usb_mux_safe_state(struct pmc_usb_port *port,
++ struct typec_mux_state *state)
+ {
+ u8 msg;
+
+ if (IOM_PORT_ACTIVITY_IS(port->iom_status, SAFE_MODE))
+ return 0;
+
++ if ((IOM_PORT_ACTIVITY_IS(port->iom_status, DP) ||
++ IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) &&
++ state->alt && state->alt->svid == USB_TYPEC_DP_SID)
++ return 0;
++
++ if ((IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
++ IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB)) &&
++ state->alt && state->alt->svid == USB_TYPEC_TBT_SID)
++ return 0;
++
+ msg = PMC_USB_SAFE_MODE;
+ msg |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
+
+@@ -443,7 +454,7 @@ pmc_usb_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+ return 0;
+
+ if (state->mode == TYPEC_STATE_SAFE)
+- return pmc_usb_mux_safe_state(port);
++ return pmc_usb_mux_safe_state(port, state);
+ if (state->mode == TYPEC_STATE_USB)
+ return pmc_usb_connect(port, port->role);
+
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index dfbba5ae9487b..92e35e62e78c2 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -474,7 +474,7 @@ static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status)
+ static irqreturn_t cd321x_interrupt(int irq, void *data)
+ {
+ struct tps6598x *tps = data;
+- u64 event;
++ u64 event = 0;
+ u32 status;
+ int ret;
+
+@@ -519,8 +519,8 @@ err_unlock:
+ static irqreturn_t tps6598x_interrupt(int irq, void *data)
+ {
+ struct tps6598x *tps = data;
+- u64 event1;
+- u64 event2;
++ u64 event1 = 0;
++ u64 event2 = 0;
+ u32 status;
+ int ret;
+
+diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
+index 7cb56c382c97a..48ceca04d9b8a 100644
+--- a/drivers/vfio/vfio_main.c
++++ b/drivers/vfio/vfio_main.c
+@@ -710,8 +710,9 @@ EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
+ /*
+ * VFIO base fd, /dev/vfio/vfio
+ */
+-static long vfio_ioctl_check_extension(struct vfio_container *container,
+- unsigned long arg)
++static long
++vfio_container_ioctl_check_extension(struct vfio_container *container,
++ unsigned long arg)
+ {
+ struct vfio_iommu_driver *driver;
+ long ret = 0;
+@@ -868,7 +869,7 @@ static long vfio_fops_unl_ioctl(struct file *filep,
+ ret = VFIO_API_VERSION;
+ break;
+ case VFIO_CHECK_EXTENSION:
+- ret = vfio_ioctl_check_extension(container, arg);
++ ret = vfio_container_ioctl_check_extension(container, arg);
+ break;
+ case VFIO_SET_IOMMU:
+ ret = vfio_ioctl_set_iommu(container, arg);
+@@ -1085,9 +1086,28 @@ static void vfio_device_unassign_container(struct vfio_device *device)
+ up_write(&device->group->group_rwsem);
+ }
+
++static void vfio_device_container_register(struct vfio_device *device)
++{
++ struct vfio_iommu_driver *iommu_driver =
++ device->group->container->iommu_driver;
++
++ if (iommu_driver && iommu_driver->ops->register_device)
++ iommu_driver->ops->register_device(
++ device->group->container->iommu_data, device);
++}
++
++static void vfio_device_container_unregister(struct vfio_device *device)
++{
++ struct vfio_iommu_driver *iommu_driver =
++ device->group->container->iommu_driver;
++
++ if (iommu_driver && iommu_driver->ops->unregister_device)
++ iommu_driver->ops->unregister_device(
++ device->group->container->iommu_data, device);
++}
++
+ static struct file *vfio_device_open(struct vfio_device *device)
+ {
+- struct vfio_iommu_driver *iommu_driver;
+ struct file *filep;
+ int ret;
+
+@@ -1118,12 +1138,7 @@ static struct file *vfio_device_open(struct vfio_device *device)
+ if (ret)
+ goto err_undo_count;
+ }
+-
+- iommu_driver = device->group->container->iommu_driver;
+- if (iommu_driver && iommu_driver->ops->register_device)
+- iommu_driver->ops->register_device(
+- device->group->container->iommu_data, device);
+-
++ vfio_device_container_register(device);
+ up_read(&device->group->group_rwsem);
+ }
+ mutex_unlock(&device->dev_set->lock);
+@@ -1161,10 +1176,7 @@ err_close_device:
+ if (device->open_count == 1 && device->ops->close_device) {
+ device->ops->close_device(device);
+
+- iommu_driver = device->group->container->iommu_driver;
+- if (iommu_driver && iommu_driver->ops->unregister_device)
+- iommu_driver->ops->unregister_device(
+- device->group->container->iommu_data, device);
++ vfio_device_container_unregister(device);
+ }
+ err_undo_count:
+ up_read(&device->group->group_rwsem);
+@@ -1360,7 +1372,6 @@ static const struct file_operations vfio_group_fops = {
+ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
+ {
+ struct vfio_device *device = filep->private_data;
+- struct vfio_iommu_driver *iommu_driver;
+
+ mutex_lock(&device->dev_set->lock);
+ vfio_assert_device_open(device);
+@@ -1368,10 +1379,7 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
+ if (device->open_count == 1 && device->ops->close_device)
+ device->ops->close_device(device);
+
+- iommu_driver = device->group->container->iommu_driver;
+- if (iommu_driver && iommu_driver->ops->unregister_device)
+- iommu_driver->ops->unregister_device(
+- device->group->container->iommu_data, device);
++ vfio_device_container_unregister(device);
+ up_read(&device->group->group_rwsem);
+ device->open_count--;
+ if (device->open_count == 0)
+@@ -1763,8 +1771,8 @@ bool vfio_file_enforced_coherent(struct file *file)
+
+ down_read(&group->group_rwsem);
+ if (group->container) {
+- ret = vfio_ioctl_check_extension(group->container,
+- VFIO_DMA_CC_IOMMU);
++ ret = vfio_container_ioctl_check_extension(group->container,
++ VFIO_DMA_CC_IOMMU);
+ } else {
+ /*
+ * Since the coherency state is determined only once a container
+diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
+index 47aa3a1ccaf57..fd3a644b08559 100644
+--- a/drivers/xen/pcpu.c
++++ b/drivers/xen/pcpu.c
+@@ -228,7 +228,7 @@ static int register_pcpu(struct pcpu *pcpu)
+
+ err = device_register(dev);
+ if (err) {
+- pcpu_release(dev);
++ put_device(dev);
+ return err;
+ }
+
+diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
+index 2feb5c20641ae..a21b9e085d1b5 100644
+--- a/fs/btrfs/raid56.c
++++ b/fs/btrfs/raid56.c
+@@ -2767,8 +2767,10 @@ raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc)
+
+ rbio->faila = find_logical_bio_stripe(rbio, bio);
+ if (rbio->faila == -1) {
+- BUG();
+- kfree(rbio);
++ btrfs_warn_rl(fs_info,
++ "can not determine the failed stripe number for full stripe %llu",
++ bioc->raid_map[0]);
++ __free_raid_bio(rbio);
+ return NULL;
+ }
+
+diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
+index 843dd3d3adbe7..63676ea19f29e 100644
+--- a/fs/btrfs/tests/qgroup-tests.c
++++ b/fs/btrfs/tests/qgroup-tests.c
+@@ -225,7 +225,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ */
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ if (ret) {
+- ulist_free(old_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -240,7 +239,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+ ulist_free(old_roots);
+- ulist_free(new_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -252,17 +250,18 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ return ret;
+ }
+
++ /* btrfs_qgroup_account_extent() always frees the ulists passed to it. */
++ old_roots = NULL;
++ new_roots = NULL;
++
+ if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
+ nodesize, nodesize)) {
+ test_err("qgroup counts didn't match expected values");
+ return -EINVAL;
+ }
+- old_roots = NULL;
+- new_roots = NULL;
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ if (ret) {
+- ulist_free(old_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -276,7 +275,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+ ulist_free(old_roots);
+- ulist_free(new_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -326,7 +324,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ if (ret) {
+- ulist_free(old_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -341,7 +338,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+ ulist_free(old_roots);
+- ulist_free(new_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -361,7 +357,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ if (ret) {
+- ulist_free(old_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -376,7 +371,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+ ulist_free(old_roots);
+- ulist_free(new_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -402,7 +396,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ if (ret) {
+- ulist_free(old_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+@@ -417,7 +410,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ if (ret) {
+ ulist_free(old_roots);
+- ulist_free(new_roots);
+ test_err("couldn't find old roots: %d", ret);
+ return ret;
+ }
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 55e762a58eb65..e1198f4b28c8f 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -2352,7 +2352,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size)
+ struct address_space *mapping = inode->i_mapping;
+ const struct address_space_operations *aops = mapping->a_ops;
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ int err;
+
+ err = inode_newsize_ok(inode, size);
+@@ -2378,7 +2378,7 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
+ const struct address_space_operations *aops = mapping->a_ops;
+ unsigned int blocksize = i_blocksize(inode);
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ pgoff_t index, curidx;
+ loff_t curpos;
+ unsigned zerofrom, offset, len;
+diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
+index 864cdaa0d2bd6..e4151852184e0 100644
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -763,7 +763,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+ struct ceph_mds_snap_realm *ri; /* encoded */
+ __le64 *snaps; /* encoded */
+ __le64 *prior_parent_snaps; /* encoded */
+- struct ceph_snap_realm *realm = NULL;
++ struct ceph_snap_realm *realm;
+ struct ceph_snap_realm *first_realm = NULL;
+ struct ceph_snap_realm *realm_to_rebuild = NULL;
+ int rebuild_snapcs;
+@@ -774,6 +774,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+
+ dout("%s deletion=%d\n", __func__, deletion);
+ more:
++ realm = NULL;
+ rebuild_snapcs = 0;
+ ceph_decode_need(&p, e, sizeof(*ri), bad);
+ ri = p;
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index c2c36451a8837..317ca1be9c4c0 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3846,9 +3846,13 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+ uuid_copy(&cifs_sb->dfs_mount_id, &mnt_ctx.mount_id);
+
+ out:
+- free_xid(mnt_ctx.xid);
+ cifs_try_adding_channels(cifs_sb, mnt_ctx.ses);
+- return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++ rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++ if (rc)
++ goto error;
++
++ free_xid(mnt_ctx.xid);
++ return rc;
+
+ error:
+ dfs_cache_put_refsrv_sessions(&mnt_ctx.mount_id);
+@@ -3875,8 +3879,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+ goto error;
+ }
+
++ rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++ if (rc)
++ goto error;
++
+ free_xid(mnt_ctx.xid);
+- return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++ return rc;
+
+ error:
+ mount_put_conns(&mnt_ctx);
+diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
+index b6e6e5d6c8dd6..baccda02deabc 100644
+--- a/fs/cifs/ioctl.c
++++ b/fs/cifs/ioctl.c
+@@ -343,7 +343,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
+ rc = put_user(ExtAttrBits &
+ FS_FL_USER_VISIBLE,
+ (int __user *)arg);
+- if (rc != EOPNOTSUPP)
++ if (rc != -EOPNOTSUPP)
+ break;
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+@@ -373,7 +373,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
+ * pSMBFile->fid.netfid,
+ * extAttrBits,
+ * &ExtAttrMask);
+- * if (rc != EOPNOTSUPP)
++ * if (rc != -EOPNOTSUPP)
+ * break;
+ */
+
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 87f60f7367315..35085fa866367 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -400,6 +400,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ {
+ struct smb_hdr *buf = (struct smb_hdr *)buffer;
+ struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
++ struct TCP_Server_Info *pserver;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+ struct cifsInodeInfo *pCifsInode;
+@@ -464,9 +465,12 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
+ return false;
+
++ /* If server is a channel, select the primary channel */
++ pserver = CIFS_SERVER_IS_CHAN(srv) ? srv->primary_server : srv;
++
+ /* look up tcon based on tid & uid */
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ if (tcon->tid != buf->Tid)
+ continue;
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
+index d73e5672aac49..3bcd3ac65dc17 100644
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -135,6 +135,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
+ int
+ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ {
++ struct TCP_Server_Info *pserver;
+ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+ int hdr_size = sizeof(struct smb2_hdr);
+@@ -143,6 +144,9 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ __u32 calc_len; /* calculated length */
+ __u64 mid;
+
++ /* If server is a channel, select the primary channel */
++ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ /*
+ * Add function to do table lookup of StructureSize by command
+ * ie Validate the wct via smb2_struct_sizes table above
+@@ -155,7 +159,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+
+ /* decrypt frame now that it is completely read in */
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) {
+ if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
+ ses = iter;
+ break;
+@@ -671,6 +675,7 @@ bool
+ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ {
+ struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
++ struct TCP_Server_Info *pserver;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+ struct cifsInodeInfo *cinode;
+@@ -691,9 +696,12 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+
+ cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
+
++ /* If server is a channel, select the primary channel */
++ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ /* look up tcon based on tid & uid */
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+
+ spin_lock(&tcon->open_file_lock);
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 14376437187ae..b724bf42b5401 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1123,6 +1123,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+ COMPOUND_FID, current->tgid,
+ FILE_FULL_EA_INFORMATION,
+ SMB2_O_INFO_FILE, 0, data, size);
++ if (rc)
++ goto sea_exit;
+ smb2_set_next_command(tcon, &rqst[1]);
+ smb2_set_related(&rqst[1]);
+
+@@ -1133,6 +1135,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+ rqst[2].rq_nvec = 1;
+ rc = SMB2_close_init(tcon, server,
+ &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
++ if (rc)
++ goto sea_exit;
+ smb2_set_related(&rqst[2]);
+
+ rc = compound_send_recv(xid, ses, server,
+@@ -2288,14 +2292,18 @@ static void
+ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
+ {
+ struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
++ struct TCP_Server_Info *pserver;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+
+ if (shdr->Status != STATUS_NETWORK_NAME_DELETED)
+ return;
+
++ /* If server is a channel, select the primary channel */
++ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ spin_lock(&cifs_tcp_ses_lock);
+- list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {
+ spin_lock(&tcon->tc_lock);
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index 4640fc4a8b133..da85cfd7803b3 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -140,9 +140,13 @@ out:
+ static struct cifs_ses *
+ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
+ {
++ struct TCP_Server_Info *pserver;
+ struct cifs_ses *ses;
+
+- list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++ /* If server is a channel, select the primary channel */
++ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
++ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ if (ses->Suid != ses_id)
+ continue;
+ ++ses->ses_count;
+diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
+index b5fd9d71e67f1..46ab2b3f9a3c9 100644
+--- a/fs/erofs/fscache.c
++++ b/fs/erofs/fscache.c
+@@ -69,11 +69,15 @@ static void erofs_fscache_rreq_unlock_folios(struct netfs_io_request *rreq)
+
+ rcu_read_lock();
+ xas_for_each(&xas, folio, last_page) {
+- unsigned int pgpos =
+- (folio_index(folio) - start_page) * PAGE_SIZE;
+- unsigned int pgend = pgpos + folio_size(folio);
++ unsigned int pgpos, pgend;
+ bool pg_failed = false;
+
++ if (xas_retry(&xas, folio))
++ continue;
++
++ pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
++ pgend = pgpos + folio_size(folio);
++
+ for (;;) {
+ if (!subreq) {
+ pg_failed = true;
+@@ -234,113 +238,114 @@ out:
+ return ret;
+ }
+
+-static int erofs_fscache_read_folio_inline(struct folio *folio,
+- struct erofs_map_blocks *map)
+-{
+- struct super_block *sb = folio_mapping(folio)->host->i_sb;
+- struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+- erofs_blk_t blknr;
+- size_t offset, len;
+- void *src, *dst;
+-
+- /* For tail packing layout, the offset may be non-zero. */
+- offset = erofs_blkoff(map->m_pa);
+- blknr = erofs_blknr(map->m_pa);
+- len = map->m_llen;
+-
+- src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
+- if (IS_ERR(src))
+- return PTR_ERR(src);
+-
+- dst = kmap_local_folio(folio, 0);
+- memcpy(dst, src + offset, len);
+- memset(dst + len, 0, PAGE_SIZE - len);
+- kunmap_local(dst);
+-
+- erofs_put_metabuf(&buf);
+- return 0;
+-}
+-
+-static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
++/*
++ * Read into page cache in the range described by (@pos, @len).
++ *
++ * On return, the caller is responsible for page unlocking if the output @unlock
++ * is true, or the callee will take this responsibility through netfs_io_request
++ * interface.
++ *
++ * The return value is the number of bytes successfully handled, or negative
++ * error code on failure. The only exception is that, the length of the range
++ * instead of the error code is returned on failure after netfs_io_request is
++ * allocated, so that .readahead() could advance rac accordingly.
++ */
++static int erofs_fscache_data_read(struct address_space *mapping,
++ loff_t pos, size_t len, bool *unlock)
+ {
+- struct inode *inode = folio_mapping(folio)->host;
++ struct inode *inode = mapping->host;
+ struct super_block *sb = inode->i_sb;
++ struct netfs_io_request *rreq;
+ struct erofs_map_blocks map;
+ struct erofs_map_dev mdev;
+- struct netfs_io_request *rreq;
+- erofs_off_t pos;
+- loff_t pstart;
++ struct iov_iter iter;
++ size_t count;
+ int ret;
+
+- DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ);
++ *unlock = true;
+
+- pos = folio_pos(folio);
+ map.m_la = pos;
+-
+ ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
+ if (ret)
+- goto out_unlock;
++ return ret;
+
+- if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+- folio_zero_range(folio, 0, folio_size(folio));
+- goto out_uptodate;
++ if (map.m_flags & EROFS_MAP_META) {
++ struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
++ erofs_blk_t blknr;
++ size_t offset, size;
++ void *src;
++
++ /* For tail packing layout, the offset may be non-zero. */
++ offset = erofs_blkoff(map.m_pa);
++ blknr = erofs_blknr(map.m_pa);
++ size = map.m_llen;
++
++ src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
++ if (IS_ERR(src))
++ return PTR_ERR(src);
++
++ iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, PAGE_SIZE);
++ if (copy_to_iter(src + offset, size, &iter) != size) {
++ erofs_put_metabuf(&buf);
++ return -EFAULT;
++ }
++ iov_iter_zero(PAGE_SIZE - size, &iter);
++ erofs_put_metabuf(&buf);
++ return PAGE_SIZE;
+ }
+
+- if (map.m_flags & EROFS_MAP_META) {
+- ret = erofs_fscache_read_folio_inline(folio, &map);
+- goto out_uptodate;
++ if (!(map.m_flags & EROFS_MAP_MAPPED)) {
++ count = len;
++ iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, count);
++ iov_iter_zero(count, &iter);
++ return count;
+ }
+
++ count = min_t(size_t, map.m_llen - (pos - map.m_la), len);
++ DBG_BUGON(!count || count % PAGE_SIZE);
++
+ mdev = (struct erofs_map_dev) {
+ .m_deviceid = map.m_deviceid,
+ .m_pa = map.m_pa,
+ };
+-
+ ret = erofs_map_dev(sb, &mdev);
+ if (ret)
+- goto out_unlock;
+-
+-
+- rreq = erofs_fscache_alloc_request(folio_mapping(folio),
+- folio_pos(folio), folio_size(folio));
+- if (IS_ERR(rreq)) {
+- ret = PTR_ERR(rreq);
+- goto out_unlock;
+- }
++ return ret;
+
+- pstart = mdev.m_pa + (pos - map.m_la);
+- return erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
+- rreq, pstart);
++ rreq = erofs_fscache_alloc_request(mapping, pos, count);
++ if (IS_ERR(rreq))
++ return PTR_ERR(rreq);
+
+-out_uptodate:
+- if (!ret)
+- folio_mark_uptodate(folio);
+-out_unlock:
+- folio_unlock(folio);
+- return ret;
++ *unlock = false;
++ erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
++ rreq, mdev.m_pa + (pos - map.m_la));
++ return count;
+ }
+
+-static void erofs_fscache_advance_folios(struct readahead_control *rac,
+- size_t len, bool unlock)
++static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
+ {
+- while (len) {
+- struct folio *folio = readahead_folio(rac);
+- len -= folio_size(folio);
+- if (unlock) {
++ bool unlock;
++ int ret;
++
++ DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ);
++
++ ret = erofs_fscache_data_read(folio_mapping(folio), folio_pos(folio),
++ folio_size(folio), &unlock);
++ if (unlock) {
++ if (ret > 0)
+ folio_mark_uptodate(folio);
+- folio_unlock(folio);
+- }
++ folio_unlock(folio);
+ }
++ return ret < 0 ? ret : 0;
+ }
+
+ static void erofs_fscache_readahead(struct readahead_control *rac)
+ {
+- struct inode *inode = rac->mapping->host;
+- struct super_block *sb = inode->i_sb;
+- size_t len, count, done = 0;
+- erofs_off_t pos;
+- loff_t start, offset;
+- int ret;
++ struct folio *folio;
++ size_t len, done = 0;
++ loff_t start, pos;
++ bool unlock;
++ int ret, size;
+
+ if (!readahead_count(rac))
+ return;
+@@ -349,67 +354,22 @@ static void erofs_fscache_readahead(struct readahead_control *rac)
+ len = readahead_length(rac);
+
+ do {
+- struct erofs_map_blocks map;
+- struct erofs_map_dev mdev;
+- struct netfs_io_request *rreq;
+-
+ pos = start + done;
+- map.m_la = pos;
+-
+- ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
+- if (ret)
++ ret = erofs_fscache_data_read(rac->mapping, pos,
++ len - done, &unlock);
++ if (ret <= 0)
+ return;
+
+- offset = start + done;
+- count = min_t(size_t, map.m_llen - (pos - map.m_la),
+- len - done);
+-
+- if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+- struct iov_iter iter;
+-
+- iov_iter_xarray(&iter, READ, &rac->mapping->i_pages,
+- offset, count);
+- iov_iter_zero(count, &iter);
+-
+- erofs_fscache_advance_folios(rac, count, true);
+- ret = count;
+- continue;
+- }
+-
+- if (map.m_flags & EROFS_MAP_META) {
+- struct folio *folio = readahead_folio(rac);
+-
+- ret = erofs_fscache_read_folio_inline(folio, &map);
+- if (!ret) {
++ size = ret;
++ while (size) {
++ folio = readahead_folio(rac);
++ size -= folio_size(folio);
++ if (unlock) {
+ folio_mark_uptodate(folio);
+- ret = folio_size(folio);
++ folio_unlock(folio);
+ }
+-
+- folio_unlock(folio);
+- continue;
+ }
+-
+- mdev = (struct erofs_map_dev) {
+- .m_deviceid = map.m_deviceid,
+- .m_pa = map.m_pa,
+- };
+- ret = erofs_map_dev(sb, &mdev);
+- if (ret)
+- return;
+-
+- rreq = erofs_fscache_alloc_request(rac->mapping, offset, count);
+- if (IS_ERR(rreq))
+- return;
+- /*
+- * Drop the ref of folios here. Unlock them in
+- * rreq_unlock_folios() when rreq complete.
+- */
+- erofs_fscache_advance_folios(rac, count, false);
+- ret = erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
+- rreq, mdev.m_pa + (pos - map.m_la));
+- if (!ret)
+- ret = count;
+- } while (ret > 0 && ((done += ret) < len));
++ } while ((done += ret) < len);
+ }
+
+ static const struct address_space_operations erofs_fscache_meta_aops = {
+diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
+index 549879929c847..c7e2e62383668 100644
+--- a/fs/gfs2/ops_fstype.c
++++ b/fs/gfs2/ops_fstype.c
+@@ -178,7 +178,10 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
+ pr_warn("Invalid block size\n");
+ return -EINVAL;
+ }
+-
++ if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) {
++ pr_warn("Invalid block size shift\n");
++ return -EINVAL;
++ }
+ return 0;
+ }
+
+@@ -381,8 +384,10 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
+ if (!table[0])
+ table = sdp->sd_vfs->s_id;
+
+- strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
+- strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
++ BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN);
++
++ strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN);
++ strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN);
+
+ table = sdp->sd_table_name;
+ while ((table = strchr(table, '/')))
+@@ -1439,13 +1444,13 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
+
+ switch (o) {
+ case Opt_lockproto:
+- strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
++ strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
+ break;
+ case Opt_locktable:
+- strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
++ strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
+ break;
+ case Opt_hostdata:
+- strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
++ strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
+ break;
+ case Opt_spectator:
+ args->ar_spectator = 1;
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index f7a5b5124d8a9..fbcfa6bfee805 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -328,6 +328,12 @@ static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
+ } else {
+ unlock_page(page);
+
++ if (PageHWPoison(page)) {
++ put_page(page);
++ retval = -EIO;
++ break;
++ }
++
+ /*
+ * We have the page, copy it to user space buffer.
+ */
+@@ -364,7 +370,7 @@ static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
+ return -EINVAL;
+ }
+
+-static void remove_huge_page(struct page *page)
++static void hugetlb_delete_from_page_cache(struct page *page)
+ {
+ ClearPageDirty(page);
+ ClearPageUptodate(page);
+@@ -487,15 +493,14 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
+ folio_lock(folio);
+ /*
+ * We must free the huge page and remove from page
+- * cache (remove_huge_page) BEFORE removing the
+- * region/reserve map (hugetlb_unreserve_pages). In
+- * rare out of memory conditions, removal of the
+- * region/reserve map could fail. Correspondingly,
+- * the subpool and global reserve usage count can need
+- * to be adjusted.
++ * cache BEFORE removing the region/reserve map
++ * (hugetlb_unreserve_pages). In rare out of memory
++ * conditions, removal of the region/reserve map could
++ * fail. Correspondingly, the subpool and global
++ * reserve usage count can need to be adjusted.
+ */
+ VM_BUG_ON(HPageRestoreReserve(&folio->page));
+- remove_huge_page(&folio->page);
++ hugetlb_delete_from_page_cache(&folio->page);
+ freed++;
+ if (!truncate_op) {
+ if (unlikely(hugetlb_unreserve_pages(inode,
+@@ -737,7 +742,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
+ }
+ clear_huge_page(page, addr, pages_per_huge_page(h));
+ __SetPageUptodate(page);
+- error = huge_add_to_page_cache(page, mapping, index);
++ error = hugetlb_add_to_page_cache(page, mapping, index);
+ if (unlikely(error)) {
+ restore_reserve_on_error(h, &pseudo_vma, addr, page);
+ put_page(page);
+@@ -749,7 +754,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
+
+ SetHPageMigratable(page);
+ /*
+- * unlock_page because locked by huge_add_to_page_cache()
++ * unlock_page because locked by hugetlb_add_to_page_cache()
+ * put_page() due to reference from alloc_huge_page()
+ */
+ unlock_page(page);
+@@ -991,13 +996,6 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
+ static int hugetlbfs_error_remove_page(struct address_space *mapping,
+ struct page *page)
+ {
+- struct inode *inode = mapping->host;
+- pgoff_t index = page->index;
+-
+- remove_huge_page(page);
+- if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1)))
+- hugetlb_fix_reserve_counts(inode);
+-
+ return 0;
+ }
+
+diff --git a/fs/namei.c b/fs/namei.c
+index 53b4bc094db23..076ae96ca0b14 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -5088,7 +5088,7 @@ int page_symlink(struct inode *inode, const char *symname, int len)
+ const struct address_space_operations *aops = mapping->a_ops;
+ bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS);
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ int err;
+ unsigned int flags;
+
+diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
+index 0ce5358521510..7679a68e81930 100644
+--- a/fs/netfs/buffered_read.c
++++ b/fs/netfs/buffered_read.c
+@@ -17,9 +17,9 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ {
+ struct netfs_io_subrequest *subreq;
+ struct folio *folio;
+- unsigned int iopos, account = 0;
+ pgoff_t start_page = rreq->start / PAGE_SIZE;
+ pgoff_t last_page = ((rreq->start + rreq->len) / PAGE_SIZE) - 1;
++ size_t account = 0;
+ bool subreq_failed = false;
+
+ XA_STATE(xas, &rreq->mapping->i_pages, start_page);
+@@ -39,18 +39,23 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ */
+ subreq = list_first_entry(&rreq->subrequests,
+ struct netfs_io_subrequest, rreq_link);
+- iopos = 0;
+ subreq_failed = (subreq->error < 0);
+
+ trace_netfs_rreq(rreq, netfs_rreq_trace_unlock);
+
+ rcu_read_lock();
+ xas_for_each(&xas, folio, last_page) {
+- unsigned int pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
+- unsigned int pgend = pgpos + folio_size(folio);
++ loff_t pg_end;
+ bool pg_failed = false;
+
++ if (xas_retry(&xas, folio))
++ continue;
++
++ pg_end = folio_pos(folio) + folio_size(folio) - 1;
++
+ for (;;) {
++ loff_t sreq_end;
++
+ if (!subreq) {
+ pg_failed = true;
+ break;
+@@ -58,11 +63,11 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags))
+ folio_start_fscache(folio);
+ pg_failed |= subreq_failed;
+- if (pgend < iopos + subreq->len)
++ sreq_end = subreq->start + subreq->len - 1;
++ if (pg_end < sreq_end)
+ break;
+
+ account += subreq->transferred;
+- iopos += subreq->len;
+ if (!list_is_last(&subreq->rreq_link, &rreq->subrequests)) {
+ subreq = list_next_entry(subreq, rreq_link);
+ subreq_failed = (subreq->error < 0);
+@@ -70,7 +75,8 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ subreq = NULL;
+ subreq_failed = false;
+ }
+- if (pgend == iopos)
++
++ if (pg_end == sreq_end)
+ break;
+ }
+
+diff --git a/fs/netfs/io.c b/fs/netfs/io.c
+index 4289258992826..e374767d1b683 100644
+--- a/fs/netfs/io.c
++++ b/fs/netfs/io.c
+@@ -121,6 +121,9 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
+ XA_STATE(xas, &rreq->mapping->i_pages, subreq->start / PAGE_SIZE);
+
+ xas_for_each(&xas, folio, (subreq->start + subreq->len - 1) / PAGE_SIZE) {
++ if (xas_retry(&xas, folio))
++ continue;
++
+ /* We might have multiple writes from the same huge
+ * folio, but we mustn't unlock a folio more than once.
+ */
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 3ed14a2a84a44..313e9145b6c9f 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -7137,6 +7137,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ {
+ struct nfs4_lockdata *data = calldata;
+ struct nfs4_lock_state *lsp = data->lsp;
++ struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry));
+
+ if (!nfs4_sequence_done(task, &data->res.seq_res))
+ return;
+@@ -7144,8 +7145,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ data->rpc_status = task->tk_status;
+ switch (task->tk_status) {
+ case 0:
+- renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)),
+- data->timestamp);
++ renew_lease(server, data->timestamp);
+ if (data->arg.new_lock && !data->cancelled) {
+ data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS);
+ if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0)
+@@ -7166,6 +7166,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ if (!nfs4_stateid_match(&data->arg.open_stateid,
+ &lsp->ls_state->open_stateid))
+ goto out_restart;
++ else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN)
++ goto out_restart;
+ } else if (!nfs4_stateid_match(&data->arg.lock_stateid,
+ &lsp->ls_stateid))
+ goto out_restart;
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 0bc36472f8b7b..ddb2bf078fdaf 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -5313,6 +5313,7 @@ nfsd4_verify_deleg_dentry(struct nfsd4_open *open, struct nfs4_file *fp,
+ if (err)
+ return -EAGAIN;
+
++ exp_put(exp);
+ dput(child);
+ if (child != file_dentry(fp->fi_deleg_file->nf_file))
+ return -EAGAIN;
+diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
+index 52615e6090e1c..a3865bc4a0c65 100644
+--- a/fs/ntfs/attrib.c
++++ b/fs/ntfs/attrib.c
+@@ -594,17 +594,37 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
+ for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
+ u8 *mrec_end = (u8 *)ctx->mrec +
+ le32_to_cpu(ctx->mrec->bytes_allocated);
+- u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
+- a->name_length * sizeof(ntfschar);
+- if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end ||
+- name_end > mrec_end)
++ u8 *name_end;
++
++ /* check whether ATTR_RECORD wrap */
++ if ((u8 *)a < (u8 *)ctx->mrec)
++ break;
++
++ /* check whether Attribute Record Header is within bounds */
++ if ((u8 *)a > mrec_end ||
++ (u8 *)a + sizeof(ATTR_RECORD) > mrec_end)
++ break;
++
++ /* check whether ATTR_RECORD's name is within bounds */
++ name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
++ a->name_length * sizeof(ntfschar);
++ if (name_end > mrec_end)
+ break;
++
+ ctx->attr = a;
+ if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
+ a->type == AT_END))
+ return -ENOENT;
+ if (unlikely(!a->length))
+ break;
++
++ /* check whether ATTR_RECORD's length wrap */
++ if ((u8 *)a + le32_to_cpu(a->length) < (u8 *)a)
++ break;
++ /* check whether ATTR_RECORD's length is within bounds */
++ if ((u8 *)a + le32_to_cpu(a->length) > mrec_end)
++ break;
++
+ if (a->type != type)
+ continue;
+ /*
+diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
+index db0f1995aedd1..08c659332e26b 100644
+--- a/fs/ntfs/inode.c
++++ b/fs/ntfs/inode.c
+@@ -1829,6 +1829,13 @@ int ntfs_read_inode_mount(struct inode *vi)
+ goto err_out;
+ }
+
++ /* Sanity check offset to the first attribute */
++ if (le16_to_cpu(m->attrs_offset) >= le32_to_cpu(m->bytes_allocated)) {
++ ntfs_error(sb, "Incorrect mft offset to the first attribute %u in superblock.",
++ le16_to_cpu(m->attrs_offset));
++ goto err_out;
++ }
++
+ /* Need this to sanity check attribute list references to $MFT. */
+ vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number);
+
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 84b13fdd34a71..79624711fda7c 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -311,6 +311,13 @@ struct queue_limits {
+ unsigned char discard_misaligned;
+ unsigned char raid_partial_stripes_expensive;
+ enum blk_zoned_model zoned;
++
++ /*
++ * Drivers that set dma_alignment to less than 511 must be prepared to
++ * handle individual bvec's that are not a multiple of a SECTOR_SIZE
++ * due to possible offsets.
++ */
++ unsigned int dma_alignment;
+ };
+
+ typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx,
+@@ -456,12 +463,6 @@ struct request_queue {
+ unsigned long nr_requests; /* Max # of requests */
+
+ unsigned int dma_pad_mask;
+- /*
+- * Drivers that set dma_alignment to less than 511 must be prepared to
+- * handle individual bvec's that are not a multiple of a SECTOR_SIZE
+- * due to possible offsets.
+- */
+- unsigned int dma_alignment;
+
+ #ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct blk_crypto_profile *crypto_profile;
+@@ -1311,7 +1312,7 @@ static inline sector_t bdev_zone_sectors(struct block_device *bdev)
+
+ static inline int queue_dma_alignment(const struct request_queue *q)
+ {
+- return q ? q->dma_alignment : 511;
++ return q ? q->limits.dma_alignment : 511;
+ }
+
+ static inline unsigned int bdev_dma_alignment(struct block_device *bdev)
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 80fc8a88c610d..73662fbabd78f 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -1967,6 +1967,7 @@ static inline bool unprivileged_ebpf_enabled(void)
+ return !sysctl_unprivileged_bpf_disabled;
+ }
+
++void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog);
+ #else /* !CONFIG_BPF_SYSCALL */
+ static inline struct bpf_prog *bpf_prog_get(u32 ufd)
+ {
+@@ -2176,6 +2177,9 @@ static inline bool unprivileged_ebpf_enabled(void)
+ return false;
+ }
+
++static inline void bpf_prog_inc_misses_counter(struct bpf_prog *prog)
++{
++}
+ #endif /* CONFIG_BPF_SYSCALL */
+
+ void __bpf_free_used_btfs(struct bpf_prog_aux *aux,
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 67c88b82fc32d..53db3648207ae 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -665,7 +665,7 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
+ nodemask_t *nmask, gfp_t gfp_mask);
+ struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
+ unsigned long address);
+-int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
++int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping,
+ pgoff_t idx);
+ void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma,
+ unsigned long address, struct page *page);
+diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
+index 4a2f6cc5a4927..ad88c4fa11132 100644
+--- a/include/linux/io_uring.h
++++ b/include/linux/io_uring.h
+@@ -15,6 +15,9 @@ enum io_uring_cmd_flags {
+ IO_URING_F_SQE128 = 4,
+ IO_URING_F_CQE32 = 8,
+ IO_URING_F_IOPOLL = 16,
++
++ /* the request is executed from poll, it should not be freed */
++ IO_URING_F_MULTISHOT = 32,
+ };
+
+ struct io_uring_cmd {
+diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
+index 2504df9a0453e..3c7d295746f67 100644
+--- a/include/linux/ring_buffer.h
++++ b/include/linux/ring_buffer.h
+@@ -100,7 +100,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
+
+ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+- struct file *filp, poll_table *poll_table);
++ struct file *filp, poll_table *poll_table, int full);
+ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
+
+ #define RING_BUFFER_ALL_CPUS -1
+diff --git a/include/linux/trace.h b/include/linux/trace.h
+index b5e16e438448f..80ffda8717491 100644
+--- a/include/linux/trace.h
++++ b/include/linux/trace.h
+@@ -26,13 +26,13 @@ struct trace_export {
+ int flags;
+ };
+
++struct trace_array;
++
+ #ifdef CONFIG_TRACING
+
+ int register_ftrace_export(struct trace_export *export);
+ int unregister_ftrace_export(struct trace_export *export);
+
+-struct trace_array;
+-
+ void trace_printk_init_buffers(void);
+ __printf(3, 4)
+ int trace_array_printk(struct trace_array *tr, unsigned long ip,
+diff --git a/include/linux/wireless.h b/include/linux/wireless.h
+index 2d1b54556eff4..e6e34d74dda04 100644
+--- a/include/linux/wireless.h
++++ b/include/linux/wireless.h
+@@ -26,7 +26,15 @@ struct compat_iw_point {
+ struct __compat_iw_event {
+ __u16 len; /* Real length of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+- compat_caddr_t pointer;
++
++ union {
++ compat_caddr_t pointer;
++
++ /* we need ptr_bytes to make memcpy() run-time destination
++ * buffer bounds checking happy, nothing special
++ */
++ DECLARE_FLEX_ARRAY(__u8, ptr_bytes);
++ };
+ };
+ #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
+ #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 1c979fd1904ce..1eca38ac6c67e 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -563,7 +563,7 @@ static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
+ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
+ offsetof(typeof(flow->addrs), v4addrs.src) +
+ sizeof(flow->addrs.v4addrs.src));
+- memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
++ memcpy(&flow->addrs.v4addrs, &iph->addrs, sizeof(flow->addrs.v4addrs));
+ flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ }
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index de9dcc5652c48..59125562c1a42 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -897,7 +897,7 @@ static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,
+ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) !=
+ offsetof(typeof(flow->addrs), v6addrs.src) +
+ sizeof(flow->addrs.v6addrs.src));
+- memcpy(&flow->addrs.v6addrs, &iph->saddr, sizeof(flow->addrs.v6addrs));
++ memcpy(&flow->addrs.v6addrs, &iph->addrs, sizeof(flow->addrs.v6addrs));
+ flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ }
+
+diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
+index 6ce3bd22f6c69..5ad7ac2e3a7ce 100644
+--- a/include/soc/at91/sama7-ddr.h
++++ b/include/soc/at91/sama7-ddr.h
+@@ -26,7 +26,10 @@
+ #define DDR3PHY_PGSR (0x0C) /* DDR3PHY PHY General Status Register */
+ #define DDR3PHY_PGSR_IDONE (1 << 0) /* Initialization Done */
+
+-#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */
++#define DDR3PHY_ACDLLCR (0x14) /* DDR3PHY AC DLL Control Register */
++#define DDR3PHY_ACDLLCR_DLLSRST (1 << 30) /* DLL Soft Reset */
++
++#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */
+ #define DDR3PHY_ACIOCR_CSPDD_CS0 (1 << 18) /* CS#[0] Power Down Driver */
+ #define DDR3PHY_ACIOCR_CKPDD_CK0 (1 << 8) /* CK[0] Power Down Driver */
+ #define DDR3PHY_ACIORC_ACPDD (1 << 3) /* AC Power Down Driver */
+diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
+index 961ec16a26b8b..874a92349bf5b 100644
+--- a/include/uapi/linux/ip.h
++++ b/include/uapi/linux/ip.h
+@@ -100,8 +100,10 @@ struct iphdr {
+ __u8 ttl;
+ __u8 protocol;
+ __sum16 check;
+- __be32 saddr;
+- __be32 daddr;
++ __struct_group(/* no tag */, addrs, /* no attrs */,
++ __be32 saddr;
++ __be32 daddr;
++ );
+ /*The options start here. */
+ };
+
+diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
+index 03cdbe798fe3c..81f4243bebb1c 100644
+--- a/include/uapi/linux/ipv6.h
++++ b/include/uapi/linux/ipv6.h
+@@ -130,8 +130,10 @@ struct ipv6hdr {
+ __u8 nexthdr;
+ __u8 hop_limit;
+
+- struct in6_addr saddr;
+- struct in6_addr daddr;
++ __struct_group(/* no tag */, addrs, /* no attrs */,
++ struct in6_addr saddr;
++ struct in6_addr daddr;
++ );
+ };
+
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index d29f397f095ee..adf73d1625218 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -171,6 +171,11 @@ static inline unsigned int __io_cqring_events(struct io_ring_ctx *ctx)
+ return ctx->cached_cq_tail - READ_ONCE(ctx->rings->cq.head);
+ }
+
++static inline unsigned int __io_cqring_events_user(struct io_ring_ctx *ctx)
++{
++ return READ_ONCE(ctx->rings->cq.tail) - READ_ONCE(ctx->rings->cq.head);
++}
++
+ static bool io_match_linked(struct io_kiocb *head)
+ {
+ struct io_kiocb *req;
+@@ -1613,7 +1618,7 @@ int io_poll_issue(struct io_kiocb *req, bool *locked)
+ io_tw_lock(req->ctx, locked);
+ if (unlikely(req->task->flags & PF_EXITING))
+ return -EFAULT;
+- return io_issue_sqe(req, IO_URING_F_NONBLOCK);
++ return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT);
+ }
+
+ struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
+@@ -2163,7 +2168,7 @@ struct io_wait_queue {
+ static inline bool io_should_wake(struct io_wait_queue *iowq)
+ {
+ struct io_ring_ctx *ctx = iowq->ctx;
+- int dist = ctx->cached_cq_tail - (int) iowq->cq_tail;
++ int dist = READ_ONCE(ctx->rings->cq.tail) - (int) iowq->cq_tail;
+
+ /*
+ * Wake up if we have enough events, or if a timeout occurred since we
+@@ -2240,7 +2245,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ do {
+ io_cqring_overflow_flush(ctx);
+
+- if (io_cqring_events(ctx) >= min_events)
++ /* if user messes with these they will just get an early return */
++ if (__io_cqring_events_user(ctx) >= min_events)
+ return 0;
+ if (!io_run_task_work())
+ break;
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 5121b20a91936..1b552d2137635 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -17,8 +17,8 @@ enum {
+ IOU_ISSUE_SKIP_COMPLETE = -EIOCBQUEUED,
+
+ /*
+- * Intended only when both REQ_F_POLLED and REQ_F_APOLL_MULTISHOT
+- * are set to indicate to the poll runner that multishot should be
++ * Intended only when both IO_URING_F_MULTISHOT is passed
++ * to indicate to the poll runner that multishot should be
+ * removed and the result is set on req->cqe.res.
+ */
+ IOU_STOP_MULTISHOT = -ECANCELED,
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 7804ac77745b1..8205cfecd647c 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -66,8 +66,6 @@ struct io_sr_msg {
+ struct io_kiocb *notif;
+ };
+
+-#define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED)
+-
+ int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+ struct io_shutdown *shutdown = io_kiocb_to_cmd(req, struct io_shutdown);
+@@ -558,7 +556,8 @@ static inline void io_recv_prep_retry(struct io_kiocb *req)
+ * again (for multishot).
+ */
+ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
+- unsigned int cflags, bool mshot_finished)
++ unsigned int cflags, bool mshot_finished,
++ unsigned issue_flags)
+ {
+ if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
+ io_req_set_res(req, *ret, cflags);
+@@ -581,7 +580,7 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
+
+ io_req_set_res(req, *ret, cflags);
+
+- if (req->flags & REQ_F_POLLED)
++ if (issue_flags & IO_URING_F_MULTISHOT)
+ *ret = IOU_STOP_MULTISHOT;
+ else
+ *ret = IOU_OK;
+@@ -740,8 +739,7 @@ retry_multishot:
+ if (ret < min_ret) {
+ if (ret == -EAGAIN && force_nonblock) {
+ ret = io_setup_async_msg(req, kmsg, issue_flags);
+- if (ret == -EAGAIN && (req->flags & IO_APOLL_MULTI_POLLED) ==
+- IO_APOLL_MULTI_POLLED) {
++ if (ret == -EAGAIN && (issue_flags & IO_URING_F_MULTISHOT)) {
+ io_kbuf_recycle(req, issue_flags);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+@@ -770,7 +768,7 @@ retry_multishot:
+ if (kmsg->msg.msg_inq)
+ cflags |= IORING_CQE_F_SOCK_NONEMPTY;
+
+- if (!io_recv_finish(req, &ret, cflags, mshot_finished))
++ if (!io_recv_finish(req, &ret, cflags, mshot_finished, issue_flags))
+ goto retry_multishot;
+
+ if (mshot_finished) {
+@@ -836,7 +834,7 @@ retry_multishot:
+ ret = sock_recvmsg(sock, &msg, flags);
+ if (ret < min_ret) {
+ if (ret == -EAGAIN && force_nonblock) {
+- if ((req->flags & IO_APOLL_MULTI_POLLED) == IO_APOLL_MULTI_POLLED) {
++ if (issue_flags & IO_URING_F_MULTISHOT) {
+ io_kbuf_recycle(req, issue_flags);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+@@ -869,7 +867,7 @@ out_free:
+ if (msg.msg_inq)
+ cflags |= IORING_CQE_F_SOCK_NONEMPTY;
+
+- if (!io_recv_finish(req, &ret, cflags, ret <= 0))
++ if (!io_recv_finish(req, &ret, cflags, ret <= 0, issue_flags))
+ goto retry_multishot;
+
+ return ret;
+@@ -1168,8 +1166,7 @@ retry:
+ * return EAGAIN to arm the poll infra since it
+ * has already been done
+ */
+- if ((req->flags & IO_APOLL_MULTI_POLLED) ==
+- IO_APOLL_MULTI_POLLED)
++ if (issue_flags & IO_URING_F_MULTISHOT)
+ ret = IOU_ISSUE_SKIP_COMPLETE;
+ return ret;
+ }
+@@ -1194,9 +1191,7 @@ retry:
+ goto retry;
+
+ io_req_set_res(req, ret, 0);
+- if (req->flags & REQ_F_POLLED)
+- return IOU_STOP_MULTISHOT;
+- return IOU_OK;
++ return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK;
+ }
+
+ int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index 0d9f49c575e0f..ba0f684669306 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -226,6 +226,13 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ return IOU_POLL_DONE;
+ if (v & IO_POLL_CANCEL_FLAG)
+ return -ECANCELED;
++ /*
++ * cqe.res contains only events of the first wake up
++ * and all others are be lost. Redo vfs_poll() to get
++ * up to date state.
++ */
++ if ((v & IO_POLL_REF_MASK) != 1)
++ req->cqe.res = 0;
+
+ /* the mask was stashed in __io_poll_execute */
+ if (!req->cqe.res) {
+@@ -237,6 +244,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ continue;
+ if (req->apoll_events & EPOLLONESHOT)
+ return IOU_POLL_DONE;
++ if (io_is_uring_fops(req->file))
++ return IOU_POLL_DONE;
+
+ /* multishot, just fill a CQE and proceed */
+ if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
+@@ -256,6 +265,9 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ return ret;
+ }
+
++ /* force the next iteration to vfs_poll() */
++ req->cqe.res = 0;
++
+ /*
+ * Release all references, retry if someone tried to restart
+ * task_work while we were executing it.
+@@ -394,7 +406,8 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
+ return 1;
+ }
+
+-static void io_poll_double_prepare(struct io_kiocb *req)
++/* fails only when polling is already completing by the first entry */
++static bool io_poll_double_prepare(struct io_kiocb *req)
+ {
+ struct wait_queue_head *head;
+ struct io_poll *poll = io_poll_get_single(req);
+@@ -403,20 +416,20 @@ static void io_poll_double_prepare(struct io_kiocb *req)
+ rcu_read_lock();
+ head = smp_load_acquire(&poll->head);
+ /*
+- * poll arm may not hold ownership and so race with
+- * io_poll_wake() by modifying req->flags. There is only one
+- * poll entry queued, serialise with it by taking its head lock.
++ * poll arm might not hold ownership and so race for req->flags with
++ * io_poll_wake(). There is only one poll entry queued, serialise with
++ * it by taking its head lock. As we're still arming the tw hanlder
++ * is not going to be run, so there are no races with it.
+ */
+- if (head)
++ if (head) {
+ spin_lock_irq(&head->lock);
+-
+- req->flags |= REQ_F_DOUBLE_POLL;
+- if (req->opcode == IORING_OP_POLL_ADD)
+- req->flags |= REQ_F_ASYNC_DATA;
+-
+- if (head)
++ req->flags |= REQ_F_DOUBLE_POLL;
++ if (req->opcode == IORING_OP_POLL_ADD)
++ req->flags |= REQ_F_ASYNC_DATA;
+ spin_unlock_irq(&head->lock);
++ }
+ rcu_read_unlock();
++ return !!head;
+ }
+
+ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt,
+@@ -454,7 +467,11 @@ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt,
+ /* mark as double wq entry */
+ wqe_private |= IO_WQE_F_DOUBLE;
+ io_init_poll_iocb(poll, first->events, first->wait.func);
+- io_poll_double_prepare(req);
++ if (!io_poll_double_prepare(req)) {
++ /* the request is completing, just back off */
++ kfree(poll);
++ return;
++ }
+ *poll_ptr = poll;
+ } else {
+ /* fine to modify, there is no poll queued to race with us */
+diff --git a/kernel/bpf/percpu_freelist.c b/kernel/bpf/percpu_freelist.c
+index 00b874c8e889f..2ffb741eee8d0 100644
+--- a/kernel/bpf/percpu_freelist.c
++++ b/kernel/bpf/percpu_freelist.c
+@@ -102,22 +102,21 @@ void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size,
+ u32 nr_elems)
+ {
+ struct pcpu_freelist_head *head;
+- int i, cpu, pcpu_entries;
++ unsigned int cpu, cpu_idx, i, j, n, m;
+
+- pcpu_entries = nr_elems / num_possible_cpus() + 1;
+- i = 0;
++ n = nr_elems / num_possible_cpus();
++ m = nr_elems % num_possible_cpus();
+
++ cpu_idx = 0;
+ for_each_possible_cpu(cpu) {
+-again:
+ head = per_cpu_ptr(s->freelist, cpu);
+- /* No locking required as this is not visible yet. */
+- pcpu_freelist_push_node(head, buf);
+- i++;
+- buf += elem_size;
+- if (i == nr_elems)
+- break;
+- if (i % pcpu_entries)
+- goto again;
++ j = n + (cpu_idx < m ? 1 : 0);
++ for (i = 0; i < j; i++) {
++ /* No locking required as this is not visible yet. */
++ pcpu_freelist_push_node(head, buf);
++ buf += elem_size;
++ }
++ cpu_idx++;
+ }
+ }
+
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 22e7a805c6723..0e758911d963f 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -2094,6 +2094,17 @@ struct bpf_prog_kstats {
+ u64 misses;
+ };
+
++void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog)
++{
++ struct bpf_prog_stats *stats;
++ unsigned int flags;
++
++ stats = this_cpu_ptr(prog->stats);
++ flags = u64_stats_update_begin_irqsave(&stats->syncp);
++ u64_stats_inc(&stats->misses);
++ u64_stats_update_end_irqrestore(&stats->syncp, flags);
++}
++
+ static void bpf_prog_get_stats(const struct bpf_prog *prog,
+ struct bpf_prog_kstats *stats)
+ {
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index ad76940b02ccf..41b67eb83ab3f 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -863,17 +863,6 @@ static __always_inline u64 notrace bpf_prog_start_time(void)
+ return start;
+ }
+
+-static void notrace inc_misses_counter(struct bpf_prog *prog)
+-{
+- struct bpf_prog_stats *stats;
+- unsigned int flags;
+-
+- stats = this_cpu_ptr(prog->stats);
+- flags = u64_stats_update_begin_irqsave(&stats->syncp);
+- u64_stats_inc(&stats->misses);
+- u64_stats_update_end_irqrestore(&stats->syncp, flags);
+-}
+-
+ /* The logic is similar to bpf_prog_run(), but with an explicit
+ * rcu_read_lock() and migrate_disable() which are required
+ * for the trampoline. The macro is split into
+@@ -896,7 +885,7 @@ u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *ru
+ run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx);
+
+ if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+- inc_misses_counter(prog);
++ bpf_prog_inc_misses_counter(prog);
+ return 0;
+ }
+ return bpf_prog_start_time();
+@@ -967,7 +956,7 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r
+ might_fault();
+
+ if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+- inc_misses_counter(prog);
++ bpf_prog_inc_misses_counter(prog);
+ return 0;
+ }
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 69fb46fdf7635..b781075dd5109 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -6674,11 +6674,11 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ /* Transfer references to the callee */
+ err = copy_reference_state(callee, caller);
+ if (err)
+- return err;
++ goto err_out;
+
+ err = set_callee_state_cb(env, caller, callee, *insn_idx);
+ if (err)
+- return err;
++ goto err_out;
+
+ clear_caller_saved_regs(env, caller->regs);
+
+@@ -6695,6 +6695,11 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ print_verifier_state(env, callee, true);
+ }
+ return 0;
++
++err_out:
++ free_func_state(callee);
++ state->frame[state->curframe + 1] = NULL;
++ return err;
+ }
+
+ int map_set_for_each_callback_args(struct bpf_verifier_env *env,
+@@ -6880,8 +6885,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ return -EINVAL;
+ }
+
+- state->curframe--;
+- caller = state->frame[state->curframe];
++ caller = state->frame[state->curframe - 1];
+ if (callee->in_callback_fn) {
+ /* enforce R0 return value range [0, 1]. */
+ struct tnum range = tnum_range(0, 1);
+@@ -6920,7 +6924,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ }
+ /* clear everything in the callee */
+ free_func_state(callee);
+- state->frame[state->curframe + 1] = NULL;
++ state->frame[state->curframe--] = NULL;
+ return 0;
+ }
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 072ab26269c0b..bec18d81b1161 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -9282,14 +9282,27 @@ static int __perf_event_overflow(struct perf_event *event,
+ }
+
+ if (event->attr.sigtrap) {
+- /*
+- * Should not be able to return to user space without processing
+- * pending_sigtrap (kernel events can overflow multiple times).
+- */
+- WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel);
++ unsigned int pending_id = 1;
++
++ if (regs)
++ pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1;
+ if (!event->pending_sigtrap) {
+- event->pending_sigtrap = 1;
++ event->pending_sigtrap = pending_id;
+ local_inc(&event->ctx->nr_pending);
++ } else if (event->attr.exclude_kernel) {
++ /*
++ * Should not be able to return to user space without
++ * consuming pending_sigtrap; with exceptions:
++ *
++ * 1. Where !exclude_kernel, events can overflow again
++ * in the kernel without returning to user space.
++ *
++ * 2. Events that can overflow again before the IRQ-
++ * work without user space progress (e.g. hrtimer).
++ * To approximate progress (with false negatives),
++ * check 32-bit hash of the current IP.
++ */
++ WARN_ON_ONCE(event->pending_sigtrap != pending_id);
+ }
+ event->pending_addr = data->addr;
+ irq_work_queue(&event->pending_irq);
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 917b92ae23821..6d2a8623ec7b5 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1762,7 +1762,13 @@ static int __unregister_kprobe_top(struct kprobe *p)
+ if ((list_p != p) && (list_p->post_handler))
+ goto noclean;
+ }
+- ap->post_handler = NULL;
++ /*
++ * For the kprobe-on-ftrace case, we keep the
++ * post_handler setting to identify this aggrprobe
++ * armed with kprobe_ipmodify_ops.
++ */
++ if (!kprobe_ftrace(ap))
++ ap->post_handler = NULL;
+ }
+ noclean:
+ /*
+diff --git a/kernel/rseq.c b/kernel/rseq.c
+index bda8175f8f993..d38ab944105d7 100644
+--- a/kernel/rseq.c
++++ b/kernel/rseq.c
+@@ -171,12 +171,27 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs)
+ return 0;
+ }
+
++static bool rseq_warn_flags(const char *str, u32 flags)
++{
++ u32 test_flags;
++
++ if (!flags)
++ return false;
++ test_flags = flags & RSEQ_CS_NO_RESTART_FLAGS;
++ if (test_flags)
++ pr_warn_once("Deprecated flags (%u) in %s ABI structure", test_flags, str);
++ test_flags = flags & ~RSEQ_CS_NO_RESTART_FLAGS;
++ if (test_flags)
++ pr_warn_once("Unknown flags (%u) in %s ABI structure", test_flags, str);
++ return true;
++}
++
+ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
+ {
+ u32 flags, event_mask;
+ int ret;
+
+- if (WARN_ON_ONCE(cs_flags & RSEQ_CS_NO_RESTART_FLAGS) || cs_flags)
++ if (rseq_warn_flags("rseq_cs", cs_flags))
+ return -EINVAL;
+
+ /* Get thread flags. */
+@@ -184,7 +199,7 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
+ if (ret)
+ return ret;
+
+- if (WARN_ON_ONCE(flags & RSEQ_CS_NO_RESTART_FLAGS) || flags)
++ if (rseq_warn_flags("rseq", flags))
+ return -EINVAL;
+
+ /*
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index b1daf7c9b895a..ec4b81007796c 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2058,9 +2058,15 @@ static __always_inline
+ void __bpf_trace_run(struct bpf_prog *prog, u64 *args)
+ {
+ cant_sleep();
++ if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
++ bpf_prog_inc_misses_counter(prog);
++ goto out;
++ }
+ rcu_read_lock();
+ (void) bpf_prog_run(prog, args);
+ rcu_read_unlock();
++out:
++ this_cpu_dec(*(prog->active));
+ }
+
+ #define UNPACK(...) __VA_ARGS__
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 8cc9eb60c3c2a..9e6231f4a04f7 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1289,6 +1289,7 @@ static int ftrace_add_mod(struct trace_array *tr,
+ if (!ftrace_mod)
+ return -ENOMEM;
+
++ INIT_LIST_HEAD(&ftrace_mod->list);
+ ftrace_mod->func = kstrdup(func, GFP_KERNEL);
+ ftrace_mod->module = kstrdup(module, GFP_KERNEL);
+ ftrace_mod->enable = enable;
+@@ -3193,7 +3194,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
+ /* if we can't allocate this size, try something smaller */
+ if (!order)
+ return -ENOMEM;
+- order >>= 1;
++ order--;
+ goto again;
+ }
+
+@@ -7394,7 +7395,7 @@ void __init ftrace_init(void)
+ }
+
+ pr_info("ftrace: allocating %ld entries in %ld pages\n",
+- count, count / ENTRIES_PER_PAGE + 1);
++ count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
+
+ ret = ftrace_process_locs(NULL,
+ __start_mcount_loc,
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index d81f7c51025c7..c736487fc0e48 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -73,6 +73,10 @@ static struct trace_event_file *gen_kretprobe_test;
+ #define KPROBE_GEN_TEST_ARG3 NULL
+ #endif
+
++static bool trace_event_file_is_valid(struct trace_event_file *input)
++{
++ return input && !IS_ERR(input);
++}
+
+ /*
+ * Test to make sure we can create a kprobe event, then add more
+@@ -139,6 +143,8 @@ static int __init test_gen_kprobe_cmd(void)
+ kfree(buf);
+ return ret;
+ delete:
++ if (trace_event_file_is_valid(gen_kprobe_test))
++ gen_kprobe_test = NULL;
+ /* We got an error after creating the event, delete it */
+ ret = kprobe_event_delete("gen_kprobe_test");
+ goto out;
+@@ -202,6 +208,8 @@ static int __init test_gen_kretprobe_cmd(void)
+ kfree(buf);
+ return ret;
+ delete:
++ if (trace_event_file_is_valid(gen_kretprobe_test))
++ gen_kretprobe_test = NULL;
+ /* We got an error after creating the event, delete it */
+ ret = kprobe_event_delete("gen_kretprobe_test");
+ goto out;
+@@ -217,10 +225,12 @@ static int __init kprobe_event_gen_test_init(void)
+
+ ret = test_gen_kretprobe_cmd();
+ if (ret) {
+- WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+- "kprobes",
+- "gen_kretprobe_test", false));
+- trace_put_event_file(gen_kretprobe_test);
++ if (trace_event_file_is_valid(gen_kretprobe_test)) {
++ WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
++ "kprobes",
++ "gen_kretprobe_test", false));
++ trace_put_event_file(gen_kretprobe_test);
++ }
+ WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+ }
+
+@@ -229,24 +239,30 @@ static int __init kprobe_event_gen_test_init(void)
+
+ static void __exit kprobe_event_gen_test_exit(void)
+ {
+- /* Disable the event or you can't remove it */
+- WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
+- "kprobes",
+- "gen_kprobe_test", false));
++ if (trace_event_file_is_valid(gen_kprobe_test)) {
++ /* Disable the event or you can't remove it */
++ WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
++ "kprobes",
++ "gen_kprobe_test", false));
++
++ /* Now give the file and instance back */
++ trace_put_event_file(gen_kprobe_test);
++ }
+
+- /* Now give the file and instance back */
+- trace_put_event_file(gen_kprobe_test);
+
+ /* Now unregister and free the event */
+ WARN_ON(kprobe_event_delete("gen_kprobe_test"));
+
+- /* Disable the event or you can't remove it */
+- WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+- "kprobes",
+- "gen_kretprobe_test", false));
++ if (trace_event_file_is_valid(gen_kretprobe_test)) {
++ /* Disable the event or you can't remove it */
++ WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
++ "kprobes",
++ "gen_kretprobe_test", false));
++
++ /* Now give the file and instance back */
++ trace_put_event_file(gen_kretprobe_test);
++ }
+
+- /* Now give the file and instance back */
+- trace_put_event_file(gen_kretprobe_test);
+
+ /* Now unregister and free the event */
+ WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c
+index c69d82273ce78..32c3dfdb4d6a7 100644
+--- a/kernel/trace/rethook.c
++++ b/kernel/trace/rethook.c
+@@ -83,8 +83,10 @@ struct rethook *rethook_alloc(void *data, rethook_handler_t handler)
+ {
+ struct rethook *rh = kzalloc(sizeof(struct rethook), GFP_KERNEL);
+
+- if (!rh || !handler)
++ if (!rh || !handler) {
++ kfree(rh);
+ return NULL;
++ }
+
+ rh->data = data;
+ rh->handler = handler;
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 9c72571ffb0bf..0b93dc17457de 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -519,6 +519,7 @@ struct ring_buffer_per_cpu {
+ local_t committing;
+ local_t commits;
+ local_t pages_touched;
++ local_t pages_lost;
+ local_t pages_read;
+ long last_pages_touch;
+ size_t shortest_full;
+@@ -894,10 +895,18 @@ size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
+ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
+ {
+ size_t read;
++ size_t lost;
+ size_t cnt;
+
+ read = local_read(&buffer->buffers[cpu]->pages_read);
++ lost = local_read(&buffer->buffers[cpu]->pages_lost);
+ cnt = local_read(&buffer->buffers[cpu]->pages_touched);
++
++ if (WARN_ON_ONCE(cnt < lost))
++ return 0;
++
++ cnt -= lost;
++
+ /* The reader can read an empty page, but not more than that */
+ if (cnt < read) {
+ WARN_ON_ONCE(read > cnt + 1);
+@@ -907,6 +916,21 @@ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
+ return cnt - read;
+ }
+
++static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int full)
++{
++ struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
++ size_t nr_pages;
++ size_t dirty;
++
++ nr_pages = cpu_buffer->nr_pages;
++ if (!nr_pages || !full)
++ return true;
++
++ dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
++
++ return (dirty * 100) > (full * nr_pages);
++}
++
+ /*
+ * rb_wake_up_waiters - wake up tasks waiting for ring buffer input
+ *
+@@ -1046,22 +1070,20 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ !ring_buffer_empty_cpu(buffer, cpu)) {
+ unsigned long flags;
+ bool pagebusy;
+- size_t nr_pages;
+- size_t dirty;
++ bool done;
+
+ if (!full)
+ break;
+
+ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+ pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page;
+- nr_pages = cpu_buffer->nr_pages;
+- dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
++ done = !pagebusy && full_hit(buffer, cpu, full);
++
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+- if (!pagebusy &&
+- (!nr_pages || (dirty * 100) > full * nr_pages))
++ if (done)
+ break;
+ }
+
+@@ -1087,6 +1109,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ * @cpu: the cpu buffer to wait on
+ * @filp: the file descriptor
+ * @poll_table: The poll descriptor
++ * @full: wait until the percentage of pages are available, if @cpu != RING_BUFFER_ALL_CPUS
+ *
+ * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon
+ * as data is added to any of the @buffer's cpu buffers. Otherwise
+@@ -1096,14 +1119,15 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ * zero otherwise.
+ */
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+- struct file *filp, poll_table *poll_table)
++ struct file *filp, poll_table *poll_table, int full)
+ {
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct rb_irq_work *work;
+
+- if (cpu == RING_BUFFER_ALL_CPUS)
++ if (cpu == RING_BUFFER_ALL_CPUS) {
+ work = &buffer->irq_work;
+- else {
++ full = 0;
++ } else {
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return -EINVAL;
+
+@@ -1111,8 +1135,14 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ work = &cpu_buffer->irq_work;
+ }
+
+- poll_wait(filp, &work->waiters, poll_table);
+- work->waiters_pending = true;
++ if (full) {
++ poll_wait(filp, &work->full_waiters, poll_table);
++ work->full_waiters_pending = true;
++ } else {
++ poll_wait(filp, &work->waiters, poll_table);
++ work->waiters_pending = true;
++ }
++
+ /*
+ * There's a tight race between setting the waiters_pending and
+ * checking if the ring buffer is empty. Once the waiters_pending bit
+@@ -1128,6 +1158,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ */
+ smp_mb();
+
++ if (full)
++ return full_hit(buffer, cpu, full) ? EPOLLIN | EPOLLRDNORM : 0;
++
+ if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
+ (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))
+ return EPOLLIN | EPOLLRDNORM;
+@@ -1769,9 +1802,9 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
+
+ free_buffer_page(cpu_buffer->reader_page);
+
+- rb_head_page_deactivate(cpu_buffer);
+-
+ if (head) {
++ rb_head_page_deactivate(cpu_buffer);
++
+ list_for_each_entry_safe(bpage, tmp, head, list) {
+ list_del_init(&bpage->list);
+ free_buffer_page(bpage);
+@@ -2007,6 +2040,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ */
+ local_add(page_entries, &cpu_buffer->overrun);
+ local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++ local_inc(&cpu_buffer->pages_lost);
+ }
+
+ /*
+@@ -2491,6 +2525,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
+ */
+ local_add(entries, &cpu_buffer->overrun);
+ local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++ local_inc(&cpu_buffer->pages_lost);
+
+ /*
+ * The entries will be zeroed out when we move the
+@@ -3155,10 +3190,6 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
+ static __always_inline void
+ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
+ {
+- size_t nr_pages;
+- size_t dirty;
+- size_t full;
+-
+ if (buffer->irq_work.waiters_pending) {
+ buffer->irq_work.waiters_pending = false;
+ /* irq_work_queue() supplies it's own memory barriers */
+@@ -3182,10 +3213,7 @@ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
+
+ cpu_buffer->last_pages_touch = local_read(&cpu_buffer->pages_touched);
+
+- full = cpu_buffer->shortest_full;
+- nr_pages = cpu_buffer->nr_pages;
+- dirty = ring_buffer_nr_dirty_pages(buffer, cpu_buffer->cpu);
+- if (full && nr_pages && (dirty * 100) <= full * nr_pages)
++ if (!full_hit(buffer, cpu_buffer->cpu, cpu_buffer->shortest_full))
+ return;
+
+ cpu_buffer->irq_work.wakeup_full = true;
+@@ -5248,6 +5276,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+ local_set(&cpu_buffer->committing, 0);
+ local_set(&cpu_buffer->commits, 0);
+ local_set(&cpu_buffer->pages_touched, 0);
++ local_set(&cpu_buffer->pages_lost, 0);
+ local_set(&cpu_buffer->pages_read, 0);
+ cpu_buffer->last_pages_touch = 0;
+ cpu_buffer->shortest_full = 0;
+diff --git a/kernel/trace/synth_event_gen_test.c b/kernel/trace/synth_event_gen_test.c
+index 0b15e975d2c2c..8d77526892f45 100644
+--- a/kernel/trace/synth_event_gen_test.c
++++ b/kernel/trace/synth_event_gen_test.c
+@@ -120,15 +120,13 @@ static int __init test_gen_synth_cmd(void)
+
+ /* Now generate a gen_synth_test event */
+ ret = synth_event_trace_array(gen_synth_test, vals, ARRAY_SIZE(vals));
+- out:
++ free:
++ kfree(buf);
+ return ret;
+ delete:
+ /* We got an error after creating the event, delete it */
+ synth_event_delete("gen_synth_test");
+- free:
+- kfree(buf);
+-
+- goto out;
++ goto free;
+ }
+
+ /*
+@@ -227,15 +225,13 @@ static int __init test_empty_synth_event(void)
+
+ /* Now trace an empty_synth_test event */
+ ret = synth_event_trace_array(empty_synth_test, vals, ARRAY_SIZE(vals));
+- out:
++ free:
++ kfree(buf);
+ return ret;
+ delete:
+ /* We got an error after creating the event, delete it */
+ synth_event_delete("empty_synth_test");
+- free:
+- kfree(buf);
+-
+- goto out;
++ goto free;
+ }
+
+ static struct synth_field_desc create_synth_test_fields[] = {
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index cc65887b31bd9..7132e21e90d6d 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -6657,6 +6657,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
+ mutex_unlock(&trace_types_lock);
+
+ free_cpumask_var(iter->started);
++ kfree(iter->fmt);
+ mutex_destroy(&iter->mutex);
+ kfree(iter);
+
+@@ -6681,7 +6682,7 @@ trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_tabl
+ return EPOLLIN | EPOLLRDNORM;
+ else
+ return ring_buffer_poll_wait(iter->array_buffer->buffer, iter->cpu_file,
+- filp, poll_table);
++ filp, poll_table, iter->tr->buffer_percent);
+ }
+
+ static __poll_t
+@@ -7802,6 +7803,7 @@ static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr,
+ int len)
+ {
+ struct tracing_log_err *err;
++ char *cmd;
+
+ if (tr->n_err_log_entries < TRACING_LOG_ERRS_MAX) {
+ err = alloc_tracing_log_err(len);
+@@ -7810,12 +7812,12 @@ static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr,
+
+ return err;
+ }
+-
++ cmd = kzalloc(len, GFP_KERNEL);
++ if (!cmd)
++ return ERR_PTR(-ENOMEM);
+ err = list_first_entry(&tr->err_log, struct tracing_log_err, list);
+ kfree(err->cmd);
+- err->cmd = kzalloc(len, GFP_KERNEL);
+- if (!err->cmd)
+- return ERR_PTR(-ENOMEM);
++ err->cmd = cmd;
+ list_del(&err->list);
+
+ return err;
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 860f5fb9514d7..3b055aaee89a9 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -560,6 +560,9 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
+ {
+ struct eprobe_data *edata = data->private_data;
+
++ if (unlikely(!rec))
++ return;
++
+ __eprobe_trace_func(edata, rec);
+ }
+
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index e310052dc83ce..29fbfb27c2b2c 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -828,10 +828,9 @@ static int register_synth_event(struct synth_event *event)
+ }
+
+ ret = set_synth_event_print_fmt(call);
+- if (ret < 0) {
++ /* unregister_trace_event() will be called inside */
++ if (ret < 0)
+ trace_remove_event_call(call);
+- goto err;
+- }
+ out:
+ return ret;
+ err:
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 15800334147b3..ada25b9f45ad1 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -3712,7 +3712,7 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
+ unsigned long offset; /* Offset into pagecache page */
+ unsigned long bytes; /* Bytes to write to page */
+ size_t copied; /* Bytes copied from user */
+- void *fsdata;
++ void *fsdata = NULL;
+
+ offset = (pos & (PAGE_SIZE - 1));
+ bytes = min_t(unsigned long, PAGE_SIZE - offset,
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index ecc197d24efb7..dbb558e71e9e1 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5445,7 +5445,7 @@ static bool hugetlbfs_pagecache_present(struct hstate *h,
+ return page != NULL;
+ }
+
+-int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
++int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping,
+ pgoff_t idx)
+ {
+ struct folio *folio = page_folio(page);
+@@ -5583,7 +5583,7 @@ retry:
+ new_page = true;
+
+ if (vma->vm_flags & VM_MAYSHARE) {
+- int err = huge_add_to_page_cache(page, mapping, idx);
++ int err = hugetlb_add_to_page_cache(page, mapping, idx);
+ if (err) {
+ put_page(page);
+ if (err == -EEXIST)
+@@ -6008,11 +6008,11 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+
+ /*
+ * Serialization between remove_inode_hugepages() and
+- * huge_add_to_page_cache() below happens through the
++ * hugetlb_add_to_page_cache() below happens through the
+ * hugetlb_fault_mutex_table that here must be hold by
+ * the caller.
+ */
+- ret = huge_add_to_page_cache(page, mapping, idx);
++ ret = hugetlb_add_to_page_cache(page, mapping, idx);
+ if (ret)
+ goto out_release_nounlock;
+ page_in_pagecache = true;
+@@ -6021,6 +6021,10 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+ ptl = huge_pte_lockptr(h, dst_mm, dst_pte);
+ spin_lock(ptl);
+
++ ret = -EIO;
++ if (PageHWPoison(page))
++ goto out_release_unlock;
++
+ /*
+ * Recheck the i_size after holding PT lock to make sure not
+ * to leave any page mapped (as page_mapped()) beyond the end
+diff --git a/mm/maccess.c b/mm/maccess.c
+index 5f4d240f67ecc..074f6b086671e 100644
+--- a/mm/maccess.c
++++ b/mm/maccess.c
+@@ -97,7 +97,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
+ return src - unsafe_addr;
+ Efault:
+ pagefault_enable();
+- dst[-1] = '\0';
++ dst[0] = '\0';
+ return -EFAULT;
+ }
+
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index e7ac570dda75d..4d302f6b02fc7 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1079,6 +1079,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ int res;
+ struct page *hpage = compound_head(p);
+ struct address_space *mapping;
++ bool extra_pins = false;
+
+ if (!PageHuge(hpage))
+ return MF_DELAYED;
+@@ -1086,6 +1087,8 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ mapping = page_mapping(hpage);
+ if (mapping) {
+ res = truncate_error_page(hpage, page_to_pfn(p), mapping);
++ /* The page is kept in page cache. */
++ extra_pins = true;
+ unlock_page(hpage);
+ } else {
+ unlock_page(hpage);
+@@ -1103,7 +1106,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ }
+ }
+
+- if (has_extra_refcount(ps, p, false))
++ if (has_extra_refcount(ps, p, extra_pins))
+ res = MF_FAILED;
+
+ return res;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index e758978b44bee..0191f22d1ec35 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -91,6 +91,7 @@ struct p9_poll_wait {
+ * @mux_list: list link for mux to manage multiple connections (?)
+ * @client: reference to client instance for this connection
+ * @err: error state
++ * @req_lock: lock protecting req_list and requests statuses
+ * @req_list: accounting for requests which have been sent
+ * @unsent_req_list: accounting for requests that haven't been sent
+ * @rreq: read request
+@@ -114,6 +115,7 @@ struct p9_conn {
+ struct list_head mux_list;
+ struct p9_client *client;
+ int err;
++ spinlock_t req_lock;
+ struct list_head req_list;
+ struct list_head unsent_req_list;
+ struct p9_req_t *rreq;
+@@ -189,10 +191,10 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+
+ p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
+
+- spin_lock(&m->client->lock);
++ spin_lock(&m->req_lock);
+
+ if (m->err) {
+- spin_unlock(&m->client->lock);
++ spin_unlock(&m->req_lock);
+ return;
+ }
+
+@@ -205,6 +207,8 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ list_move(&req->req_list, &cancel_list);
+ }
+
++ spin_unlock(&m->req_lock);
++
+ list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
+ p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
+ list_del(&req->req_list);
+@@ -212,7 +216,6 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ req->t_err = err;
+ p9_client_cb(m->client, req, REQ_STATUS_ERROR);
+ }
+- spin_unlock(&m->client->lock);
+ }
+
+ static __poll_t
+@@ -359,7 +362,7 @@ static void p9_read_work(struct work_struct *work)
+ if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
+ p9_debug(P9_DEBUG_TRANS, "got new packet\n");
+ m->rreq->rc.size = m->rc.offset;
+- spin_lock(&m->client->lock);
++ spin_lock(&m->req_lock);
+ if (m->rreq->status == REQ_STATUS_SENT) {
+ list_del(&m->rreq->req_list);
+ p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
+@@ -368,14 +371,14 @@ static void p9_read_work(struct work_struct *work)
+ p9_debug(P9_DEBUG_TRANS,
+ "Ignore replies associated with a cancelled request\n");
+ } else {
+- spin_unlock(&m->client->lock);
++ spin_unlock(&m->req_lock);
+ p9_debug(P9_DEBUG_ERROR,
+ "Request tag %d errored out while we were reading the reply\n",
+ m->rc.tag);
+ err = -EIO;
+ goto error;
+ }
+- spin_unlock(&m->client->lock);
++ spin_unlock(&m->req_lock);
+ m->rc.sdata = NULL;
+ m->rc.offset = 0;
+ m->rc.capacity = 0;
+@@ -453,10 +456,10 @@ static void p9_write_work(struct work_struct *work)
+ }
+
+ if (!m->wsize) {
+- spin_lock(&m->client->lock);
++ spin_lock(&m->req_lock);
+ if (list_empty(&m->unsent_req_list)) {
+ clear_bit(Wworksched, &m->wsched);
+- spin_unlock(&m->client->lock);
++ spin_unlock(&m->req_lock);
+ return;
+ }
+
+@@ -471,7 +474,7 @@ static void p9_write_work(struct work_struct *work)
+ m->wpos = 0;
+ p9_req_get(req);
+ m->wreq = req;
+- spin_unlock(&m->client->lock);
++ spin_unlock(&m->req_lock);
+ }
+
+ p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
+@@ -588,6 +591,7 @@ static void p9_conn_create(struct p9_client *client)
+ INIT_LIST_HEAD(&m->mux_list);
+ m->client = client;
+
++ spin_lock_init(&m->req_lock);
+ INIT_LIST_HEAD(&m->req_list);
+ INIT_LIST_HEAD(&m->unsent_req_list);
+ INIT_WORK(&m->rq, p9_read_work);
+@@ -669,10 +673,10 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+ if (m->err < 0)
+ return m->err;
+
+- spin_lock(&client->lock);
++ spin_lock(&m->req_lock);
+ req->status = REQ_STATUS_UNSENT;
+ list_add_tail(&req->req_list, &m->unsent_req_list);
+- spin_unlock(&client->lock);
++ spin_unlock(&m->req_lock);
+
+ if (test_and_clear_bit(Wpending, &m->wsched))
+ n = EPOLLOUT;
+@@ -687,11 +691,13 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+
+ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ {
++ struct p9_trans_fd *ts = client->trans;
++ struct p9_conn *m = &ts->conn;
+ int ret = 1;
+
+ p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
+
+- spin_lock(&client->lock);
++ spin_lock(&m->req_lock);
+
+ if (req->status == REQ_STATUS_UNSENT) {
+ list_del(&req->req_list);
+@@ -699,21 +705,24 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ p9_req_put(client, req);
+ ret = 0;
+ }
+- spin_unlock(&client->lock);
++ spin_unlock(&m->req_lock);
+
+ return ret;
+ }
+
+ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ {
++ struct p9_trans_fd *ts = client->trans;
++ struct p9_conn *m = &ts->conn;
++
+ p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
+
+- spin_lock(&client->lock);
++ spin_lock(&m->req_lock);
+ /* Ignore cancelled request if message has been received
+ * before lock.
+ */
+ if (req->status == REQ_STATUS_RCVD) {
+- spin_unlock(&client->lock);
++ spin_unlock(&m->req_lock);
+ return 0;
+ }
+
+@@ -722,7 +731,8 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ */
+ list_del(&req->req_list);
+ req->status = REQ_STATUS_FLSHD;
+- spin_unlock(&client->lock);
++ spin_unlock(&m->req_lock);
++
+ p9_req_put(client, req);
+
+ return 0;
+@@ -821,11 +831,14 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
+ goto out_free_ts;
+ if (!(ts->rd->f_mode & FMODE_READ))
+ goto out_put_rd;
++ /* prevent workers from hanging on IO when fd is a pipe */
++ ts->rd->f_flags |= O_NONBLOCK;
+ ts->wr = fget(wfd);
+ if (!ts->wr)
+ goto out_put_rd;
+ if (!(ts->wr->f_mode & FMODE_WRITE))
+ goto out_put_wr;
++ ts->wr->f_flags |= O_NONBLOCK;
+
+ client->trans = ts;
+ client->status = Connected;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 4df3d0ed6c80d..9c24947aa41ef 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1990,7 +1990,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
+ if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
+ continue;
+
+- if (c->psm == psm) {
++ if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) {
+ int src_match, dst_match;
+ int src_any, dst_any;
+
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index d11209367dd00..b422238f9f86c 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -733,6 +733,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
+ if (user_size > size)
+ return ERR_PTR(-EMSGSIZE);
+
++ size = SKB_DATA_ALIGN(size);
+ data = kzalloc(size + headroom + tailroom, GFP_USER);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index 6e53dc9914094..9ffd40b8270c1 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -959,6 +959,8 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+ list_for_each_entry(p, &br->port_list, list) {
+ vg = nbp_vlan_group(p);
+ list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++ if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++ continue;
+ err = vlan_vid_add(p->dev, proto, vlan->vid);
+ if (err)
+ goto err_filt;
+@@ -973,8 +975,11 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+ /* Delete VLANs for the old proto from the device filter. */
+ list_for_each_entry(p, &br->port_list, list) {
+ vg = nbp_vlan_group(p);
+- list_for_each_entry(vlan, &vg->vlan_list, vlist)
++ list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++ if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++ continue;
+ vlan_vid_del(p->dev, oldproto, vlan->vid);
++ }
+ }
+
+ return 0;
+@@ -983,13 +988,19 @@ err_filt:
+ attr.u.vlan_protocol = ntohs(oldproto);
+ switchdev_port_attr_set(br->dev, &attr, NULL);
+
+- list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist)
++ list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) {
++ if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++ continue;
+ vlan_vid_del(p->dev, proto, vlan->vid);
++ }
+
+ list_for_each_entry_continue_reverse(p, &br->port_list, list) {
+ vg = nbp_vlan_group(p);
+- list_for_each_entry(vlan, &vg->vlan_list, vlist)
++ list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++ if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++ continue;
+ vlan_vid_del(p->dev, proto, vlan->vid);
++ }
+ }
+
+ return err;
+diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
+index 4d63ef13a1fd7..f35fc87c453a2 100644
+--- a/net/caif/chnl_net.c
++++ b/net/caif/chnl_net.c
+@@ -310,9 +310,6 @@ static int chnl_net_open(struct net_device *dev)
+
+ if (result == 0) {
+ pr_debug("connect timeout\n");
+- caif_disconnect_client(dev_net(dev), &priv->chnl);
+- priv->state = CAIF_DISCONNECTED;
+- pr_debug("state disconnected\n");
+ result = -ETIMEDOUT;
+ goto error;
+ }
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index e537655e442b8..befa954b0a472 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -850,6 +850,14 @@ disconnect:
+ return err;
+ }
+
++static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds)
++{
++ const struct dsa_device_ops *tag_ops = ds->dst->tag_ops;
++
++ if (tag_ops->disconnect)
++ tag_ops->disconnect(ds);
++}
++
+ static int dsa_switch_setup(struct dsa_switch *ds)
+ {
+ struct dsa_devlink_priv *dl_priv;
+@@ -953,6 +961,8 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
+ ds->slave_mii_bus = NULL;
+ }
+
++ dsa_switch_teardown_tag_protocol(ds);
++
+ if (ds->ops->teardown)
+ ds->ops->teardown(ds);
+
+diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
+index d9722e49864b0..acea875c05e5c 100644
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -201,6 +201,7 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
+ }
+
+ /* port.c */
++bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr);
+ void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp,
+ const struct dsa_device_ops *tag_ops);
+ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age);
+diff --git a/net/dsa/master.c b/net/dsa/master.c
+index 2851e44c4cf0d..46b1f0455a7bd 100644
+--- a/net/dsa/master.c
++++ b/net/dsa/master.c
+@@ -204,8 +204,7 @@ static int dsa_master_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ * switch in the tree that is PTP capable.
+ */
+ list_for_each_entry(dp, &dst->ports, list)
+- if (dp->ds->ops->port_hwtstamp_get ||
+- dp->ds->ops->port_hwtstamp_set)
++ if (dsa_port_supports_hwtstamp(dp, ifr))
+ return -EBUSY;
+ break;
+ }
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index a8895ee3cd600..9ac87063cca8a 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -109,6 +109,22 @@ static bool dsa_port_can_configure_learning(struct dsa_port *dp)
+ return !err;
+ }
+
++bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr)
++{
++ struct dsa_switch *ds = dp->ds;
++ int err;
++
++ if (!ds->ops->port_hwtstamp_get || !ds->ops->port_hwtstamp_set)
++ return false;
++
++ /* "See through" shim implementations of the "get" method.
++ * This will clobber the ifreq structure, but we will either return an
++ * error, or the master will overwrite it with proper values.
++ */
++ err = ds->ops->port_hwtstamp_get(ds, dp->index, ifr);
++ return err != -EOPNOTSUPP;
++}
++
+ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age)
+ {
+ struct dsa_switch *ds = dp->ds;
+diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c
+index ddc7ba0554bdd..112f28f936934 100644
+--- a/net/ipv4/tcp_cdg.c
++++ b/net/ipv4/tcp_cdg.c
+@@ -375,6 +375,7 @@ static void tcp_cdg_init(struct sock *sk)
+ struct cdg *ca = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+
++ ca->gradients = NULL;
+ /* We silently fall back to window = 1 if allocation fails. */
+ if (window > 1)
+ ca->gradients = kcalloc(window, sizeof(ca->gradients[0]),
+@@ -388,6 +389,7 @@ static void tcp_cdg_release(struct sock *sk)
+ struct cdg *ca = inet_csk_ca(sk);
+
+ kfree(ca->gradients);
++ ca->gradients = NULL;
+ }
+
+ static struct tcp_congestion_ops tcp_cdg __read_mostly = {
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index befc62606cdf0..890a2423f559e 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -222,7 +222,7 @@ static void requeue_rx_msgs(struct kcm_mux *mux, struct sk_buff_head *head)
+ struct sk_buff *skb;
+ struct kcm_sock *kcm;
+
+- while ((skb = __skb_dequeue(head))) {
++ while ((skb = skb_dequeue(head))) {
+ /* Reset destructor to avoid calling kcm_rcv_ready */
+ skb->destructor = sock_rfree;
+ skb_orphan(skb);
+@@ -1085,53 +1085,17 @@ out_error:
+ return err;
+ }
+
+-static struct sk_buff *kcm_wait_data(struct sock *sk, int flags,
+- long timeo, int *err)
+-{
+- struct sk_buff *skb;
+-
+- while (!(skb = skb_peek(&sk->sk_receive_queue))) {
+- if (sk->sk_err) {
+- *err = sock_error(sk);
+- return NULL;
+- }
+-
+- if (sock_flag(sk, SOCK_DONE))
+- return NULL;
+-
+- if ((flags & MSG_DONTWAIT) || !timeo) {
+- *err = -EAGAIN;
+- return NULL;
+- }
+-
+- sk_wait_data(sk, &timeo, NULL);
+-
+- /* Handle signals */
+- if (signal_pending(current)) {
+- *err = sock_intr_errno(timeo);
+- return NULL;
+- }
+- }
+-
+- return skb;
+-}
+-
+ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg,
+ size_t len, int flags)
+ {
+ struct sock *sk = sock->sk;
+ struct kcm_sock *kcm = kcm_sk(sk);
+ int err = 0;
+- long timeo;
+ struct strp_msg *stm;
+ int copied = 0;
+ struct sk_buff *skb;
+
+- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+-
+- lock_sock(sk);
+-
+- skb = kcm_wait_data(sk, flags, timeo, &err);
++ skb = skb_recv_datagram(sk, flags, &err);
+ if (!skb)
+ goto out;
+
+@@ -1162,14 +1126,11 @@ msg_finished:
+ /* Finished with message */
+ msg->msg_flags |= MSG_EOR;
+ KCM_STATS_INCR(kcm->stats.rx_msgs);
+- skb_unlink(skb, &sk->sk_receive_queue);
+- kfree_skb(skb);
+ }
+ }
+
+ out:
+- release_sock(sk);
+-
++ skb_free_datagram(sk, skb);
+ return copied ? : err;
+ }
+
+@@ -1179,7 +1140,6 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+ {
+ struct sock *sk = sock->sk;
+ struct kcm_sock *kcm = kcm_sk(sk);
+- long timeo;
+ struct strp_msg *stm;
+ int err = 0;
+ ssize_t copied;
+@@ -1187,11 +1147,7 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+
+ /* Only support splice for SOCKSEQPACKET */
+
+- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+-
+- lock_sock(sk);
+-
+- skb = kcm_wait_data(sk, flags, timeo, &err);
++ skb = skb_recv_datagram(sk, flags, &err);
+ if (!skb)
+ goto err_out;
+
+@@ -1219,13 +1175,11 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+ * finish reading the message.
+ */
+
+- release_sock(sk);
+-
++ skb_free_datagram(sk, skb);
+ return copied;
+
+ err_out:
+- release_sock(sk);
+-
++ skb_free_datagram(sk, skb);
+ return err;
+ }
+
+@@ -1845,10 +1799,10 @@ static int kcm_release(struct socket *sock)
+ kcm = kcm_sk(sk);
+ mux = kcm->mux;
+
++ lock_sock(sk);
+ sock_orphan(sk);
+ kfree_skb(kcm->seq_skb);
+
+- lock_sock(sk);
+ /* Purge queue under lock to avoid race condition with tx_work trying
+ * to act when queue is nonempty. If tx_work runs after this point
+ * it will just return.
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 16ae92054baa8..6b31746f9be3b 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1719,11 +1719,13 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+ skb2 = nlmsg_new(payload, GFP_KERNEL);
+ if (!skb2)
+ return -ENOMEM;
+- rep = __nlmsg_put(skb2, NETLINK_CB(skb).portid,
+- nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
++ rep = nlmsg_put(skb2, NETLINK_CB(skb).portid,
++ nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
+ errmsg = nlmsg_data(rep);
+ errmsg->error = ret;
+- memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
++ unsafe_memcpy(&errmsg->msg, nlh, nlh->nlmsg_len,
++ /* Bounds checked by the skb layer. */);
++
+ cmdattr = (void *)&errmsg->msg + min_len;
+
+ ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr,
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 0cd91f813a3bd..d8d3ed2096a31 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2440,11 +2440,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ return;
+ }
+
+- rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
+- NLMSG_ERROR, payload, flags);
++ rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
++ NLMSG_ERROR, payload, flags);
+ errmsg = nlmsg_data(rep);
+ errmsg->error = err;
+- memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
++ unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg)
++ ? nlh->nlmsg_len : sizeof(*nlh),
++ /* Bounds checked by the skb layer. */);
+
+ if (nlk_has_extack && extack) {
+ if (extack->_msg) {
+diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
+index e213aaf45d67c..20831079fb09e 100644
+--- a/net/sctp/outqueue.c
++++ b/net/sctp/outqueue.c
+@@ -384,6 +384,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
+ {
+ struct sctp_outq *q = &asoc->outqueue;
+ struct sctp_chunk *chk, *temp;
++ struct sctp_stream_out *sout;
+
+ q->sched->unsched_all(&asoc->stream);
+
+@@ -398,12 +399,14 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
+ sctp_sched_dequeue_common(q, chk);
+ asoc->sent_cnt_removable--;
+ asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+- if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
+- struct sctp_stream_out *streamout =
+- SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
+
+- streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+- }
++ sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
++ sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
++
++ /* clear out_curr if all frag chunks are pruned */
++ if (asoc->stream.out_curr == sout &&
++ list_is_last(&chk->frag_list, &chk->msg->chunks))
++ asoc->stream.out_curr = NULL;
+
+ msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
+ sctp_chunk_free(chk);
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index a31a27816cc0f..7bb247c51e2f6 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -1989,7 +1989,7 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
+ goto unwrap_failed;
+ mic.len = len;
+ mic.data = kmalloc(len, GFP_KERNEL);
+- if (!mic.data)
++ if (ZERO_OR_NULL_PTR(mic.data))
+ goto unwrap_failed;
+ if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len))
+ goto unwrap_failed;
+diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
+index 76a80a41615be..fe8765c4075d3 100644
+--- a/net/wireless/wext-core.c
++++ b/net/wireless/wext-core.c
+@@ -468,6 +468,7 @@ void wireless_send_event(struct net_device * dev,
+ struct __compat_iw_event *compat_event;
+ struct compat_iw_point compat_wrqu;
+ struct sk_buff *compskb;
++ int ptr_len;
+ #endif
+
+ /*
+@@ -582,6 +583,9 @@ void wireless_send_event(struct net_device * dev,
+ nlmsg_end(skb, nlh);
+ #ifdef CONFIG_COMPAT
+ hdr_len = compat_event_type_size[descr->header_type];
++
++ /* ptr_len is remaining size in event header apart from LCP */
++ ptr_len = hdr_len - IW_EV_COMPAT_LCP_LEN;
+ event_len = hdr_len + extra_len;
+
+ compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+@@ -612,16 +616,15 @@ void wireless_send_event(struct net_device * dev,
+ if (descr->header_type == IW_HEADER_TYPE_POINT) {
+ compat_wrqu.length = wrqu->data.length;
+ compat_wrqu.flags = wrqu->data.flags;
+- memcpy(&compat_event->pointer,
+- ((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
+- hdr_len - IW_EV_COMPAT_LCP_LEN);
++ memcpy(compat_event->ptr_bytes,
++ ((char *)&compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
++ ptr_len);
+ if (extra_len)
+- memcpy(((char *) compat_event) + hdr_len,
+- extra, extra_len);
++ memcpy(&compat_event->ptr_bytes[ptr_len],
++ extra, extra_len);
+ } else {
+ /* extra_len must be zero, so no if (extra) needed */
+- memcpy(&compat_event->pointer, wrqu,
+- hdr_len - IW_EV_COMPAT_LCP_LEN);
++ memcpy(compat_event->ptr_bytes, wrqu, ptr_len);
+ }
+
+ nlmsg_end(compskb, nlh);
+diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
+index 5259ef8f5242f..748d8630ab58b 100644
+--- a/net/x25/x25_dev.c
++++ b/net/x25/x25_dev.c
+@@ -117,7 +117,7 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
+
+ if (!pskb_may_pull(skb, 1)) {
+ x25_neigh_put(nb);
+- return 0;
++ goto drop;
+ }
+
+ switch (skb->data[0]) {
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b7cccbef401ce..bf58e98c7a699 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9446,6 +9446,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP),
+ SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP),
+ SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
++ SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP),
++ SND_PCI_QUIRK(0x144d, 0xc1a6, "Samsung Galaxy Book Pro 360 (NP930QBD)", ALC298_FIXUP_SAMSUNG_AMP),
+ SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
+ SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
+ SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 2cb50d5cf1a9a..6c0f1de10429a 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = {
+ };
+
+ static const struct dmi_system_id yc_acp_quirk_table[] = {
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
++ }
++ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
++ }
++ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+diff --git a/sound/soc/codecs/jz4725b.c b/sound/soc/codecs/jz4725b.c
+index 5201a8f6d7b63..71ea576f7e67a 100644
+--- a/sound/soc/codecs/jz4725b.c
++++ b/sound/soc/codecs/jz4725b.c
+@@ -136,14 +136,17 @@ enum {
+ #define REG_CGR3_GO1L_OFFSET 0
+ #define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET)
+
++#define REG_CGR10_GIL_OFFSET 0
++#define REG_CGR10_GIR_OFFSET 4
++
+ struct jz_icdc {
+ struct regmap *regmap;
+ void __iomem *base;
+ struct clk *clk;
+ };
+
+-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0);
+-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600);
++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0);
++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
+
+ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
+ SOC_DOUBLE_TLV("Master Playback Volume",
+@@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
+ REG_CGR1_GODL_OFFSET,
+ REG_CGR1_GODR_OFFSET,
+ 0xf, 1, jz4725b_dac_tlv),
+- SOC_DOUBLE_R_TLV("Master Capture Volume",
+- JZ4725B_CODEC_REG_CGR3,
+- JZ4725B_CODEC_REG_CGR2,
+- REG_CGR2_GO1R_OFFSET,
+- 0x1f, 1, jz4725b_line_tlv),
++ SOC_DOUBLE_TLV("Master Capture Volume",
++ JZ4725B_CODEC_REG_CGR10,
++ REG_CGR10_GIL_OFFSET,
++ REG_CGR10_GIR_OFFSET,
++ 0xf, 0, jz4725b_adc_tlv),
+
+ SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
+ REG_CR1_DAC_MUTE_OFFSET, 1, 1),
+@@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
+ jz4725b_codec_adc_src_texts,
+ jz4725b_codec_adc_src_values);
+ static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
+- SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum);
++ SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
+
+ static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
+@@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
+ SND_SOC_DAPM_ADC("ADC", "Capture",
+ JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
+
+- SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0,
++ SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
+ &jz4725b_codec_adc_src_ctrl),
+
+ /* Mixer */
+@@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
+ REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
+
+- SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0),
++ SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
++ REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
+ SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
+ REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
+
+@@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
+ {"Mixer", NULL, "DAC to Mixer"},
+
+ {"Mixer to ADC", NULL, "Mixer"},
+- {"ADC Source", "Mixer", "Mixer to ADC"},
+- {"ADC Source", "Line In", "Line In"},
+- {"ADC Source", "Mic 1", "Mic 1"},
+- {"ADC Source", "Mic 2", "Mic 2"},
+- {"ADC", NULL, "ADC Source"},
++ {"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
++ {"ADC Source Capture Route", "Line In", "Line In"},
++ {"ADC Source Capture Route", "Mic 1", "Mic 1"},
++ {"ADC Source Capture Route", "Mic 2", "Mic 2"},
++ {"ADC", NULL, "ADC Source Capture Route"},
+
+ {"Out Stage", NULL, "Mixer"},
+ {"HP Out", NULL, "Out Stage"},
+diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c
+index 45e0df13afb9f..b8369eeccc302 100644
+--- a/sound/soc/codecs/mt6660.c
++++ b/sound/soc/codecs/mt6660.c
+@@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
+ dev_err(chip->dev, "read chip revision fail\n");
+ goto probe_fail;
+ }
++ pm_runtime_set_active(chip->dev);
++ pm_runtime_enable(chip->dev);
+
+ ret = devm_snd_soc_register_component(chip->dev,
+ &mt6660_component_driver,
+ &mt6660_codec_dai, 1);
+- if (!ret) {
+- pm_runtime_set_active(chip->dev);
+- pm_runtime_enable(chip->dev);
+- }
++ if (ret)
++ pm_runtime_disable(chip->dev);
+
+ return ret;
+
+diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c
+index b66bfecbb879b..49f527c61a7ad 100644
+--- a/sound/soc/codecs/rt1019.c
++++ b/sound/soc/codecs/rt1019.c
+@@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+ {
+ struct snd_soc_component *component = dai->component;
+- unsigned int val = 0, rx_slotnum;
++ unsigned int cn = 0, cl = 0, rx_slotnum;
+ int ret = 0, first_bit;
+
+ switch (slots) {
+ case 4:
+- val |= RT1019_I2S_TX_4CH;
++ cn = RT1019_I2S_TX_4CH;
+ break;
+ case 6:
+- val |= RT1019_I2S_TX_6CH;
++ cn = RT1019_I2S_TX_6CH;
+ break;
+ case 8:
+- val |= RT1019_I2S_TX_8CH;
++ cn = RT1019_I2S_TX_8CH;
+ break;
+ case 2:
+ break;
+@@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+
+ switch (slot_width) {
+ case 20:
+- val |= RT1019_I2S_DL_20;
++ cl = RT1019_TDM_CL_20;
+ break;
+ case 24:
+- val |= RT1019_I2S_DL_24;
++ cl = RT1019_TDM_CL_24;
+ break;
+ case 32:
+- val |= RT1019_I2S_DL_32;
++ cl = RT1019_TDM_CL_32;
+ break;
+ case 8:
+- val |= RT1019_I2S_DL_8;
++ cl = RT1019_TDM_CL_8;
+ break;
+ case 16:
+ break;
+@@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ goto _set_tdm_err_;
+ }
+
++ snd_soc_component_update_bits(component, RT1019_TDM_1,
++ RT1019_TDM_CL_MASK, cl);
+ snd_soc_component_update_bits(component, RT1019_TDM_2,
+- RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val);
++ RT1019_I2S_CH_TX_MASK, cn);
+
+ _set_tdm_err_:
+ return ret;
+diff --git a/sound/soc/codecs/rt1019.h b/sound/soc/codecs/rt1019.h
+index 64df831eeb720..48ba15efb48dd 100644
+--- a/sound/soc/codecs/rt1019.h
++++ b/sound/soc/codecs/rt1019.h
+@@ -95,6 +95,12 @@
+ #define RT1019_TDM_BCLK_MASK (0x1 << 6)
+ #define RT1019_TDM_BCLK_NORM (0x0 << 6)
+ #define RT1019_TDM_BCLK_INV (0x1 << 6)
++#define RT1019_TDM_CL_MASK (0x7)
++#define RT1019_TDM_CL_8 (0x4)
++#define RT1019_TDM_CL_32 (0x3)
++#define RT1019_TDM_CL_24 (0x2)
++#define RT1019_TDM_CL_20 (0x1)
++#define RT1019_TDM_CL_16 (0x0)
+
+ /* 0x0401 TDM Control-2 */
+ #define RT1019_I2S_CH_TX_MASK (0x3 << 6)
+diff --git a/sound/soc/codecs/rt1308-sdw.h b/sound/soc/codecs/rt1308-sdw.h
+index 6668e19d85d46..b5f231f708cba 100644
+--- a/sound/soc/codecs/rt1308-sdw.h
++++ b/sound/soc/codecs/rt1308-sdw.h
+@@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
+ { 0x3005, 0x23 },
+ { 0x3008, 0x02 },
+ { 0x300a, 0x00 },
++ { 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
+ { 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
+ { 0xc000 | (RT1308_POWER << 4), 0x00 },
+ { 0xc001 | (RT1308_POWER << 4), 0x00 },
+ { 0xc002 | (RT1308_POWER << 4), 0x00 },
++ { 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
+ };
+
+ #define RT1308_SDW_OFFSET 0xc000
+diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
+index 1a25a37879356..362663abcb89e 100644
+--- a/sound/soc/codecs/rt5514-spi.c
++++ b/sound/soc/codecs/rt5514-spi.c
+@@ -298,13 +298,14 @@ static int rt5514_spi_pcm_new(struct snd_soc_component *component,
+ }
+
+ static const struct snd_soc_component_driver rt5514_spi_component = {
+- .name = DRV_NAME,
+- .probe = rt5514_spi_pcm_probe,
+- .open = rt5514_spi_pcm_open,
+- .hw_params = rt5514_spi_hw_params,
+- .hw_free = rt5514_spi_hw_free,
+- .pointer = rt5514_spi_pcm_pointer,
+- .pcm_construct = rt5514_spi_pcm_new,
++ .name = DRV_NAME,
++ .probe = rt5514_spi_pcm_probe,
++ .open = rt5514_spi_pcm_open,
++ .hw_params = rt5514_spi_hw_params,
++ .hw_free = rt5514_spi_hw_free,
++ .pointer = rt5514_spi_pcm_pointer,
++ .pcm_construct = rt5514_spi_pcm_new,
++ .legacy_dai_naming = 1,
+ };
+
+ /**
+diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
+index 8f3993a4c1cc7..d25703dd74996 100644
+--- a/sound/soc/codecs/rt5677-spi.c
++++ b/sound/soc/codecs/rt5677-spi.c
+@@ -396,15 +396,16 @@ static int rt5677_spi_pcm_probe(struct snd_soc_component *component)
+ }
+
+ static const struct snd_soc_component_driver rt5677_spi_dai_component = {
+- .name = DRV_NAME,
+- .probe = rt5677_spi_pcm_probe,
+- .open = rt5677_spi_pcm_open,
+- .close = rt5677_spi_pcm_close,
+- .hw_params = rt5677_spi_hw_params,
+- .hw_free = rt5677_spi_hw_free,
+- .prepare = rt5677_spi_prepare,
+- .pointer = rt5677_spi_pcm_pointer,
+- .pcm_construct = rt5677_spi_pcm_new,
++ .name = DRV_NAME,
++ .probe = rt5677_spi_pcm_probe,
++ .open = rt5677_spi_pcm_open,
++ .close = rt5677_spi_pcm_close,
++ .hw_params = rt5677_spi_hw_params,
++ .hw_free = rt5677_spi_hw_free,
++ .prepare = rt5677_spi_prepare,
++ .pointer = rt5677_spi_pcm_pointer,
++ .pcm_construct = rt5677_spi_pcm_new,
++ .legacy_dai_naming = 1,
+ };
+
+ /* Select a suitable transfer command for the next transfer to ensure
+diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c
+index eb47e7cd485aa..95fe993d59cb1 100644
+--- a/sound/soc/codecs/rt5682s.c
++++ b/sound/soc/codecs/rt5682s.c
+@@ -1932,7 +1932,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+ {
+ struct snd_soc_component *component = dai->component;
+- unsigned int cl, val = 0;
++ unsigned int cl, val = 0, tx_slotnum;
+
+ if (tx_mask || rx_mask)
+ snd_soc_component_update_bits(component,
+@@ -1941,6 +1941,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ snd_soc_component_update_bits(component,
+ RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0);
+
++ /* Tx slot configuration */
++ tx_slotnum = hweight_long(tx_mask);
++ if (tx_slotnum) {
++ if (tx_slotnum > slots) {
++ dev_err(component->dev, "Invalid or oversized Tx slots.\n");
++ return -EINVAL;
++ }
++ val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT;
++ }
++
+ switch (slots) {
+ case 4:
+ val |= RT5682S_TDM_TX_CH_4;
+@@ -1961,7 +1971,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ }
+
+ snd_soc_component_update_bits(component, RT5682S_TDM_CTRL,
+- RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val);
++ RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK |
++ RT5682S_TDM_ADC_DL_MASK, val);
+
+ switch (slot_width) {
+ case 8:
+diff --git a/sound/soc/codecs/rt5682s.h b/sound/soc/codecs/rt5682s.h
+index 7353831c73dd5..b660a311b6c21 100644
+--- a/sound/soc/codecs/rt5682s.h
++++ b/sound/soc/codecs/rt5682s.h
+@@ -899,6 +899,7 @@
+ #define RT5682S_TDM_RX_CH_8 (0x3 << 8)
+ #define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4)
+ #define RT5682S_TDM_ADC_LCA_SFT 4
++#define RT5682S_TDM_ADC_DL_MASK (0x3 << 0)
+ #define RT5682S_TDM_ADC_DL_SFT 0
+
+ /* TDM control 2 (0x007a) */
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 39902f77a2e0f..6c87c3cf5ef74 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -386,20 +386,13 @@ static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ if (tx_mask == 0 || rx_mask != 0)
+ return -EINVAL;
+
+- if (slots == 1) {
+- if (tx_mask != 1)
+- return -EINVAL;
+- left_slot = 0;
+- right_slot = 0;
++ left_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << left_slot);
++ if (tx_mask == 0) {
++ right_slot = left_slot;
+ } else {
+- left_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << left_slot);
+- if (tx_mask == 0) {
+- right_slot = left_slot;
+- } else {
+- right_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << right_slot);
+- }
++ right_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << right_slot);
+ }
+
+ if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
+index b6765235a4b3d..8557759acb1f2 100644
+--- a/sound/soc/codecs/tas2770.c
++++ b/sound/soc/codecs/tas2770.c
+@@ -395,21 +395,13 @@ static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ if (tx_mask == 0 || rx_mask != 0)
+ return -EINVAL;
+
+- if (slots == 1) {
+- if (tx_mask != 1)
+- return -EINVAL;
+-
+- left_slot = 0;
+- right_slot = 0;
++ left_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << left_slot);
++ if (tx_mask == 0) {
++ right_slot = left_slot;
+ } else {
+- left_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << left_slot);
+- if (tx_mask == 0) {
+- right_slot = left_slot;
+- } else {
+- right_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << right_slot);
+- }
++ right_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << right_slot);
+ }
+
+ if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/tas2780.c b/sound/soc/codecs/tas2780.c
+index a6db6f0e5431f..afdf0c863aa10 100644
+--- a/sound/soc/codecs/tas2780.c
++++ b/sound/soc/codecs/tas2780.c
+@@ -380,20 +380,13 @@ static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ if (tx_mask == 0 || rx_mask != 0)
+ return -EINVAL;
+
+- if (slots == 1) {
+- if (tx_mask != 1)
+- return -EINVAL;
+- left_slot = 0;
+- right_slot = 0;
++ left_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << left_slot);
++ if (tx_mask == 0) {
++ right_slot = left_slot;
+ } else {
+- left_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << left_slot);
+- if (tx_mask == 0) {
+- right_slot = left_slot;
+- } else {
+- right_slot = __ffs(tx_mask);
+- tx_mask &= ~(1 << right_slot);
+- }
++ right_slot = __ffs(tx_mask);
++ tx_mask &= ~(1 << right_slot);
+ }
+
+ if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
+index c09c9ac51b3e7..af7d324e33525 100644
+--- a/sound/soc/codecs/wm5102.c
++++ b/sound/soc/codecs/wm5102.c
+@@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
+ WM5102_DIG_VU, WM5102_DIG_VU);
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
+ wm5102);
+@@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
+index fc634c995834d..f3f4a10bf0f7c 100644
+--- a/sound/soc/codecs/wm5110.c
++++ b/sound/soc/codecs/wm5110.c
+@@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
+ WM5110_DIG_VU, WM5110_DIG_VU);
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
+ wm5110);
+@@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 398c448ea8540..6df06fba43778 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
+ 4, 1, 0, inmix_tlv),
+ };
+
++static int tp_event(struct snd_soc_dapm_widget *w,
++ struct snd_kcontrol *kcontrol, int event)
++{
++ int ret, reg, val, mask;
++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
++
++ ret = pm_runtime_resume_and_get(component->dev);
++ if (ret < 0) {
++ dev_err(component->dev, "Failed to resume device: %d\n", ret);
++ return ret;
++ }
++
++ reg = WM8962_ADDITIONAL_CONTROL_4;
++
++ if (!strcmp(w->name, "TEMP_HP")) {
++ mask = WM8962_TEMP_ENA_HP_MASK;
++ val = WM8962_TEMP_ENA_HP;
++ } else if (!strcmp(w->name, "TEMP_SPK")) {
++ mask = WM8962_TEMP_ENA_SPK_MASK;
++ val = WM8962_TEMP_ENA_SPK;
++ } else {
++ pm_runtime_put(component->dev);
++ return -EINVAL;
++ }
++
++ switch (event) {
++ case SND_SOC_DAPM_POST_PMD:
++ val = 0;
++ fallthrough;
++ case SND_SOC_DAPM_POST_PMU:
++ ret = snd_soc_component_update_bits(component, reg, mask, val);
++ break;
++ default:
++ WARN(1, "Invalid event %d\n", event);
++ pm_runtime_put(component->dev);
++ return -EINVAL;
++ }
++
++ pm_runtime_put(component->dev);
++
++ return 0;
++}
++
+ static int cp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
+ WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+-SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
+-SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
++SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
++ SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
++ SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
+ inpgal, ARRAY_SIZE(inpgal)),
+@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
+ if (ret < 0)
+ goto err_pm_runtime;
+
++ regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
++ WM8962_TEMP_ENA_HP_MASK, 0);
++ regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
++ WM8962_TEMP_ENA_SPK_MASK, 0);
++
+ regcache_cache_only(wm8962->regmap, true);
+
+ /* The drivers should power up as needed */
+diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
+index 77136a5216059..210ad662fc26d 100644
+--- a/sound/soc/codecs/wm8997.c
++++ b/sound/soc/codecs/wm8997.c
+@@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
+ regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
+ WM8997_DIG_VU, WM8997_DIG_VU);
+
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_idle(&pdev->dev);
++
+ arizona_init_common(arizona);
+
+ ret = arizona_init_vol_limit(arizona);
+@@ -1179,9 +1182,6 @@ static int wm8997_probe(struct platform_device *pdev)
+ goto err_spk_irqs;
+ }
+
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_idle(&pdev->dev);
+-
+ return ret;
+
+ err_spk_irqs:
+diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
+index aa5edf32d9889..d90adb6ee43d9 100644
+--- a/sound/soc/fsl/fsl_asrc.c
++++ b/sound/soc/fsl/fsl_asrc.c
+@@ -1224,7 +1224,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+ }
+
+ ret = pm_runtime_put_sync(&pdev->dev);
+- if (ret < 0)
++ if (ret < 0 && ret != -ENOSYS)
+ goto err_pm_get_sync;
+
+ ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
+diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
+index 5c21fc490fce1..17fefd27ec90a 100644
+--- a/sound/soc/fsl/fsl_esai.c
++++ b/sound/soc/fsl/fsl_esai.c
+@@ -1069,7 +1069,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
+ regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
+
+ ret = pm_runtime_put_sync(&pdev->dev);
+- if (ret < 0)
++ if (ret < 0 && ret != -ENOSYS)
+ goto err_pm_get_sync;
+
+ /*
+diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
+index d430eece1d6b1..887063f9cbeae 100644
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -1415,7 +1415,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
+ }
+
+ ret = pm_runtime_put_sync(dev);
+- if (ret < 0)
++ if (ret < 0 && ret != -ENOSYS)
+ goto err_pm_get_sync;
+
+ /*
+diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
+index 045965312245b..30c53dca342e8 100644
+--- a/sound/soc/intel/boards/sof_rt5682.c
++++ b/sound/soc/intel/boards/sof_rt5682.c
+@@ -225,6 +225,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
+ SOF_RT5682_SSP_AMP(2) |
+ SOF_RT5682_NUM_HDMIDEV(4)),
+ },
++ {
++ .callback = sof_rt5682_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
++ },
++ .driver_data = (void *)(SOF_RT5682_MCLK_EN |
++ SOF_RT5682_SSP_CODEC(2) |
++ SOF_SPEAKER_AMP_PRESENT |
++ SOF_RT5682_SSP_AMP(0) |
++ SOF_RT5682_NUM_HDMIDEV(4)
++ ),
++ },
+ {}
+ };
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 2ff30b40a1e4c..ee9857dc3135d 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ SOF_SDW_PCH_DMIC |
+ RT711_JD1),
+ },
++ {
++ /* NUC15 LAPBC710 skews */
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
++ },
++ .driver_data = (void *)(SOF_SDW_TGL_HDMI |
++ SOF_SDW_PCH_DMIC |
++ RT711_JD1),
++ },
+ /* TigerLake-SDCA devices */
+ {
+ .callback = sof_sdw_quirk_cb,
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index e824ff1a9fc09..3d057784cbd53 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -3472,10 +3472,23 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus);
+
+ static int __init snd_soc_init(void)
+ {
++ int ret;
++
+ snd_soc_debugfs_init();
+- snd_soc_util_init();
++ ret = snd_soc_util_init();
++ if (ret)
++ goto err_util_init;
+
+- return platform_driver_register(&soc_driver);
++ ret = platform_driver_register(&soc_driver);
++ if (ret)
++ goto err_register;
++ return 0;
++
++err_register:
++ snd_soc_util_exit();
++err_util_init:
++ snd_soc_debugfs_exit();
++ return ret;
+ }
+ module_init(snd_soc_init);
+
+diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
+index 70c380c0ac7b6..d1308904e6e0f 100644
+--- a/sound/soc/soc-utils.c
++++ b/sound/soc/soc-utils.c
+@@ -263,7 +263,7 @@ int __init snd_soc_util_init(void)
+ return ret;
+ }
+
+-void __exit snd_soc_util_exit(void)
++void snd_soc_util_exit(void)
+ {
+ platform_driver_unregister(&soc_dummy_driver);
+ platform_device_unregister(soc_dummy_dev);
+diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
+index 9273a70fec25c..e1b7f07de7fcd 100644
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -1346,16 +1346,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
+ break;
+ }
+
+- if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
+- swidget->core = SOF_DSP_PRIMARY_CORE;
+- } else {
+- int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
+- swidget->num_tuples);
+-
+- if (core >= 0)
+- swidget->core = core;
+- }
+-
+ /* check token parsing reply */
+ if (ret < 0) {
+ dev_err(scomp->dev,
+@@ -1367,6 +1357,16 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
+ return ret;
+ }
+
++ if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
++ swidget->core = SOF_DSP_PRIMARY_CORE;
++ } else {
++ int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
++ swidget->num_tuples);
++
++ if (core >= 0)
++ swidget->core = core;
++ }
++
+ /* bind widget to external event */
+ if (tw->event_type) {
+ if (widget_ops[w->id].bind_event) {
+diff --git a/sound/usb/midi.c b/sound/usb/midi.c
+index bbff0923d2646..2839f6b6f09b4 100644
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -1133,10 +1133,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
+ port = &umidi->endpoints[i].out->ports[j];
+ break;
+ }
+- if (!port) {
+- snd_BUG();
++ if (!port)
+ return -ENXIO;
+- }
+
+ substream->runtime->private_data = port;
+ port->state = STATE_UNKNOWN;
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index a072b2d3e726a..133e4c73d3702 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -695,7 +695,7 @@ static __init int cxl_test_init(void)
+
+ pdev = platform_device_alloc("cxl_switch_uport", i);
+ if (!pdev)
+- goto err_port;
++ goto err_uport;
+ pdev->dev.parent = &root_port->dev;
+
+ rc = platform_device_add(pdev);
+@@ -713,7 +713,7 @@ static __init int cxl_test_init(void)
+
+ pdev = platform_device_alloc("cxl_switch_dport", i);
+ if (!pdev)
+- goto err_port;
++ goto err_dport;
+ pdev->dev.parent = &uport->dev;
+
+ rc = platform_device_add(pdev);
+diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
+index 3561c97701f24..a07b8ae64bf83 100644
+--- a/tools/testing/selftests/bpf/test_progs.c
++++ b/tools/testing/selftests/bpf/test_progs.c
+@@ -993,7 +993,7 @@ static inline const char *str_msg(const struct msg *msg, char *buf)
+ msg->subtest_done.have_log);
+ break;
+ case MSG_TEST_LOG:
+- sprintf(buf, "MSG_TEST_LOG (cnt: %ld, last: %d)",
++ sprintf(buf, "MSG_TEST_LOG (cnt: %zu, last: %d)",
+ strlen(msg->test_log.log_buf),
+ msg->test_log.is_last);
+ break;
+diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
+index f9d553fbf68a3..ce97a92626989 100644
+--- a/tools/testing/selftests/bpf/test_verifier.c
++++ b/tools/testing/selftests/bpf/test_verifier.c
+@@ -1260,7 +1260,7 @@ static int get_xlated_program(int fd_prog, struct bpf_insn **buf, int *cnt)
+
+ bzero(&info, sizeof(info));
+ info.xlated_prog_len = xlated_prog_len;
+- info.xlated_prog_insns = (__u64)*buf;
++ info.xlated_prog_insns = (__u64)(unsigned long)*buf;
+ if (bpf_obj_get_info_by_fd(fd_prog, &info, &info_len)) {
+ perror("second bpf_obj_get_info_by_fd failed");
+ goto out_free_buf;
+diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile
+index 7321490116925..5a0e0df8de9b3 100644
+--- a/tools/testing/selftests/futex/functional/Makefile
++++ b/tools/testing/selftests/futex/functional/Makefile
+@@ -3,11 +3,11 @@ INCLUDES := -I../include -I../../ -I../../../../../usr/include/
+ CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES)
+ LDLIBS := -lpthread -lrt
+
+-HEADERS := \
++LOCAL_HDRS := \
+ ../include/futextest.h \
+ ../include/atomic.h \
+ ../include/logging.h
+-TEST_GEN_FILES := \
++TEST_GEN_PROGS := \
+ futex_wait_timeout \
+ futex_wait_wouldblock \
+ futex_requeue_pi \
+@@ -24,5 +24,3 @@ TEST_PROGS := run.sh
+ top_srcdir = ../../../../..
+ DEFAULT_INSTALL_HDR_PATH := 1
+ include ../../lib.mk
+-
+-$(TEST_GEN_FILES): $(HEADERS)
+diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile
+index 39f0fa2a8fd63..05d66ef50c977 100644
+--- a/tools/testing/selftests/intel_pstate/Makefile
++++ b/tools/testing/selftests/intel_pstate/Makefile
+@@ -2,10 +2,10 @@
+ CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
+ LDLIBS += -lm
+
+-uname_M := $(shell uname -m 2>/dev/null || echo not)
+-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
++ARCH ?= $(shell uname -m 2>/dev/null || echo not)
++ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+-ifeq (x86,$(ARCH))
++ifeq (x86,$(ARCH_PROCESSED))
+ TEST_GEN_FILES := msr aperf
+ endif
+
+diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile
+index 806a150648c36..67fe7a46cb624 100644
+--- a/tools/testing/selftests/kexec/Makefile
++++ b/tools/testing/selftests/kexec/Makefile
+@@ -1,10 +1,10 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ # Makefile for kexec tests
+
+-uname_M := $(shell uname -m 2>/dev/null || echo not)
+-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
++ARCH ?= $(shell uname -m 2>/dev/null || echo not)
++ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+-ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le))
++ifeq ($(ARCH_PROCESSED),$(filter $(ARCH_PROCESSED),x86 ppc64le))
+ TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh
+ TEST_FILES := kexec_common_lib.sh
+
+diff --git a/tools/testing/selftests/pidfd/pidfd_wait.c b/tools/testing/selftests/pidfd/pidfd_wait.c
+index 070c1c876df15..c3e2a3041f55f 100644
+--- a/tools/testing/selftests/pidfd/pidfd_wait.c
++++ b/tools/testing/selftests/pidfd/pidfd_wait.c
+@@ -95,20 +95,28 @@ TEST(wait_states)
+ .flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
+ .exit_signal = SIGCHLD,
+ };
++ int pfd[2];
+ pid_t pid;
+ siginfo_t info = {
+ .si_signo = 0,
+ };
+
++ ASSERT_EQ(pipe(pfd), 0);
+ pid = sys_clone3(&args);
+ ASSERT_GE(pid, 0);
+
+ if (pid == 0) {
++ char buf[2];
++
++ close(pfd[1]);
+ kill(getpid(), SIGSTOP);
++ ASSERT_EQ(read(pfd[0], buf, 1), 1);
++ close(pfd[0]);
+ kill(getpid(), SIGSTOP);
+ exit(EXIT_SUCCESS);
+ }
+
++ close(pfd[0]);
+ ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED, NULL), 0);
+ ASSERT_EQ(info.si_signo, SIGCHLD);
+ ASSERT_EQ(info.si_code, CLD_STOPPED);
+@@ -117,6 +125,8 @@ TEST(wait_states)
+ ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0), 0);
+
+ ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED, NULL), 0);
++ ASSERT_EQ(write(pfd[1], "C", 1), 1);
++ close(pfd[1]);
+ ASSERT_EQ(info.si_signo, SIGCHLD);
+ ASSERT_EQ(info.si_code, CLD_CONTINUED);
+ ASSERT_EQ(info.si_pid, parent_tid);
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-02 17:23 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-02 17:23 UTC (permalink / raw
To: gentoo-commits
commit: 6bdec7c135eddb0a34e89f2eac3ef9628666542b
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Dec 2 17:23:34 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Dec 2 17:23:34 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6bdec7c1
Linux patch 6.0.11
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1010_linux-6.0.11.patch | 10345 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 10349 insertions(+)
diff --git a/0000_README b/0000_README
index bf26e8c8..12c46dfc 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch: 1009_linux-6.0.10.patch
From: http://www.kernel.org
Desc: Linux 6.0.10
+Patch: 1010_linux-6.0.11.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.11
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1010_linux-6.0.11.patch b/1010_linux-6.0.11.patch
new file mode 100644
index 00000000..43ca90bb
--- /dev/null
+++ b/1010_linux-6.0.11.patch
@@ -0,0 +1,10345 @@
+diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+index b283c8ca2bbfc..5c08d8b6e9951 100644
+--- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
++++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+@@ -62,13 +62,6 @@ properties:
+ description:
+ Inform the driver that last channel will be used to sensor battery.
+
+- aspeed,trim-data-valid:
+- type: boolean
+- description: |
+- The ADC reference voltage can be calibrated to obtain the trimming
+- data which will be stored in otp. This property informs the driver that
+- the data store in the otp is valid.
+-
+ required:
+ - compatible
+ - reg
+diff --git a/Makefile b/Makefile
+index 4f7da26fef784..9fecb094c28a2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/am335x-pcm-953.dtsi b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+index dae448040a97b..9474974139778 100644
+--- a/arch/arm/boot/dts/am335x-pcm-953.dtsi
++++ b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+@@ -12,22 +12,20 @@
+ compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx";
+
+ /* Power */
+- regulators {
+- vcc3v3: fixedregulator@1 {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc3v3";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- };
++ vcc3v3: fixedregulator1 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ };
+
+- vcc1v8: fixedregulator@2 {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc1v8";
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-boot-on;
+- };
++ vcc1v8: fixedregulator2 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
+ };
+
+ /* User IO */
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index 60d61291f3444..024af2db638eb 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -39,6 +39,13 @@
+
+ };
+
++ usb1 {
++ pinctrl_usb1_vbus_gpio: usb1_vbus_gpio {
++ atmel,pins =
++ <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PC5 GPIO */
++ };
++ };
++
+ mmc0_slot1 {
+ pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ atmel,pins =
+@@ -84,6 +91,8 @@
+ };
+
+ usb1: gadget@fffa4000 {
++ pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
++ pinctrl-names = "default";
+ atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/imx6q-prti6q.dts b/arch/arm/boot/dts/imx6q-prti6q.dts
+index b4605edfd2ab8..d8fa83effd638 100644
+--- a/arch/arm/boot/dts/imx6q-prti6q.dts
++++ b/arch/arm/boot/dts/imx6q-prti6q.dts
+@@ -364,8 +364,8 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi>;
+ interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>;
+- ref-clock-frequency = "38400000";
+- tcxo-clock-frequency = "19200000";
++ ref-clock-frequency = <38400000>;
++ tcxo-clock-frequency = <19200000>;
+ };
+ };
+
+diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
+index 25c9d184fa4c6..1c57ac4016493 100644
+--- a/arch/arm/mach-mxs/mach-mxs.c
++++ b/arch/arm/mach-mxs/mach-mxs.c
+@@ -393,8 +393,10 @@ static void __init mxs_machine_init(void)
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+- if (ret)
++ if (ret) {
++ kfree(soc_dev_attr);
+ return;
++ }
+
+ soc_dev_attr->family = "Freescale MXS Family";
+ soc_dev_attr->soc_id = mxs_get_soc_id();
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+index 04c752f49be98..115c14c0a3c68 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+@@ -207,7 +207,7 @@
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ disable-wp;
+- max-frequency = <150000000>;
++ max-frequency = <40000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ vmmc-supply = <&vcc3v3_baseboard>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+index a05460b924153..25a8c781f4e75 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+@@ -740,7 +740,7 @@
+
+ &uart1 {
+ pinctrl-names = "default";
+- pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>;
++ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+ status = "okay";
+ uart-has-rtscts;
+
+@@ -748,13 +748,14 @@
+ compatible = "brcm,bcm43438-bt";
+ clocks = <&rk817 1>;
+ clock-names = "lpo";
+- device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
+- host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
++ host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+ vbat-supply = <&vcc_sys>;
+ vddio-supply = <&vcca1v8_pmu>;
++ max-speed = <3000000>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+index 528bb4e8ac776..a2d0524e0ec90 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+@@ -176,7 +176,7 @@
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+- interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+
+ pinctrl-names = "default";
+diff --git a/arch/arm64/include/asm/syscall_wrapper.h b/arch/arm64/include/asm/syscall_wrapper.h
+index b383b4802a7bd..d30217c21eff7 100644
+--- a/arch/arm64/include/asm/syscall_wrapper.h
++++ b/arch/arm64/include/asm/syscall_wrapper.h
+@@ -8,7 +8,7 @@
+ #ifndef __ASM_SYSCALL_WRAPPER_H
+ #define __ASM_SYSCALL_WRAPPER_H
+
+-struct pt_regs;
++#include <asm/ptrace.h>
+
+ #define SC_ARM64_REGS_TO_ARGS(x, ...) \
+ __MAP(x,__SC_ARGS \
+diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
+index 8ea57e2f0e04c..cc0674d1b8f0f 100644
+--- a/arch/loongarch/include/asm/pgtable.h
++++ b/arch/loongarch/include/asm/pgtable.h
+@@ -349,7 +349,9 @@ static inline pte_t pte_mkclean(pte_t pte)
+
+ static inline pte_t pte_mkdirty(pte_t pte)
+ {
+- pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++ pte_val(pte) |= _PAGE_MODIFIED;
++ if (pte_val(pte) & _PAGE_WRITE)
++ pte_val(pte) |= _PAGE_DIRTY;
+ return pte;
+ }
+
+@@ -475,7 +477,9 @@ static inline pmd_t pmd_mkclean(pmd_t pmd)
+
+ static inline pmd_t pmd_mkdirty(pmd_t pmd)
+ {
+- pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++ pmd_val(pmd) |= _PAGE_MODIFIED;
++ if (pmd_val(pmd) & _PAGE_WRITE)
++ pmd_val(pmd) |= _PAGE_DIRTY;
+ return pmd;
+ }
+
+diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
+index 660492f064e7e..6ae7c669ee642 100644
+--- a/arch/loongarch/kernel/process.c
++++ b/arch/loongarch/kernel/process.c
+@@ -152,7 +152,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ childregs->csr_crmd = p->thread.csr_crmd;
+ childregs->csr_prmd = p->thread.csr_prmd;
+ childregs->csr_ecfg = p->thread.csr_ecfg;
+- return 0;
++ goto out;
+ }
+
+ /* user thread */
+@@ -171,14 +171,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ */
+ childregs->csr_euen = 0;
+
++ if (clone_flags & CLONE_SETTLS)
++ childregs->regs[2] = tls;
++
++out:
+ clear_tsk_thread_flag(p, TIF_USEDFPU);
+ clear_tsk_thread_flag(p, TIF_USEDSIMD);
+ clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE);
+ clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE);
+
+- if (clone_flags & CLONE_SETTLS)
+- childregs->regs[2] = tls;
+-
+ return 0;
+ }
+
+diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h
+index d0ef8b4892bbe..d0494ce4b3373 100644
+--- a/arch/mips/include/asm/fw/fw.h
++++ b/arch/mips/include/asm/fw/fw.h
+@@ -26,6 +26,6 @@ extern char *fw_getcmdline(void);
+ extern void fw_meminit(void);
+ extern char *fw_getenv(char *name);
+ extern unsigned long fw_getenvl(char *name);
+-extern void fw_init_early_console(char port);
++extern void fw_init_early_console(void);
+
+ #endif /* __ASM_FW_H_ */
+diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
+index 25372e62783b5..3cd1b408fa1cb 100644
+--- a/arch/mips/pic32/pic32mzda/early_console.c
++++ b/arch/mips/pic32/pic32mzda/early_console.c
+@@ -27,7 +27,7 @@
+ #define U_BRG(x) (UART_BASE(x) + 0x40)
+
+ static void __iomem *uart_base;
+-static char console_port = -1;
++static int console_port = -1;
+
+ static int __init configure_uart_pins(int port)
+ {
+@@ -47,7 +47,7 @@ static int __init configure_uart_pins(int port)
+ return 0;
+ }
+
+-static void __init configure_uart(char port, int baud)
++static void __init configure_uart(int port, int baud)
+ {
+ u32 pbclk;
+
+@@ -60,7 +60,7 @@ static void __init configure_uart(char port, int baud)
+ uart_base + PIC32_SET(U_STA(port)));
+ }
+
+-static void __init setup_early_console(char port, int baud)
++static void __init setup_early_console(int port, int baud)
+ {
+ if (configure_uart_pins(port))
+ return;
+@@ -130,16 +130,15 @@ _out:
+ return baud;
+ }
+
+-void __init fw_init_early_console(char port)
++void __init fw_init_early_console(void)
+ {
+ char *arch_cmdline = pic32_getcmdline();
+- int baud = -1;
++ int baud, port;
+
+ uart_base = ioremap(PIC32_BASE_UART, 0xc00);
+
+ baud = get_baud_from_cmdline(arch_cmdline);
+- if (port == -1)
+- port = get_port_from_cmdline(arch_cmdline);
++ port = get_port_from_cmdline(arch_cmdline);
+
+ if (port == -1)
+ port = EARLY_CONSOLE_PORT;
+diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
+index d9c8c4e46aff9..58d8ca730df73 100644
+--- a/arch/mips/pic32/pic32mzda/init.c
++++ b/arch/mips/pic32/pic32mzda/init.c
+@@ -47,7 +47,7 @@ void __init plat_mem_setup(void)
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+
+ #ifdef CONFIG_EARLY_PRINTK
+- fw_init_early_console(-1);
++ fw_init_early_console();
+ #endif
+ pic32_config_init();
+ }
+diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
+index 8c3ad76602f3e..29c11a06b750a 100644
+--- a/arch/nios2/boot/Makefile
++++ b/arch/nios2/boot/Makefile
+@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
+ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+-$(obj)/vmImage: $(obj)/vmlinux.gz
++$(obj)/vmImage: $(obj)/vmlinux.gz FORCE
+ $(call if_changed,uimage)
+ @$(kecho) 'Kernel: $@ is ready'
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index ced0d4e479385..900a50526d771 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -3,6 +3,8 @@
+
+ #include "fu540-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pwm/pwm.h>
+
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ 1000000
+@@ -42,6 +44,42 @@
+ compatible = "gpio-restart";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ };
++
++ led-controller {
++ compatible = "pwm-leds";
++
++ led-d1 {
++ pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++ active-low;
++ color = <LED_COLOR_ID_GREEN>;
++ max-brightness = <255>;
++ label = "d1";
++ };
++
++ led-d2 {
++ pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++ active-low;
++ color = <LED_COLOR_ID_GREEN>;
++ max-brightness = <255>;
++ label = "d2";
++ };
++
++ led-d3 {
++ pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++ active-low;
++ color = <LED_COLOR_ID_GREEN>;
++ max-brightness = <255>;
++ label = "d3";
++ };
++
++ led-d4 {
++ pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++ active-low;
++ color = <LED_COLOR_ID_GREEN>;
++ max-brightness = <255>;
++ label = "d4";
++ };
++ };
+ };
+
+ &uart0 {
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index 84ac0fe612e79..db6548509bb3e 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -28,6 +28,9 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
+ obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
++ifneq ($(filter vgettimeofday, $(vdso-syms)),)
++CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
++endif
+
+ # Disable -pg to prevent insert call site
+ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
+index 01d94aae5bf51..150b1a572e619 100644
+--- a/arch/riscv/kernel/vdso/vdso.lds.S
++++ b/arch/riscv/kernel/vdso/vdso.lds.S
+@@ -68,9 +68,11 @@ VERSION
+ LINUX_4.15 {
+ global:
+ __vdso_rt_sigreturn;
++#ifdef HAS_VGETTIMEOFDAY
+ __vdso_gettimeofday;
+ __vdso_clock_gettime;
+ __vdso_clock_getres;
++#endif
+ __vdso_getcpu;
+ __vdso_flush_icache;
+ local: *;
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 318fce77601d3..de575af02ffea 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -568,8 +568,7 @@ config EXPOLINE_FULL
+ endchoice
+
+ config RELOCATABLE
+- bool "Build a relocatable kernel"
+- default y
++ def_bool y
+ help
+ This builds a kernel image that retains relocation information
+ so it can be loaded at an arbitrary address.
+@@ -578,10 +577,11 @@ config RELOCATABLE
+ bootup process.
+ The relocations make the kernel image about 15% larger (compressed
+ 10%), but are discarded at runtime.
++ Note: this option exists only for documentation purposes, please do
++ not remove it.
+
+ config RANDOMIZE_BASE
+ bool "Randomize the address of the kernel image (KASLR)"
+- depends on RELOCATABLE
+ default y
+ help
+ In support of Kernel Address Space Layout Randomization (KASLR),
+diff --git a/arch/s390/Makefile b/arch/s390/Makefile
+index 4cb5d17e7ead6..47bec926d6c09 100644
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -14,10 +14,8 @@ KBUILD_AFLAGS_MODULE += -fPIC
+ KBUILD_CFLAGS_MODULE += -fPIC
+ KBUILD_AFLAGS += -m64
+ KBUILD_CFLAGS += -m64
+-ifeq ($(CONFIG_RELOCATABLE),y)
+ KBUILD_CFLAGS += -fPIE
+ LDFLAGS_vmlinux := -pie
+-endif
+ aflags_dwarf := -Wa,-gdwarf-2
+ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
+ ifndef CONFIG_AS_IS_LLVM
+diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
+index 883357a211a3b..d52c3e2e16bc5 100644
+--- a/arch/s390/boot/Makefile
++++ b/arch/s390/boot/Makefile
+@@ -37,9 +37,8 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
+
+ obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
+ obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
+-obj-y += version.o pgm_check_info.o ctype.o ipl_data.o
++obj-y += version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o
+ obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
+-obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o
+ obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
+ obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
+ obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
+index bc48fe82d949a..e5026e1d277fb 100644
+--- a/arch/s390/boot/startup.c
++++ b/arch/s390/boot/startup.c
+@@ -285,8 +285,7 @@ void startup_kernel(void)
+
+ clear_bss_section();
+ copy_bootdata();
+- if (IS_ENABLED(CONFIG_RELOCATABLE))
+- handle_relocs(__kaslr_offset);
++ handle_relocs(__kaslr_offset);
+
+ if (__kaslr_offset) {
+ /*
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index bad8f47fc5d69..c1b2b0d4af773 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -45,7 +45,7 @@ struct save_area {
+ u64 fprs[16];
+ u32 fpc;
+ u32 prefix;
+- u64 todpreg;
++ u32 todpreg;
+ u64 timer;
+ u64 todcmp;
+ u64 vxrs_low[16];
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index 3de6d8b533672..a0165df3c4d8c 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void)
+ static int hv_cpu_init(unsigned int cpu)
+ {
+ union hv_vp_assist_msr_contents msr = { 0 };
+- struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
++ struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+ int ret;
+
+ ret = hv_common_cpu_init(cpu);
+@@ -87,34 +87,32 @@ static int hv_cpu_init(unsigned int cpu)
+ if (!hv_vp_assist_page)
+ return 0;
+
+- if (!*hvp) {
+- if (hv_root_partition) {
+- /*
+- * For root partition we get the hypervisor provided VP assist
+- * page, instead of allocating a new page.
+- */
+- rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+- *hvp = memremap(msr.pfn <<
+- HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
+- PAGE_SIZE, MEMREMAP_WB);
+- } else {
+- /*
+- * The VP assist page is an "overlay" page (see Hyper-V TLFS's
+- * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
+- * out to make sure we always write the EOI MSR in
+- * hv_apic_eoi_write() *after* the EOI optimization is disabled
+- * in hv_cpu_die(), otherwise a CPU may not be stopped in the
+- * case of CPU offlining and the VM will hang.
+- */
++ if (hv_root_partition) {
++ /*
++ * For root partition we get the hypervisor provided VP assist
++ * page, instead of allocating a new page.
++ */
++ rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
++ *hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
++ PAGE_SIZE, MEMREMAP_WB);
++ } else {
++ /*
++ * The VP assist page is an "overlay" page (see Hyper-V TLFS's
++ * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
++ * out to make sure we always write the EOI MSR in
++ * hv_apic_eoi_write() *after* the EOI optimization is disabled
++ * in hv_cpu_die(), otherwise a CPU may not be stopped in the
++ * case of CPU offlining and the VM will hang.
++ */
++ if (!*hvp)
+ *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
+- if (*hvp)
+- msr.pfn = vmalloc_to_pfn(*hvp);
+- }
+- WARN_ON(!(*hvp));
+- if (*hvp) {
+- msr.enable = 1;
+- wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+- }
++ if (*hvp)
++ msr.pfn = vmalloc_to_pfn(*hvp);
++
++ }
++ if (!WARN_ON(!(*hvp))) {
++ msr.enable = 1;
++ wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+ }
+
+ return hyperv_init_ghcb();
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index ef4775c6db01c..dfa672bec6109 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -305,6 +305,9 @@
+ #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
+ #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
+
++
++#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
++
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
+ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
+diff --git a/arch/x86/kernel/cpu/tsx.c b/arch/x86/kernel/cpu/tsx.c
+index ec7bbac3a9f29..8009c8346d8f8 100644
+--- a/arch/x86/kernel/cpu/tsx.c
++++ b/arch/x86/kernel/cpu/tsx.c
+@@ -58,24 +58,6 @@ static void tsx_enable(void)
+ wrmsrl(MSR_IA32_TSX_CTRL, tsx);
+ }
+
+-static bool tsx_ctrl_is_supported(void)
+-{
+- u64 ia32_cap = x86_read_arch_cap_msr();
+-
+- /*
+- * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this
+- * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
+- *
+- * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
+- * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
+- * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
+- * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
+- * tsx= cmdline requests will do nothing on CPUs without
+- * MSR_IA32_TSX_CTRL support.
+- */
+- return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
+-}
+-
+ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
+ {
+ if (boot_cpu_has_bug(X86_BUG_TAA))
+@@ -135,7 +117,7 @@ static void tsx_clear_cpuid(void)
+ rdmsrl(MSR_TSX_FORCE_ABORT, msr);
+ msr |= MSR_TFA_TSX_CPUID_CLEAR;
+ wrmsrl(MSR_TSX_FORCE_ABORT, msr);
+- } else if (tsx_ctrl_is_supported()) {
++ } else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) {
+ rdmsrl(MSR_IA32_TSX_CTRL, msr);
+ msr |= TSX_CTRL_CPUID_CLEAR;
+ wrmsrl(MSR_IA32_TSX_CTRL, msr);
+@@ -158,7 +140,8 @@ static void tsx_dev_mode_disable(void)
+ u64 mcu_opt_ctrl;
+
+ /* Check if RTM_ALLOW exists */
+- if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() ||
++ if (!boot_cpu_has_bug(X86_BUG_TAA) ||
++ !cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) ||
+ !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
+ return;
+
+@@ -191,7 +174,20 @@ void __init tsx_init(void)
+ return;
+ }
+
+- if (!tsx_ctrl_is_supported()) {
++ /*
++ * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this
++ * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
++ *
++ * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
++ * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
++ * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
++ * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
++ * tsx= cmdline requests will do nothing on CPUs without
++ * MSR_IA32_TSX_CTRL support.
++ */
++ if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) {
++ setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL);
++ } else {
+ tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
+ return;
+ }
+diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
+index 83e30e4db2ae0..0a163ba9fa1a2 100644
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -2431,6 +2431,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm,
+ {
+ bool list_unstable, zapped_root = false;
+
++ lockdep_assert_held_write(&kvm->mmu_lock);
+ trace_kvm_mmu_prepare_zap_page(sp);
+ ++kvm->stat.mmu_shadow_zapped;
+ *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);
+@@ -4250,14 +4251,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
+ if (is_page_fault_stale(vcpu, fault, mmu_seq))
+ goto out_unlock;
+
+- r = make_mmu_pages_available(vcpu);
+- if (r)
+- goto out_unlock;
+-
+- if (is_tdp_mmu_fault)
++ if (is_tdp_mmu_fault) {
+ r = kvm_tdp_mmu_map(vcpu, fault);
+- else
++ } else {
++ r = make_mmu_pages_available(vcpu);
++ if (r)
++ goto out_unlock;
+ r = __direct_map(vcpu, fault);
++ }
+
+ out_unlock:
+ if (is_tdp_mmu_fault)
+diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
+index 76dcc8a3e8496..630359bce06d4 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -1143,6 +1143,9 @@ void svm_free_nested(struct vcpu_svm *svm)
+ if (!svm->nested.initialized)
+ return;
+
++ if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
++ svm_switch_vmcb(svm, &svm->vmcb01);
++
+ svm_vcpu_free_msrpm(svm->nested.msrpm);
+ svm->nested.msrpm = NULL;
+
+@@ -1161,9 +1164,6 @@ void svm_free_nested(struct vcpu_svm *svm)
+ svm->nested.initialized = false;
+ }
+
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void svm_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index e80756ab141bf..6431019d0eff0 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -346,12 +346,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+ return 0;
+ }
+
+-static int is_external_interrupt(u32 info)
+-{
+- info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
+- return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
+-}
+-
+ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+@@ -1440,6 +1434,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ */
+ svm_clear_current_vmcb(svm->vmcb);
+
++ svm_leave_nested(vcpu);
+ svm_free_nested(svm);
+
+ sev_free_vcpu(vcpu);
+@@ -3426,15 +3421,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+ return 0;
+ }
+
+- if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
+- exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
+- exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
+- exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
+- printk(KERN_ERR "%s: unexpected exit_int_info 0x%x "
+- "exit_code 0x%x\n",
+- __func__, svm->vmcb->control.exit_int_info,
+- exit_code);
+-
+ if (exit_fastpath != EXIT_FASTPATH_NONE)
+ return 1;
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 03d348fa6485a..f56cc2382edf9 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -6294,9 +6294,6 @@ out:
+ return kvm_state.size;
+ }
+
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void vmx_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ if (is_guest_mode(vcpu)) {
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 71cbafd67319b..5d38409913a9d 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -611,6 +611,12 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
+ }
+ EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload);
+
++/* Forcibly leave the nested mode in cases like a vCPU reset */
++static void kvm_leave_nested(struct kvm_vcpu *vcpu)
++{
++ kvm_x86_ops.nested_ops->leave_nested(vcpu);
++}
++
+ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
+ unsigned nr, bool has_error, u32 error_code,
+ bool has_payload, unsigned long payload, bool reinject)
+@@ -5154,7 +5160,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
+
+ if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
+ if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
+- kvm_x86_ops.nested_ops->leave_nested(vcpu);
++ kvm_leave_nested(vcpu);
+ kvm_smm_changed(vcpu, events->smi.smm);
+ }
+
+@@ -11789,8 +11795,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ WARN_ON_ONCE(!init_event &&
+ (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
+
++ /*
++ * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
++ * possible to INIT the vCPU while L2 is active. Force the vCPU back
++ * into L1 as EFER.SVME is cleared on INIT (along with all other EFER
++ * bits), i.e. virtualization is disabled.
++ */
++ if (is_guest_mode(vcpu))
++ kvm_leave_nested(vcpu);
++
+ kvm_lapic_reset(vcpu, init_event);
+
++ WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
+ vcpu->arch.hflags = 0;
+
+ vcpu->arch.smi_pending = 0;
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index 9a1950879fc44..8333b6c50e93c 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -954,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+ return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
+ }
+
++static inline int max_evtchn_port(struct kvm *kvm)
++{
++ if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
++ return EVTCHN_2L_NR_CHANNELS;
++ else
++ return COMPAT_EVTCHN_2L_NR_CHANNELS;
++}
++
+ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
+ evtchn_port_t *ports)
+ {
+@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
+ *r = -EFAULT;
+ goto out;
+ }
++ if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
++ *r = -EINVAL;
++ goto out;
++ }
+ }
+
+ if (sched_poll.nr_ports == 1)
+@@ -1216,6 +1228,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ bool longmode;
+ u64 input, params[6], r = -ENOSYS;
+ bool handled = false;
++ u8 cpl;
+
+ input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);
+
+@@ -1243,9 +1256,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ params[5] = (u64)kvm_r9_read(vcpu);
+ }
+ #endif
++ cpl = static_call(kvm_x86_get_cpl)(vcpu);
+ trace_kvm_xen_hypercall(input, params[0], params[1], params[2],
+ params[3], params[4], params[5]);
+
++ /*
++ * Only allow hypercall acceleration for CPL0. The rare hypercalls that
++ * are permitted in guest userspace can be handled by the VMM.
++ */
++ if (unlikely(cpl > 0))
++ goto handle_in_userspace;
++
+ switch (input) {
+ case __HYPERVISOR_xen_version:
+ if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) {
+@@ -1280,10 +1301,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ if (handled)
+ return kvm_xen_hypercall_set_result(vcpu, r);
+
++handle_in_userspace:
+ vcpu->run->exit_reason = KVM_EXIT_XEN;
+ vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
+ vcpu->run->xen.u.hcall.longmode = longmode;
+- vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu);
++ vcpu->run->xen.u.hcall.cpl = cpl;
+ vcpu->run->xen.u.hcall.input = input;
+ vcpu->run->xen.u.hcall.params[0] = params[0];
+ vcpu->run->xen.u.hcall.params[1] = params[1];
+@@ -1298,14 +1320,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ return 0;
+ }
+
+-static inline int max_evtchn_port(struct kvm *kvm)
+-{
+- if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
+- return EVTCHN_2L_NR_CHANNELS;
+- else
+- return COMPAT_EVTCHN_2L_NR_CHANNELS;
+-}
+-
+ static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
+ {
+ int poll_evtchn = vcpu->arch.xen.poll_evtchn;
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 1ad0228f8ceb9..19058d7466957 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -216,9 +216,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+- phys_addr &= PHYSICAL_PAGE_MASK;
++ phys_addr &= PAGE_MASK;
+ size = PAGE_ALIGN(last_addr+1) - phys_addr;
+
++ /*
++ * Mask out any bits not part of the actual physical
++ * address, like memory encryption bits.
++ */
++ phys_addr &= PHYSICAL_PAGE_MASK;
++
+ retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
+ pcm, &new_pcm);
+ if (retval) {
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index 4cd39f304e206..93ae33248f421 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -513,16 +513,23 @@ static int pm_cpu_check(const struct x86_cpu_id *c)
+
+ static void pm_save_spec_msr(void)
+ {
+- u32 spec_msr_id[] = {
+- MSR_IA32_SPEC_CTRL,
+- MSR_IA32_TSX_CTRL,
+- MSR_TSX_FORCE_ABORT,
+- MSR_IA32_MCU_OPT_CTRL,
+- MSR_AMD64_LS_CFG,
+- MSR_AMD64_DE_CFG,
++ struct msr_enumeration {
++ u32 msr_no;
++ u32 feature;
++ } msr_enum[] = {
++ { MSR_IA32_SPEC_CTRL, X86_FEATURE_MSR_SPEC_CTRL },
++ { MSR_IA32_TSX_CTRL, X86_FEATURE_MSR_TSX_CTRL },
++ { MSR_TSX_FORCE_ABORT, X86_FEATURE_TSX_FORCE_ABORT },
++ { MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL },
++ { MSR_AMD64_LS_CFG, X86_FEATURE_LS_CFG_SSBD },
++ { MSR_AMD64_DE_CFG, X86_FEATURE_LFENCE_RDTSC },
+ };
++ int i;
+
+- msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
++ for (i = 0; i < ARRAY_SIZE(msr_enum); i++) {
++ if (boot_cpu_has(msr_enum[i].feature))
++ msr_build_context(&msr_enum[i].msr_no, 1);
++ }
+ }
+
+ static int pm_check_save_msr(void)
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 30b15a9a47c4f..249f489d115f0 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -615,6 +615,10 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
+ struct bfq_group *bfqg;
+
+ while (blkg) {
++ if (!blkg->online) {
++ blkg = blkg->parent;
++ continue;
++ }
+ bfqg = blkg_to_bfqg(blkg);
+ if (bfqg->online) {
+ bio_associate_blkg_from_css(bio, &blkg->blkcg->css);
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 4402e4ecb8b11..3f1f5e3e0951d 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3956,9 +3956,14 @@ EXPORT_SYMBOL(__blk_mq_alloc_disk);
+ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
+ struct lock_class_key *lkclass)
+ {
++ struct gendisk *disk;
++
+ if (!blk_get_queue(q))
+ return NULL;
+- return __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++ disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++ if (!disk)
++ blk_put_queue(q);
++ return disk;
+ }
+ EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 4949ed3ce7c95..8ac1038d0c797 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -59,7 +59,6 @@ void blk_set_default_limits(struct queue_limits *lim)
+ lim->zone_write_granularity = 0;
+ lim->dma_alignment = 511;
+ }
+-EXPORT_SYMBOL(blk_set_default_limits);
+
+ /**
+ * blk_set_stacking_limits - set default limits for stacking devices
+diff --git a/block/blk.h b/block/blk.h
+index 52432eab621e5..ff0bec16f0fa0 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -324,6 +324,7 @@ void blk_rq_set_mixed_merge(struct request *rq);
+ bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
+ enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
+
++void blk_set_default_limits(struct queue_limits *lim);
+ int blk_dev_init(void);
+
+ /*
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 68a566f696845..aae9261c424a3 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -578,6 +578,20 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
+ },
+ },
++ /*
++ * Models which have nvidia-ec-wmi support, but should not use it.
++ * Note this indicates a likely firmware bug on these models and should
++ * be revisited if/when Linux gets support for dynamic mux mode.
++ */
++ {
++ .callback = video_detect_force_native,
++ /* Dell G15 5515 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
++ },
++ },
++
+ /*
+ * Desktops which falsely report a backlight and which our heuristics
+ * for this do not catch.
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
+index 9b1778c006103..64999777e0bf5 100644
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -760,6 +760,12 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
+ const char *failure_string;
+ struct binder_buffer *buffer;
+
++ if (unlikely(vma->vm_mm != alloc->vma_vm_mm)) {
++ ret = -EINVAL;
++ failure_string = "invalid vma->vm_mm";
++ goto err_invalid_mm;
++ }
++
+ mutex_lock(&binder_alloc_mmap_lock);
+ if (alloc->buffer_size) {
+ ret = -EBUSY;
+@@ -806,6 +812,7 @@ err_alloc_pages_failed:
+ alloc->buffer_size = 0;
+ err_already_mapped:
+ mutex_unlock(&binder_alloc_mmap_lock);
++err_invalid_mm:
+ binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
+ "%s: %d %lx-%lx %s failed %d\n", __func__,
+ alloc->pid, vma->vm_start, vma->vm_end,
+diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c
+index a4388440aca7a..91db001eb69a6 100644
+--- a/drivers/bus/intel-ixp4xx-eb.c
++++ b/drivers/bus/intel-ixp4xx-eb.c
+@@ -49,7 +49,7 @@
+ #define IXP4XX_EXP_SIZE_SHIFT 10
+ #define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */
+ #define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */
+-#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */
++#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */
+ #define IXP4XX_EXP_BYTE_RD16 BIT(6)
+ #define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */
+ #define IXP4XX_EXP_MUX_EN BIT(4)
+@@ -57,8 +57,6 @@
+ #define IXP4XX_EXP_WORD BIT(2) /* Always zero */
+ #define IXP4XX_EXP_WR_EN BIT(1)
+ #define IXP4XX_EXP_BYTE_EN BIT(0)
+-#define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD)
+-#define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD)
+
+ #define IXP4XX_EXP_CNFG0 0x20
+ #define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31)
+@@ -252,10 +250,9 @@ static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb,
+ cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT;
+ }
+
+- if (eb->is_42x)
+- cs_cfg &= ~IXP42X_RESERVED;
+ if (eb->is_43x) {
+- cs_cfg &= ~IXP43X_RESERVED;
++ /* Should always be zero */
++ cs_cfg &= ~IXP4XX_EXP_WORD;
+ /*
+ * This bit for Intel strata flash is currently unused, but let's
+ * report it if we find one.
+diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
+index 4cd2e127946ea..3aa91aed3bf73 100644
+--- a/drivers/bus/sunxi-rsb.c
++++ b/drivers/bus/sunxi-rsb.c
+@@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+ /* common code that starts a transfer */
+ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ {
++ u32 int_mask, status;
++ bool timeout;
++
+ if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+ dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+ return -EBUSY;
+@@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+
+ reinit_completion(&rsb->complete);
+
+- writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+- rsb->regs + RSB_INTE);
++ int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER;
++ writel(int_mask, rsb->regs + RSB_INTE);
+ writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+ rsb->regs + RSB_CTRL);
+
+- if (!wait_for_completion_io_timeout(&rsb->complete,
+- msecs_to_jiffies(100))) {
++ if (irqs_disabled()) {
++ timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
++ status, (status & int_mask),
++ 10, 100000);
++ writel(status, rsb->regs + RSB_INTS);
++ } else {
++ timeout = !wait_for_completion_io_timeout(&rsb->complete,
++ msecs_to_jiffies(100));
++ status = rsb->status;
++ }
++
++ if (timeout) {
+ dev_dbg(rsb->dev, "RSB timeout\n");
+
+ /* abort the transfer */
+@@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ return -ETIMEDOUT;
+ }
+
+- if (rsb->status & RSB_INTS_LOAD_BSY) {
++ if (status & RSB_INTS_LOAD_BSY) {
+ dev_dbg(rsb->dev, "RSB busy\n");
+ return -EBUSY;
+ }
+
+- if (rsb->status & RSB_INTS_TRANS_ERR) {
+- if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
++ if (status & RSB_INTS_TRANS_ERR) {
++ if (status & RSB_INTS_TRANS_ERR_ACK) {
+ dev_dbg(rsb->dev, "RSB slave nack\n");
+ return -EINVAL;
+ }
+
+- if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
++ if (status & RSB_INTS_TRANS_ERR_DATA) {
+ dev_dbg(rsb->dev, "RSB transfer data error\n");
+ return -EIO;
+ }
+@@ -812,14 +825,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-static void sunxi_rsb_shutdown(struct platform_device *pdev)
+-{
+- struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+-
+- pm_runtime_disable(&pdev->dev);
+- sunxi_rsb_hw_exit(rsb);
+-}
+-
+ static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
+ sunxi_rsb_runtime_resume, NULL)
+@@ -835,7 +840,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+ static struct platform_driver sunxi_rsb_driver = {
+ .probe = sunxi_rsb_probe,
+ .remove = sunxi_rsb_remove,
+- .shutdown = sunxi_rsb_shutdown,
+ .driver = {
+ .name = RSB_CTRL_NAME,
+ .of_match_table = sunxi_rsb_of_match_table,
+diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
+index 55516043b656b..8184378f67efa 100644
+--- a/drivers/cpufreq/Kconfig.x86
++++ b/drivers/cpufreq/Kconfig.x86
+@@ -35,7 +35,7 @@ config X86_PCC_CPUFREQ
+ If in doubt, say N.
+
+ config X86_AMD_PSTATE
+- tristate "AMD Processor P-State driver"
++ bool "AMD Processor P-State driver"
+ depends on X86 && ACPI
+ select ACPI_PROCESSOR
+ select ACPI_CPPC_LIB if X86_64
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index d63a28c5f95a9..5b788492ce5e7 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -483,12 +483,22 @@ static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
+ amd_pstate_driver.boost_enabled = true;
+ }
+
++static void amd_perf_ctl_reset(unsigned int cpu)
++{
++ wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
++}
++
+ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ {
+ int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
+ struct device *dev;
+ struct amd_cpudata *cpudata;
+
++ /*
++ * Resetting PERF_CTL_MSR will put the CPU in P0 frequency,
++ * which is ideal for initialization process.
++ */
++ amd_perf_ctl_reset(policy->cpu);
+ dev = get_cpu_device(policy->cpu);
+ if (!dev)
+ return -ENODEV;
+@@ -718,16 +728,7 @@ static int __init amd_pstate_init(void)
+
+ return ret;
+ }
+-
+-static void __exit amd_pstate_exit(void)
+-{
+- cpufreq_unregister_driver(&amd_pstate_driver);
+-
+- amd_pstate_enable(false);
+-}
+-
+-module_init(amd_pstate_init);
+-module_exit(amd_pstate_exit);
++device_initcall(amd_pstate_init);
+
+ MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
+ MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
+diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
+index efb4990b29e10..c6f08066e1653 100644
+--- a/drivers/dma-buf/dma-buf.c
++++ b/drivers/dma-buf/dma-buf.c
+@@ -15,6 +15,7 @@
+ #include <linux/slab.h>
+ #include <linux/dma-buf.h>
+ #include <linux/dma-fence.h>
++#include <linux/dma-fence-unwrap.h>
+ #include <linux/anon_inodes.h>
+ #include <linux/export.h>
+ #include <linux/debugfs.h>
+@@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ const void __user *user_data)
+ {
+ struct dma_buf_import_sync_file arg;
+- struct dma_fence *fence;
++ struct dma_fence *fence, *f;
+ enum dma_resv_usage usage;
++ struct dma_fence_unwrap iter;
++ unsigned int num_fences;
+ int ret = 0;
+
+ if (copy_from_user(&arg, user_data, sizeof(arg)))
+@@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
+ DMA_RESV_USAGE_READ;
+
+- dma_resv_lock(dmabuf->resv, NULL);
++ num_fences = 0;
++ dma_fence_unwrap_for_each(f, &iter, fence)
++ ++num_fences;
+
+- ret = dma_resv_reserve_fences(dmabuf->resv, 1);
+- if (!ret)
+- dma_resv_add_fence(dmabuf->resv, fence, usage);
++ if (num_fences > 0) {
++ dma_resv_lock(dmabuf->resv, NULL);
+
+- dma_resv_unlock(dmabuf->resv);
++ ret = dma_resv_reserve_fences(dmabuf->resv, num_fences);
++ if (!ret) {
++ dma_fence_unwrap_for_each(f, &iter, fence)
++ dma_resv_add_fence(dmabuf->resv, f, usage);
++ }
++
++ dma_resv_unlock(dmabuf->resv);
++ }
+
+ dma_fence_put(fence);
+
+diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
+index 8f5848aa144fe..59d158873f4cb 100644
+--- a/drivers/dma-buf/dma-heap.c
++++ b/drivers/dma-buf/dma-heap.c
+@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ return ERR_PTR(-EINVAL);
+ }
+
+- /* check the name is unique */
+- mutex_lock(&heap_list_lock);
+- list_for_each_entry(h, &heap_list, list) {
+- if (!strcmp(h->name, exp_info->name)) {
+- mutex_unlock(&heap_list_lock);
+- pr_err("dma_heap: Already registered heap named %s\n",
+- exp_info->name);
+- return ERR_PTR(-EINVAL);
+- }
+- }
+- mutex_unlock(&heap_list_lock);
+-
+ heap = kzalloc(sizeof(*heap), GFP_KERNEL);
+ if (!heap)
+ return ERR_PTR(-ENOMEM);
+@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ err_ret = ERR_CAST(dev_ret);
+ goto err2;
+ }
+- /* Add heap to the list */
++
+ mutex_lock(&heap_list_lock);
++ /* check the name is unique */
++ list_for_each_entry(h, &heap_list, list) {
++ if (!strcmp(h->name, exp_info->name)) {
++ mutex_unlock(&heap_list_lock);
++ pr_err("dma_heap: Already registered heap named %s\n",
++ exp_info->name);
++ err_ret = ERR_PTR(-EINVAL);
++ goto err3;
++ }
++ }
++
++ /* Add heap to the list */
+ list_add(&heap->list, &heap_list);
+ mutex_unlock(&heap_list_lock);
+
+ return heap;
+
++err3:
++ device_destroy(dma_heap_class, heap->heap_devt);
+ err2:
+ cdev_del(&heap->heap_cdev);
+ err1:
+diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
+index 6c416955da532..bbe0a7cabb75f 100644
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -246,7 +246,9 @@ config FPGA_MGR_VERSAL_FPGA
+
+ config FPGA_M10_BMC_SEC_UPDATE
+ tristate "Intel MAX10 BMC Secure Update driver"
+- depends on MFD_INTEL_M10_BMC && FW_UPLOAD
++ depends on MFD_INTEL_M10_BMC
++ select FW_LOADER
++ select FW_UPLOAD
+ help
+ Secure update support for the Intel MAX10 board management
+ controller.
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+index c8935d7182073..4485bb29bec96 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+@@ -41,5 +41,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
+ .get_atc_vmid_pasid_mapping_info =
+ kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
+ .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
++ .get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
+ .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 93ad00453f4b3..7db4aef9c45cb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -170,9 +170,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
+ (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
+ kfd_mem_limit.max_ttm_mem_limit) ||
+ (adev && adev->kfd.vram_used + vram_needed >
+- adev->gmc.real_vram_size -
+- atomic64_read(&adev->vram_pin_size) -
+- reserved_for_pt)) {
++ adev->gmc.real_vram_size - reserved_for_pt)) {
+ ret = -ENOMEM;
+ goto release;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index 491d4846fc02c..cfb262911bfc7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -328,7 +328,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector)
+
+ kfree(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
+- drm_connector_update_edid_property(connector, NULL);
+ }
+
+ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+index 8ef31d687ef3b..111484ceb47d7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+@@ -413,11 +413,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ if (r)
+ goto release_object;
+
+- if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) {
+- r = amdgpu_mn_register(bo, args->addr);
+- if (r)
+- goto release_object;
+- }
++ r = amdgpu_mn_register(bo, args->addr);
++ if (r)
++ goto release_object;
+
+ if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+ r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index aebc384531ac8..bff5d8c832add 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
+ unsigned i;
+ unsigned vmhub, inv_eng;
+
++ if (adev->enable_mes) {
++ /* reserve engine 5 for firmware */
++ for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++)
++ vm_inv_engs[vmhub] &= ~(1 << 5);
++ }
++
+ for (i = 0; i < adev->num_rings; ++i) {
+ ring = adev->rings[i];
+ vmhub = ring->funcs->vmhub;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index c9dec2434f370..cfa45a697d241 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -171,6 +171,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
+ {
+ amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr,
+ &mem_ctx->shared_buf);
++ mem_ctx->shared_bo = NULL;
+ }
+
+ static void psp_free_shared_bufs(struct psp_context *psp)
+@@ -181,6 +182,7 @@ static void psp_free_shared_bufs(struct psp_context *psp)
+ /* free TMR memory buffer */
+ pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+ amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++ psp->tmr_bo = NULL;
+
+ /* free xgmi shared memory */
+ psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context);
+@@ -728,7 +730,7 @@ static int psp_load_toc(struct psp_context *psp,
+ /* Set up Trusted Memory Region */
+ static int psp_tmr_init(struct psp_context *psp)
+ {
+- int ret;
++ int ret = 0;
+ int tmr_size;
+ void *tmr_buf;
+ void **pptr;
+@@ -755,10 +757,12 @@ static int psp_tmr_init(struct psp_context *psp)
+ }
+ }
+
+- pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+- ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
+- AMDGPU_GEM_DOMAIN_VRAM,
+- &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++ if (!psp->tmr_bo) {
++ pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
++ ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
++ AMDGPU_GEM_DOMAIN_VRAM,
++ &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++ }
+
+ return ret;
+ }
+@@ -2720,8 +2724,6 @@ static int psp_suspend(void *handle)
+ }
+
+ out:
+- psp_free_shared_bufs(psp);
+-
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 04130f8813ef1..369c0d03e3c6a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -143,32 +143,6 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ return 0;
+ }
+
+-/*
+- * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
+- * happens while holding this lock anywhere to prevent deadlocks when
+- * an MMU notifier runs in reclaim-FS context.
+- */
+-static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
+-{
+- mutex_lock(&vm->eviction_lock);
+- vm->saved_flags = memalloc_noreclaim_save();
+-}
+-
+-static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
+-{
+- if (mutex_trylock(&vm->eviction_lock)) {
+- vm->saved_flags = memalloc_noreclaim_save();
+- return 1;
+- }
+- return 0;
+-}
+-
+-static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
+-{
+- memalloc_noreclaim_restore(vm->saved_flags);
+- mutex_unlock(&vm->eviction_lock);
+-}
+-
+ /**
+ * amdgpu_vm_bo_evicted - vm_bo is evicted
+ *
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+index 278512535b518..39d2898caedef 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -503,4 +503,30 @@ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
+ return atomic64_read(&vm->tlb_seq);
+ }
+
++/*
++ * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
++ * happens while holding this lock anywhere to prevent deadlocks when
++ * an MMU notifier runs in reclaim-FS context.
++ */
++static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
++{
++ mutex_lock(&vm->eviction_lock);
++ vm->saved_flags = memalloc_noreclaim_save();
++}
++
++static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
++{
++ if (mutex_trylock(&vm->eviction_lock)) {
++ vm->saved_flags = memalloc_noreclaim_save();
++ return true;
++ }
++ return false;
++}
++
++static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
++{
++ memalloc_noreclaim_restore(vm->saved_flags);
++ mutex_unlock(&vm->eviction_lock);
++}
++
+ #endif
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+index 88de9f0d4728a..9838995744648 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+@@ -597,7 +597,9 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev,
+ if (entry->bo)
+ return 0;
+
++ amdgpu_vm_eviction_unlock(vm);
+ r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt);
++ amdgpu_vm_eviction_lock(vm);
+ if (r)
+ return r;
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 3bff0ae15e64e..3175b9c1849dd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -190,7 +190,11 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
+ mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
+ mes_add_queue_pkt.tma_addr = input->tma_addr;
+ mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
+- mes_add_queue_pkt.trap_en = 1;
++
++ if (!(((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 4) &&
++ (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) &&
++ (adev->ip_versions[GC_HWIP][0] <= IP_VERSION(11, 0, 3))))
++ mes_add_queue_pkt.trap_en = 1;
+
+ /* For KFD, gds_size is re-used for queue size (needed in MES for AQL queues) */
+ mes_add_queue_pkt.is_aql_queue = input->is_aql_queue;
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+index 60a81649cf128..0c4c5499bb5cc 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+@@ -742,7 +742,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 0xbf88fffe, 0x877aff7f,
+ 0x04000000, 0x8f7a857a,
+ 0x886d7a6d, 0xb97b02dc,
+- 0x8f7b997b, 0xb97a2a05,
++ 0x8f7b997b, 0xb97a3a05,
+ 0x807a817a, 0xbf0d997b,
+ 0xbf850002, 0x8f7a897a,
+ 0xbf820001, 0x8f7a8a7a,
+@@ -819,7 +819,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 0xbefe037c, 0xbefc0370,
+ 0xf4611c7a, 0xf8000000,
+ 0x80708470, 0xbefc037e,
+- 0xb9702a05, 0x80708170,
++ 0xb9703a05, 0x80708170,
+ 0xbf0d9973, 0xbf850002,
+ 0x8f708970, 0xbf820001,
+ 0x8f708a70, 0xb97a1e06,
+@@ -1069,7 +1069,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 0xb9f9f816, 0x876f7bff,
+ 0xfffff800, 0x906f8b6f,
+ 0xb9efa2c3, 0xb9f3f801,
+- 0xb96e2a05, 0x806e816e,
++ 0xb96e3a05, 0x806e816e,
+ 0xbf0d9972, 0xbf850002,
+ 0x8f6e896e, 0xbf820001,
+ 0x8f6e8a6e, 0xb96f1e06,
+@@ -2114,7 +2114,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 0x007a0000, 0x7e000280,
+ 0xbefe037a, 0xbeff037b,
+ 0xb97b02dc, 0x8f7b997b,
+- 0xb97a2a05, 0x807a817a,
++ 0xb97a3a05, 0x807a817a,
+ 0xbf0d997b, 0xbf850002,
+ 0x8f7a897a, 0xbf820001,
+ 0x8f7a8a7a, 0xb97b1e06,
+@@ -2157,7 +2157,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 0x01000000, 0xe0704100,
+ 0x705d0100, 0xe0704200,
+ 0x705d0200, 0xe0704300,
+- 0x705d0300, 0xb9702a05,
++ 0x705d0300, 0xb9703a05,
+ 0x80708170, 0xbf0d9973,
+ 0xbf850002, 0x8f708970,
+ 0xbf820001, 0x8f708a70,
+@@ -2189,7 +2189,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 0xbefe03ff, 0x0000ffff,
+ 0xbeff0380, 0xe0704000,
+ 0x705d0200, 0xbefe03c1,
+- 0xb9702a05, 0x80708170,
++ 0xb9703a05, 0x80708170,
+ 0xbf0d9973, 0xbf850002,
+ 0x8f708970, 0xbf820001,
+ 0x8f708a70, 0xb97a1e06,
+@@ -2475,7 +2475,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 0xb9ef4803, 0x876f7bff,
+ 0xfffff800, 0x906f8b6f,
+ 0xb9efa2c3, 0xb9f3f801,
+- 0xb96e2a05, 0x806e816e,
++ 0xb96e3a05, 0x806e816e,
+ 0xbf0d9972, 0xbf850002,
+ 0x8f6e896e, 0xbf820001,
+ 0x8f6e8a6e, 0xb96f1e06,
+@@ -2494,11 +2494,13 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 0xbf9f0000, 0xbf9f0000,
+ 0xbf9f0000, 0x00000000,
+ };
+-
+ static const uint32_t cwsr_trap_gfx11_hex[] = {
+- 0xbfa00001, 0xbfa0021b,
++ 0xbfa00001, 0xbfa00221,
+ 0xb0804006, 0xb8f8f802,
+- 0x91788678, 0xb8fbf803,
++ 0x9178ff78, 0x00020006,
++ 0xb8fbf803, 0xbf0d9e6d,
++ 0xbfa10001, 0xbfbd0000,
++ 0xbf0d9f6d, 0xbfa20006,
+ 0x8b6eff78, 0x00002000,
+ 0xbfa10009, 0x8b6eff6d,
+ 0x00ff0000, 0xbfa2001e,
+@@ -2766,7 +2768,7 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 0x701d0000, 0x807d817d,
+ 0x8070ff70, 0x00000080,
+ 0xbf0a7b7d, 0xbfa2fff8,
+- 0xbfa00141, 0xbef4007e,
++ 0xbfa00146, 0xbef4007e,
+ 0x8b75ff7f, 0x0000ffff,
+ 0x8c75ff75, 0x00040000,
+ 0xbef60080, 0xbef700ff,
+@@ -2926,8 +2928,11 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 0xf8000074, 0xbf89fc07,
+ 0x8b6dff6d, 0x0000ffff,
+ 0x8bfe7e7e, 0x8bea6a6a,
+- 0xb97af802, 0xbe804a6c,
+- 0xbfb00000, 0xbf9f0000,
++ 0xb8eef802, 0xbf0d866e,
++ 0xbfa20002, 0xb97af802,
++ 0xbe80486c, 0xb97af802,
++ 0xbe804a6c, 0xbfb00000,
+ 0xbf9f0000, 0xbf9f0000,
+ 0xbf9f0000, 0xbf9f0000,
++ 0xbf9f0000, 0x00000000,
+ };
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+index 250ab007399bd..8b92c33c2a7c5 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+@@ -43,12 +43,14 @@
+ #define HAVE_XNACK (ASIC_FAMILY < CHIP_SIENNA_CICHLID)
+ #define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+ #define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO)
++#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+
+ var SINGLE_STEP_MISSED_WORKAROUND = 1 //workaround for lost MODE.DEBUG_EN exception when SAVECTX raised
+
+ var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006
+ var SQ_WAVE_STATUS_HALT_MASK = 0x2000
+ var SQ_WAVE_STATUS_ECC_ERR_MASK = 0x20000
++var SQ_WAVE_STATUS_TRAP_EN_SHIFT = 6
+
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE = 9
+@@ -183,6 +185,19 @@ L_SKIP_RESTORE:
+
+ s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
+
++#if SW_SA_TRAP
++ // If ttmp1[30] is set then issue s_barrier to unblock dependent waves.
++ s_bitcmp1_b32 s_save_pc_hi, 30
++ s_cbranch_scc0 L_TRAP_NO_BARRIER
++ s_barrier
++
++L_TRAP_NO_BARRIER:
++ // If ttmp1[31] is set then trap may occur early.
++ // Spin wait until SAVECTX exception is raised.
++ s_bitcmp1_b32 s_save_pc_hi, 31
++ s_cbranch_scc1 L_CHECK_SAVE
++#endif
++
+ s_and_b32 ttmp2, s_save_status, SQ_WAVE_STATUS_HALT_MASK
+ s_cbranch_scc0 L_NOT_HALTED
+
+@@ -1061,8 +1076,20 @@ L_RESTORE_HWREG:
+ s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS
+ s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32
+ s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32
++
++#if SW_SA_TRAP
++ // If traps are enabled then return to the shader with PRIV=0.
++ // Otherwise retain PRIV=1 for subsequent context save requests.
++ s_getreg_b32 s_restore_tmp, hwreg(HW_REG_STATUS)
++ s_bitcmp1_b32 s_restore_tmp, SQ_WAVE_STATUS_TRAP_EN_SHIFT
++ s_cbranch_scc1 L_RETURN_WITHOUT_PRIV
++
+ s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu
++ s_setpc_b64 [s_restore_pc_lo, s_restore_pc_hi]
++L_RETURN_WITHOUT_PRIV:
++#endif
+
++ s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu
+ s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution
+
+ L_END_PGM:
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 7f8eb09b0b7cb..4b16d9d1e058c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1371,7 +1371,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
+ },
+ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
++ },
++ },
+ {}
++ /* TODO: refactor this from a fixed table to a dynamic option */
+ };
+
+ static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
+@@ -7650,9 +7687,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ bundle->surface_updates[planes_count].plane_info =
+ &bundle->plane_infos[planes_count];
+
+- fill_dc_dirty_rects(plane, old_plane_state, new_plane_state,
+- new_crtc_state,
+- &bundle->flip_addrs[planes_count]);
++ if (acrtc_state->stream->link->psr_settings.psr_feature_enabled)
++ fill_dc_dirty_rects(plane, old_plane_state,
++ new_plane_state, new_crtc_state,
++ &bundle->flip_addrs[planes_count]);
+
+ /*
+ * Only allow immediate flips for fast updates that don't
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index dbf8158b832e4..fcddf60d3c10d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -746,6 +746,9 @@ struct dc_debug_options {
+ bool force_disable_subvp;
+ bool force_subvp_mclk_switch;
+ bool allow_sw_cursor_fallback;
++ unsigned int force_subvp_num_ways;
++ unsigned int force_mall_ss_num_ways;
++ bool alloc_extra_way_for_cursor;
+ bool force_usr_allow;
+ /* uses value at boot and disables switch */
+ bool disable_dtb_ref_clk_switch;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+index 1b70b78e2fa15..af631085e88c5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+@@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = {
+ audio_regs(2),
+ audio_regs(3),
+ audio_regs(4),
+- audio_regs(5)
++ audio_regs(5),
++ audio_regs(6),
+ };
+
+ #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
+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 c72166e096bad..bbc0bfbec6c42 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -49,6 +49,7 @@
+ #include "dcn20/dcn20_optc.h"
+ #include "dmub_subvp_state.h"
+ #include "dce/dmub_hw_lock_mgr.h"
++#include "dcn32_resource.h"
+ #include "dc_link_dp.h"
+ #include "dmub/inc/dmub_subvp_state.h"
+
+@@ -198,42 +199,6 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
+ return false;
+ }
+
+-/* This function takes in the start address and surface size to be cached in CAB
+- * and calculates the total number of cache lines required to store the surface.
+- * The number of cache lines used for each surface is calculated independently of
+- * one another. For example, if there is a primary surface(1), meta surface(2), and
+- * cursor(3), this function should be called 3 times to calculate the number of cache
+- * lines used for each of those surfaces.
+- */
+-static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address)
+-{
+- uint32_t lines_used = 1;
+- uint32_t num_cached_bytes = 0;
+- uint32_t remaining_size = 0;
+- uint32_t cache_line_size = dc->caps.cache_line_size;
+- uint32_t remainder = 0;
+-
+- /* 1. Calculate surface size minus the number of bytes stored
+- * in the first cache line (all bytes in first cache line might
+- * not be fully used).
+- */
+- div_u64_rem(start_address, cache_line_size, &remainder);
+- num_cached_bytes = cache_line_size - remainder;
+- remaining_size = surface_size - num_cached_bytes;
+-
+- /* 2. Calculate number of cache lines that will be fully used with
+- * the remaining number of bytes to be stored.
+- */
+- lines_used += (remaining_size / cache_line_size);
+-
+- /* 3. Check if we need an extra line due to the remaining size not being
+- * a multiple of CACHE_LINE_SIZE.
+- */
+- if (remaining_size % cache_line_size > 0)
+- lines_used++;
+-
+- return lines_used;
+-}
+
+ /* This function loops through every surface that needs to be cached in CAB for SS,
+ * and calculates the total number of ways required to store all surfaces (primary,
+@@ -241,94 +206,115 @@ static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_si
+ */
+ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
+ {
+- uint8_t i, j;
++ uint8_t i;
++ int j;
+ struct dc_stream_state *stream = NULL;
+ struct dc_plane_state *plane = NULL;
+- uint32_t surface_size = 0;
+ uint32_t cursor_size = 0;
+- uint32_t cache_lines_used = 0;
+ uint32_t total_lines = 0;
+ uint32_t lines_per_way = 0;
+- uint32_t num_ways = 0;
+- uint32_t prev_addr_low = 0;
++ uint8_t num_ways = 0;
++ uint8_t bytes_per_pixel = 0;
++ uint8_t cursor_bpp = 0;
++ uint16_t mblk_width = 0;
++ uint16_t mblk_height = 0;
++ uint16_t mall_alloc_width_blk_aligned = 0;
++ uint16_t mall_alloc_height_blk_aligned = 0;
++ uint16_t num_mblks = 0;
++ uint32_t bytes_in_mall = 0;
++ uint32_t cache_lines_used = 0;
++ uint32_t cache_lines_per_plane = 0;
+
+- for (i = 0; i < ctx->stream_count; i++) {
+- stream = ctx->streams[i];
++ for (i = 0; i < dc->res_pool->pipe_count; i++) {
++ struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+- // Don't include PSR surface in the total surface size for CAB allocation
+- if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
++ if (!pipe->stream || !pipe->plane_state ||
++ pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED ||
++ pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
+ continue;
+
+- if (ctx->stream_status[i].plane_count == 0)
+- continue;
++ bytes_per_pixel = pipe->plane_state->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4;
++ mblk_width = DCN3_2_MBLK_WIDTH;
++ mblk_height = bytes_per_pixel == 4 ? DCN3_2_MBLK_HEIGHT_4BPE : DCN3_2_MBLK_HEIGHT_8BPE;
+
+- // For each stream, loop through each plane to calculate the number of cache
+- // lines required to store the surface in CAB
+- for (j = 0; j < ctx->stream_status[i].plane_count; j++) {
+- plane = ctx->stream_status[i].plane_states[j];
++ /* full_vp_width_blk_aligned = FLOOR(vp_x_start + full_vp_width + blk_width - 1, blk_width) -
++ * FLOOR(vp_x_start, blk_width)
++ *
++ * mall_alloc_width_blk_aligned_l/c = full_vp_width_blk_aligned_l/c
++ */
++ mall_alloc_width_blk_aligned = ((pipe->plane_res.scl_data.viewport.x +
++ pipe->plane_res.scl_data.viewport.width + mblk_width - 1) / mblk_width * mblk_width) +
++ (pipe->plane_res.scl_data.viewport.x / mblk_width * mblk_width);
++
++ /* full_vp_height_blk_aligned = FLOOR(vp_y_start + full_vp_height + blk_height - 1, blk_height) -
++ * FLOOR(vp_y_start, blk_height)
++ *
++ * mall_alloc_height_blk_aligned_l/c = full_vp_height_blk_aligned_l/c
++ */
++ mall_alloc_height_blk_aligned = ((pipe->plane_res.scl_data.viewport.y +
++ pipe->plane_res.scl_data.viewport.height + mblk_height - 1) / mblk_height * mblk_height) +
++ (pipe->plane_res.scl_data.viewport.y / mblk_height * mblk_height);
+
+- // Calculate total surface size
+- if (prev_addr_low != plane->address.grph.addr.u.low_part) {
+- /* if plane address are different from prev FB, then userspace allocated separate FBs*/
+- surface_size += plane->plane_size.surface_pitch *
+- plane->plane_size.surface_size.height *
+- (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
++ num_mblks = ((mall_alloc_width_blk_aligned + mblk_width - 1) / mblk_width) *
++ ((mall_alloc_height_blk_aligned + mblk_height - 1) / mblk_height);
+
+- prev_addr_low = plane->address.grph.addr.u.low_part;
+- } else {
+- /* We have the same fb for all the planes.
+- * Xorg always creates one giant fb that holds all surfaces,
+- * so allocating it once is sufficient.
+- * */
+- continue;
+- }
+- // Convert surface size + starting address to number of cache lines required
+- // (alignment accounted for)
+- cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+- plane->address.grph.addr.quad_part);
+-
+- if (plane->address.grph.meta_addr.quad_part) {
+- // Meta surface
+- cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+- plane->address.grph.meta_addr.quad_part);
+- }
+- }
++ /* For DCC:
++ * meta_num_mblk = CEILING(full_mblk_width_ub_l*full_mblk_height_ub_l*Bpe/256/mblk_bytes, 1)
++ */
++ if (pipe->plane_state->dcc.enable)
++ num_mblks += (mall_alloc_width_blk_aligned * mall_alloc_width_blk_aligned * bytes_per_pixel +
++ (256 * DCN3_2_MALL_MBLK_SIZE_BYTES) - 1) / (256 * DCN3_2_MALL_MBLK_SIZE_BYTES);
+
+- // Include cursor size for CAB allocation
+- for (j = 0; j < dc->res_pool->pipe_count; j++) {
+- struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
+- struct hubp *hubp = pipe->plane_res.hubp;
++ bytes_in_mall = num_mblks * DCN3_2_MALL_MBLK_SIZE_BYTES;
+
+- if (pipe->stream && pipe->plane_state && hubp)
+- /* Find the cursor plane and use the exact size instead of
+- * using the max for calculation
+- */
+- if (hubp->curs_attr.width > 0) {
+- cursor_size = hubp->curs_attr.width * hubp->curs_attr.height;
+- break;
+- }
+- }
++ /* (cache lines used is total bytes / cache_line size. Add +2 for worst case alignment
++ * (MALL is 64-byte aligned)
++ */
++ cache_lines_per_plane = bytes_in_mall / dc->caps.cache_line_size + 2;
++ cache_lines_used += cache_lines_per_plane;
++ }
+
+- switch (stream->cursor_attributes.color_format) {
+- case CURSOR_MODE_MONO:
+- cursor_size /= 2;
+- break;
+- case CURSOR_MODE_COLOR_1BIT_AND:
+- case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+- case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+- cursor_size *= 4;
+- break;
++ // Include cursor size for CAB allocation
++ for (j = 0; j < dc->res_pool->pipe_count; j++) {
++ struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
++ struct hubp *hubp = pipe->plane_res.hubp;
+
+- case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+- case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+- cursor_size *= 8;
+- break;
+- }
++ if (pipe->stream && pipe->plane_state && hubp)
++ /* Find the cursor plane and use the exact size instead of
++ using the max for calculation */
+
+- if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) {
+- cache_lines_used += dcn32_cache_lines_for_surface(dc, cursor_size,
+- plane->address.grph.cursor_cache_addr.quad_part);
+- }
++ if (hubp->curs_attr.width > 0) {
++ cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
++
++ switch (pipe->stream->cursor_attributes.color_format) {
++ case CURSOR_MODE_MONO:
++ cursor_size /= 2;
++ cursor_bpp = 4;
++ break;
++ case CURSOR_MODE_COLOR_1BIT_AND:
++ case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
++ case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
++ cursor_size *= 4;
++ cursor_bpp = 4;
++ break;
++
++ case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
++ case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
++ cursor_size *= 8;
++ cursor_bpp = 8;
++ break;
++ }
++
++ if (pipe->stream->cursor_position.enable && !dc->debug.alloc_extra_way_for_cursor &&
++ cursor_size > 16384) {
++ /* cursor_num_mblk = CEILING(num_cursors*cursor_width*cursor_width*cursor_Bpe/mblk_bytes, 1)
++ */
++ cache_lines_used += (((cursor_size + DCN3_2_MALL_MBLK_SIZE_BYTES - 1) /
++ DCN3_2_MALL_MBLK_SIZE_BYTES) * DCN3_2_MALL_MBLK_SIZE_BYTES) /
++ dc->caps.cache_line_size + 2;
++ }
++ break;
++ }
+ }
+
+ // Convert number of cache lines required to number of ways
+@@ -345,8 +331,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ plane = ctx->stream_status[i].plane_states[j];
+
+ if (stream->cursor_position.enable && plane &&
+- !plane->address.grph.cursor_cache_addr.quad_part &&
+- cursor_size > 16384) {
++ dc->debug.alloc_extra_way_for_cursor &&
++ cursor_size > 16384) {
+ /* Cursor caching is not supported since it won't be on the same line.
+ * So we need an extra line to accommodate it. With large cursors and a single 4k monitor
+ * this case triggers corruption. If we're at the edge, then dont trigger display refresh
+@@ -358,7 +344,9 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ }
+ }
+ }
+-
++ if (dc->debug.force_mall_ss_num_ways > 0) {
++ num_ways = dc->debug.force_mall_ss_num_ways;
++ }
+ return num_ways;
+ }
+
+@@ -741,10 +729,7 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
+ struct hubp *hubp = pipe->plane_res.hubp;
+
+ if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
+- //Round cursor width up to next multiple of 64
+- int cursor_width = ((hubp->curs_attr.width + 63) / 64) * 64;
+- int cursor_height = hubp->curs_attr.height;
+- int cursor_size = cursor_width * cursor_height;
++ int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
+
+ switch (hubp->curs_attr.color_format) {
+ case CURSOR_MODE_MONO:
+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 c3b783cea8a03..6f1bcb45a3b2d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+@@ -872,6 +872,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ .enable_single_display_2to1_odm_policy = true,
+ .enable_dp_dig_pixel_rate_div_policy = 1,
+ .allow_sw_cursor_fallback = false,
++ .alloc_extra_way_for_cursor = true,
+ };
+
+ static const struct dc_debug_options debug_defaults_diags = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 13cd1f2e50ca3..7c37575d69c73 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -54,13 +54,14 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ uint32_t num_mblks = 0;
+ uint32_t cache_lines_per_plane = 0;
+ uint32_t i = 0, j = 0;
+- uint32_t mblk_width = 0;
+- uint32_t mblk_height = 0;
++ uint16_t mblk_width = 0;
++ uint16_t mblk_height = 0;
+ uint32_t full_vp_width_blk_aligned = 0;
+ uint32_t full_vp_height_blk_aligned = 0;
+ uint32_t mall_alloc_width_blk_aligned = 0;
+ uint32_t mall_alloc_height_blk_aligned = 0;
+- uint32_t full_vp_height = 0;
++ uint16_t full_vp_height = 0;
++ bool subvp_in_use = false;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+@@ -70,6 +71,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+ struct pipe_ctx *main_pipe = NULL;
+
++ subvp_in_use = true;
+ /* Get full viewport height from main pipe (required for MBLK calculation) */
+ for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ main_pipe = &context->res_ctx.pipe_ctx[j];
+@@ -129,6 +131,9 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ if (cache_lines_used % lines_per_way > 0)
+ num_ways++;
+
++ if (subvp_in_use && dc->debug.force_subvp_num_ways > 0)
++ num_ways = dc->debug.force_subvp_num_ways;
++
+ return num_ways;
+ }
+
+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 7309eed33a61c..d074716dc1972 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+@@ -873,6 +873,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ .enable_single_display_2to1_odm_policy = true,
+ .enable_dp_dig_pixel_rate_div_policy = 1,
+ .allow_sw_cursor_fallback = false,
++ .alloc_extra_way_for_cursor = true,
+ };
+
+ static const struct dc_debug_options debug_defaults_diags = {
+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 b9d3a4000c3d4..2f996fdaa70dd 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
+@@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
+ .dispclk_dppclk_vco_speed_mhz = 4300.0,
+ .do_urgent_latency_adjustment = true,
+ .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+- .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++ .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+
+ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+@@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ /* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */
+ if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true;
+- clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38;
++ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
+@@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
+ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
+ clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16;
+- clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
++ clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;
+ clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16;
+ clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
+ clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16;
+@@ -1700,6 +1700,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ */
+ context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
++ /* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so
++ * prefetch is scheduled correctly to account for dummy pstate.
++ */
++ if (dummy_latency_index == 0)
++ context->bw_ctx.dml.soc.fclk_change_latency_us =
++ dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
+ dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
+ maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
+ dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+@@ -1879,6 +1885,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+
+ context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
+
++ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0)
++ context->bw_ctx.dml.soc.fclk_change_latency_us =
++ dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
++
+ dcn32_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+
+ if (!pstate_en)
+@@ -1886,8 +1896,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
+
+- if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
++ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+ dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
++ if (dummy_latency_index == 0)
++ context->bw_ctx.dml.soc.fclk_change_latency_us =
++ dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us;
++ }
+ }
+
+ static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index bea380407151a..042f9a62c4c50 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -3197,6 +3197,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.FCLKChangeLatency, mode_lib->vba.UrgLatency[i],
+ mode_lib->vba.SREnterPlusExitTime);
+
++ memset(&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull, 0, sizeof(DmlPipe));
+ v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dppclk = mode_lib->vba.RequiredDPPCLK[i][j][k];
+ v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dispclk = mode_lib->vba.RequiredDISPCLK[i][j];
+ v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 67af8f4df8b8f..d9141ef2fefdd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -4396,7 +4396,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
+
+ if (v->NumberOfActiveSurfaces > 1) {
+ ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY
+- - (1 - 1 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
++ - (1.0 - 1.0 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
+ / v->PixelClock[k] / v->VRatio[k];
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+index 0b427d89b3c5d..f174f5c5ff921 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+@@ -30,7 +30,7 @@
+ #include "os_types.h"
+ #include "../dc_features.h"
+ #include "../display_mode_structs.h"
+-#include "dml/display_mode_vba.h"
++#include "../display_mode_vba.h"
+
+ unsigned int dml32_dscceComputeDelay(
+ unsigned int bpc,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index aa976fe4d426d..0ab8e48b68416 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -125,9 +125,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ .sr_enter_plus_exit_z8_time_us = 320,
+ .writeback_latency_us = 12.0,
+ .round_trip_ping_latency_dcfclk_cycles = 263,
+- .urgent_latency_pixel_data_only_us = 9.35,
+- .urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
+- .urgent_latency_vm_data_only_us = 9.35,
++ .urgent_latency_pixel_data_only_us = 4,
++ .urgent_latency_pixel_mixed_with_vm_data_us = 4,
++ .urgent_latency_vm_data_only_us = 4,
+ .fclk_change_latency_us = 20,
+ .usr_retraining_latency_us = 2,
+ .smn_latency_us = 2,
+@@ -155,7 +155,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ .dispclk_dppclk_vco_speed_mhz = 4300.0,
+ .do_urgent_latency_adjustment = true,
+ .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+- .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++ .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+
+ static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+index d635b73af46fe..0ea52ba5ac827 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+@@ -107,6 +107,13 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
+ ddc_data_regs_dcn2(3),
+ ddc_data_regs_dcn2(4),
+ ddc_data_regs_dcn2(5),
++ {
++ // add a dummy entry for cases no such port
++ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++ .ddc_setup = 0,
++ .phy_aux_cntl = 0,
++ .dc_gpio_aux_ctrl_5 = 0
++ },
+ {
+ DDC_GPIO_VGA_REG_LIST(DATA),
+ .ddc_setup = 0,
+@@ -121,6 +128,13 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
+ ddc_clk_regs_dcn2(3),
+ ddc_clk_regs_dcn2(4),
+ ddc_clk_regs_dcn2(5),
++ {
++ // add a dummy entry for cases no such port
++ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++ .ddc_setup = 0,
++ .phy_aux_cntl = 0,
++ .dc_gpio_aux_ctrl_5 = 0
++ },
+ {
+ DDC_GPIO_VGA_REG_LIST(CLK),
+ .ddc_setup = 0,
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+index 6fd38cdd68c0c..525bc8881950d 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+@@ -94,11 +94,14 @@ static enum gpio_result set_config(
+ * is required for detection of AUX mode */
+ if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
+ if (!ddc_data_pd_en || !ddc_clk_pd_en) {
+-
+- REG_SET_2(gpio.MASK_reg, regval,
++ if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) {
++ // bit 4 of mask has different usage in some cases
++ REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1);
++ } else {
++ REG_SET_2(gpio.MASK_reg, regval,
+ DC_GPIO_DDC1DATA_PD_EN, 1,
+ DC_GPIO_DDC1CLK_PD_EN, 1);
+-
++ }
+ if (config_data->type ==
+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+ msleep(3);
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+index dad3e3741a4e8..190af79f3236f 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+@@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
+ int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
+ uint32_t *speed)
+ {
+- uint32_t current_rpm;
+- uint32_t percent = 0;
+-
+- if (hwmgr->thermal_controller.fanInfo.bNoFan)
+- return 0;
++ struct amdgpu_device *adev = hwmgr->adev;
++ uint32_t duty100, duty;
++ uint64_t tmp64;
+
+- if (vega10_get_current_rpm(hwmgr, ¤t_rpm))
+- return -1;
++ duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
++ CG_FDO_CTRL1, FMAX_DUTY100);
++ duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
++ CG_THERMAL_STATUS, FDO_PWM_DUTY);
+
+- if (hwmgr->thermal_controller.
+- advanceFanControlParameters.usMaxFanRPM != 0)
+- percent = current_rpm * 255 /
+- hwmgr->thermal_controller.
+- advanceFanControlParameters.usMaxFanRPM;
++ if (!duty100)
++ return -EINVAL;
+
+- *speed = MIN(percent, 255);
++ tmp64 = (uint64_t)duty * 255;
++ do_div(tmp64, duty100);
++ *speed = MIN((uint32_t)tmp64, 255);
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index 8292839bc42a9..9ce0dcc5bb90a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -378,6 +378,10 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
+ ((adev->pdev->device == 0x73BF) &&
+ (adev->pdev->revision == 0xCF)) ||
+ ((adev->pdev->device == 0x7422) &&
++ (adev->pdev->revision == 0x00)) ||
++ ((adev->pdev->device == 0x73A3) &&
++ (adev->pdev->revision == 0x00)) ||
++ ((adev->pdev->device == 0x73E3) &&
+ (adev->pdev->revision == 0x00)))
+ smu_baco->platform_support = false;
+
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 7a94a5288e8d7..855297e69f04c 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -5293,7 +5293,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
+ mst_state = drm_atomic_get_mst_topology_state(state, mgr);
+
+ if (IS_ERR(mst_state))
+- return -EINVAL;
++ return PTR_ERR(mst_state);
+
+ list_for_each_entry(pos, &mst_state->vcpis, next) {
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 8a0c0e0bb5bd2..52d8800a8ab86 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -134,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ },
+ .driver_data = (void *)&lcd800x1280_rightside_up,
++ }, { /* Acer Switch V 10 (SW5-017) */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++ },
++ .driver_data = (void *)&lcd800x1280_rightside_up,
+ }, { /* Anbernic Win600 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
+@@ -319,6 +325,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+ },
+ .driver_data = (void *)&lcd1200x1920_rightside_up,
++ }, { /* Nanote UMPC-01 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++ },
++ .driver_data = (void *)&lcd1200x1920_rightside_up,
+ }, { /* OneGX1 Pro */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
+diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
+index 589af257edebc..3bb113b42cfa2 100644
+--- a/drivers/gpu/drm/i915/display/intel_display_power.c
++++ b/drivers/gpu/drm/i915/display/intel_display_power.c
+@@ -2427,7 +2427,7 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
+ {
+ const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+
+- if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID)
++ if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID))
+ return POWER_DOMAIN_PORT_DDI_IO_A;
+
+ return domains->ddi_io + (int)(port - domains->port_start);
+@@ -2438,7 +2438,7 @@ intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port po
+ {
+ const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+
+- if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID)
++ if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID))
+ return POWER_DOMAIN_PORT_DDI_LANES_A;
+
+ return domains->ddi_lanes + (int)(port - domains->port_start);
+@@ -2464,7 +2464,7 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch
+ {
+ const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+
+- if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)
++ if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID))
+ return POWER_DOMAIN_AUX_A;
+
+ return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start);
+@@ -2475,7 +2475,7 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au
+ {
+ const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+
+- if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID)
++ if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID))
+ return POWER_DOMAIN_AUX_TBT1;
+
+ return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+index e85cfc36359a4..f5a803060515c 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+@@ -642,6 +642,10 @@ static int i915_ttm_truncate(struct drm_i915_gem_object *obj)
+
+ WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED);
+
++ err = ttm_bo_wait(bo, true, false);
++ if (err)
++ return err;
++
+ err = i915_ttm_move_notify(bo);
+ if (err)
+ return err;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
+index f435e06125aab..f158f6a08e757 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt.c
+@@ -961,6 +961,11 @@ static void mmio_invalidate_full(struct intel_gt *gt)
+ if (!i915_mmio_reg_offset(rb.reg))
+ continue;
+
++ if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS ||
++ engine->class == VIDEO_ENHANCEMENT_CLASS ||
++ engine->class == COMPUTE_CLASS))
++ rb.bit = _MASKED_BIT_ENABLE(rb.bit);
++
+ intel_uncore_write_fw(uncore, rb.reg, rb.bit);
+ awake |= engine->mask;
+ }
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index de89946c4817f..f671ae5a3b7b4 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -765,8 +765,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+ return -ESRCH;
+ }
+
+- kvm_get_kvm(vgpu->vfio_device.kvm);
+-
+ if (__kvmgt_vgpu_exist(vgpu))
+ return -EEXIST;
+
+@@ -777,6 +775,7 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+
+ vgpu->track_node.track_write = kvmgt_page_track_write;
+ vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
++ kvm_get_kvm(vgpu->vfio_device.kvm);
+ kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
+ &vgpu->track_node);
+
+diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
+index 6748ec1e00057..a1f909dac89a7 100644
+--- a/drivers/gpu/drm/tegra/drm.c
++++ b/drivers/gpu/drm/tegra/drm.c
+@@ -1093,6 +1093,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev)
+ struct host1x *host1x = dev_get_drvdata(dev->dev.parent);
+ struct iommu_domain *domain;
+
++ /* Our IOMMU usage policy doesn't currently play well with GART */
++ if (of_machine_is_compatible("nvidia,tegra20"))
++ return false;
++
+ /*
+ * If the Tegra DRM clients are backed by an IOMMU, push buffers are
+ * likely to be allocated beyond the 32-bit boundary if sufficient
+diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
+index 0cd3f97e7e49f..f60ea24db0ec8 100644
+--- a/drivers/gpu/host1x/dev.c
++++ b/drivers/gpu/host1x/dev.c
+@@ -292,6 +292,10 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
+
+ static bool host1x_wants_iommu(struct host1x *host1x)
+ {
++ /* Our IOMMU usage policy doesn't currently play well with GART */
++ if (of_machine_is_compatible("nvidia,tegra20"))
++ return false;
++
+ /*
+ * If we support addressing a maximum of 32 bits of physical memory
+ * and if the host1x firewall is enabled, there's no need to enable
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 5b120402d4057..cc23b90cae02f 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -533,13 +533,17 @@ static void vmbus_add_channel_work(struct work_struct *work)
+ * Add the new device to the bus. This will kick off device-driver
+ * binding which eventually invokes the device driver's AddDevice()
+ * method.
++ *
++ * If vmbus_device_register() fails, the 'device_obj' is freed in
++ * vmbus_device_release() as called by device_unregister() in the
++ * error path of vmbus_device_register(). In the outside error
++ * path, there's no need to free it.
+ */
+ ret = vmbus_device_register(newchannel->device_obj);
+
+ if (ret != 0) {
+ pr_err("unable to add child device object (relid %d)\n",
+ newchannel->offermsg.child_relid);
+- kfree(newchannel->device_obj);
+ goto err_deq_chan;
+ }
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 3c833ea60db65..939ccf921e71b 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2083,6 +2083,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
+ ret = device_register(&child_device_obj->device);
+ if (ret) {
+ pr_err("Unable to register child device\n");
++ put_device(&child_device_obj->device);
+ return ret;
+ }
+
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 29c9fa99c2bd3..dea438b9eb9e3 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -673,8 +673,10 @@ static int bma400_get_steps_reg(struct bma400_data *data, int *val)
+
+ ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG,
+ steps_raw, BMA400_STEP_RAW_LEN);
+- if (ret)
++ if (ret) {
++ kfree(steps_raw);
+ return ret;
++ }
+ *val = get_unaligned_le24(steps_raw);
+ kfree(steps_raw);
+ return IIO_VAL_INT;
+diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
+index 9341e0e0eb556..998e8bcc06e1d 100644
+--- a/drivers/iio/adc/aspeed_adc.c
++++ b/drivers/iio/adc/aspeed_adc.c
+@@ -202,6 +202,8 @@ static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+ ((scu_otp) &
+ (data->model_data->trim_locate->field)) >>
+ __ffs(data->model_data->trim_locate->field);
++ if (!trimming_val)
++ trimming_val = 0x8;
+ }
+ dev_dbg(data->dev,
+ "trimming val = %d, offset = %08x, fields = %08x\n",
+@@ -563,12 +565,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+- NULL)) {
+- ret = aspeed_adc_set_trim_data(indio_dev);
+- if (ret)
+- return ret;
+- }
++ ret = aspeed_adc_set_trim_data(indio_dev);
++ if (ret)
++ return ret;
+
+ if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
+ NULL)) {
+diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c
+index 994f03a715204..d86a3305d9e8d 100644
+--- a/drivers/iio/industrialio-sw-trigger.c
++++ b/drivers/iio/industrialio-sw-trigger.c
+@@ -58,8 +58,12 @@ int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
+
+ t->group = configfs_register_default_group(iio_triggers_group, t->name,
+ &iio_trigger_type_group_type);
+- if (IS_ERR(t->group))
++ if (IS_ERR(t->group)) {
++ mutex_lock(&iio_trigger_types_lock);
++ list_del(&t->list);
++ mutex_unlock(&iio_trigger_types_lock);
+ ret = PTR_ERR(t->group);
++ }
+
+ return ret;
+ }
+diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
+index 09b831f9f40b6..795224a38bef8 100644
+--- a/drivers/iio/light/apds9960.c
++++ b/drivers/iio/light/apds9960.c
+@@ -54,9 +54,6 @@
+ #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2
+
+ #define APDS9960_REG_CONFIG_2 0x90
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK 0x60
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT 5
+-
+ #define APDS9960_REG_ID 0x92
+
+ #define APDS9960_REG_STATUS 0x93
+@@ -77,6 +74,9 @@
+ #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6
+
+ #define APDS9960_REG_GCONF_2 0xa3
++#define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60
++#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5
++
+ #define APDS9960_REG_GOFFSET_U 0xa4
+ #define APDS9960_REG_GOFFSET_D 0xa5
+ #define APDS9960_REG_GPULSE 0xa6
+@@ -396,9 +396,9 @@ static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
+ }
+
+ ret = regmap_update_bits(data->regmap,
+- APDS9960_REG_CONFIG_2,
+- APDS9960_REG_CONFIG_2_GGAIN_MASK,
+- idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
++ APDS9960_REG_GCONF_2,
++ APDS9960_REG_GCONF_2_GGAIN_MASK,
++ idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT);
+ if (!ret)
+ data->pxs_gain = idx;
+ mutex_unlock(&data->lock);
+diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
+index 480476121c010..09489380afda7 100644
+--- a/drivers/input/misc/soc_button_array.c
++++ b/drivers/input/misc/soc_button_array.c
+@@ -18,6 +18,10 @@
+ #include <linux/gpio.h>
+ #include <linux/platform_device.h>
+
++static bool use_low_level_irq;
++module_param(use_low_level_irq, bool, 0444);
++MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered");
++
+ struct soc_button_info {
+ const char *name;
+ int acpi_index;
+@@ -73,6 +77,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+ },
+ },
++ {
++ /* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++ },
++ },
+ {
+ /*
+ * Acer One S1003. _LID method messes with power-button GPIO
+@@ -164,7 +175,8 @@ soc_button_device_create(struct platform_device *pdev,
+ }
+
+ /* See dmi_use_low_level_irq[] comment */
+- if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) {
++ if (!autorepeat && (use_low_level_irq ||
++ dmi_check_system(dmi_use_low_level_irq))) {
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
+ gpio_keys[n_buttons].irq = irq;
+ gpio_keys[n_buttons].gpio = -ENOENT;
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+index ffad142801b39..973a4c1d5d09f 100644
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -191,6 +191,7 @@ static const char * const smbus_pnp_ids[] = {
+ "SYN3221", /* HP 15-ay000 */
+ "SYN323d", /* HP Spectre X360 13-w013dx */
+ "SYN3257", /* HP Envy 13-ad105ng */
++ "SYN3286", /* HP Laptop 15-da3001TU */
+ NULL
+ };
+
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 4fbec7bbeccaa..5043dc7b8fb3a 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -114,18 +114,18 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
+ },
+ {
+- /* ASUS ZenBook UX425UA */
++ /* ASUS ZenBook UX425UA/QA */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ },
+ {
+- /* ASUS ZenBook UM325UA */
++ /* ASUS ZenBook UM325UA/QA */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ },
+diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
+index 21c0dddbe41d4..25e6ba132bbc2 100644
+--- a/drivers/input/touchscreen/goodix.c
++++ b/drivers/input/touchscreen/goodix.c
+@@ -1158,6 +1158,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+
++retry_read_config:
+ /* Read configuration and apply touchscreen parameters */
+ goodix_read_config(ts);
+
+@@ -1165,6 +1166,16 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
+
+ if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) {
++ if (!ts->reset_controller_at_probe &&
++ ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) {
++ dev_info(&ts->client->dev, "Config not set, resetting controller\n");
++ /* Retry after a controller reset */
++ ts->reset_controller_at_probe = true;
++ error = goodix_reset(ts);
++ if (error)
++ return error;
++ goto retry_read_config;
++ }
+ dev_err(&ts->client->dev,
+ "Invalid config (%d, %d, %d), using defaults\n",
+ ts->prop.max_x, ts->prop.max_y, ts->max_touch_num);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index aaf2472df6e58..e97e9f97456d4 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -263,6 +263,7 @@ struct dm_integrity_c {
+
+ struct completion crypto_backoff;
+
++ bool wrote_to_journal;
+ bool journal_uptodate;
+ bool just_formatted;
+ bool recalculate_flag;
+@@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w)
+ if (!commit_sections)
+ goto release_flush_bios;
+
++ ic->wrote_to_journal = true;
++
+ i = commit_start;
+ for (n = 0; n < commit_sections; n++) {
+ for (j = 0; j < ic->journal_section_entries; j++) {
+@@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w)
+
+ unsigned prev_free_sectors;
+
+- /* the following test is not needed, but it tests the replay code */
+- if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev)
+- return;
+-
+ spin_lock_irq(&ic->endio_wait.lock);
+ write_start = ic->committed_section;
+ write_sections = ic->n_committed_sections;
+@@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
+ drain_workqueue(ic->commit_wq);
+
+ if (ic->mode == 'J') {
+- if (ic->meta_dev)
+- queue_work(ic->writer_wq, &ic->writer_work);
++ queue_work(ic->writer_wq, &ic->writer_work);
+ drain_workqueue(ic->writer_wq);
+ dm_integrity_flush_buffers(ic, true);
++ if (ic->wrote_to_journal) {
++ init_journal(ic, ic->free_section,
++ ic->journal_sections - ic->free_section, ic->commit_seq);
++ if (ic->free_section) {
++ init_journal(ic, 0, ic->free_section,
++ next_commit_seq(ic->commit_seq));
++ }
++ }
+ }
+
+ if (ic->mode == 'B') {
+@@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti)
+
+ DEBUG_print("resume\n");
+
++ ic->wrote_to_journal = false;
++
+ if (ic->provided_data_sectors != old_provided_data_sectors) {
+ if (ic->provided_data_sectors > old_provided_data_sectors &&
+ ic->mode == 'B' &&
+@@ -3370,6 +3378,7 @@ static void dm_integrity_io_hints(struct dm_target *ti, struct queue_limits *lim
+ limits->logical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT);
++ limits->dma_alignment = limits->logical_block_size - 1;
+ }
+ }
+
+diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
+index 20fd688f72e7c..178e13a5b059f 100644
+--- a/drivers/md/dm-log-writes.c
++++ b/drivers/md/dm-log-writes.c
+@@ -875,6 +875,7 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit
+ limits->logical_block_size = bdev_logical_block_size(lc->dev->bdev);
+ limits->physical_block_size = bdev_physical_block_size(lc->dev->bdev);
+ limits->io_min = limits->physical_block_size;
++ limits->dma_alignment = limits->logical_block_size - 1;
+ }
+
+ #if IS_ENABLED(CONFIG_FS_DAX)
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index 24150c933fcbe..dc3253b318daf 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ struct com20020_dev *info;
+ struct net_device *dev;
+ struct arcnet_local *lp;
++ int ret = -ENOMEM;
+
+ dev_dbg(&p_dev->dev, "com20020_attach()\n");
+
+@@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ info->dev = dev;
+ p_dev->priv = info;
+
+- return com20020_config(p_dev);
++ ret = com20020_config(p_dev);
++ if (ret)
++ goto fail_config;
++
++ return 0;
+
++fail_config:
++ free_arcdev(dev);
+ fail_alloc_dev:
+ kfree(info);
+ fail_alloc_info:
+- return -ENOMEM;
++ return ret;
+ } /* com20020_attach */
+
+ static void com20020_detach(struct pcmcia_device *link)
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 86d42306aa5ee..76dd5ff1d99d5 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3231,16 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
+ {
+ struct slave *curr_active_slave, *curr_arp_slave;
+- struct icmp6hdr *hdr = icmp6_hdr(skb);
+ struct in6_addr *saddr, *daddr;
++ struct {
++ struct ipv6hdr ip6;
++ struct icmp6hdr icmp6;
++ } *combined, _combined;
+
+ if (skb->pkt_type == PACKET_OTHERHOST ||
+- skb->pkt_type == PACKET_LOOPBACK ||
+- hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
++ skb->pkt_type == PACKET_LOOPBACK)
++ goto out;
++
++ combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined);
++ if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP ||
++ combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+ goto out;
+
+- saddr = &ipv6_hdr(skb)->saddr;
+- daddr = &ipv6_hdr(skb)->daddr;
++ saddr = &combined->ip6.saddr;
++ daddr = &combined->ip6.saddr;
+
+ slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
+ __func__, slave->dev->name, bond_slave_state(slave),
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index cd4115a1b81c6..0deac073d9cfa 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -268,8 +268,6 @@ struct gs_can {
+
+ struct usb_anchor tx_submitted;
+ atomic_t active_tx_urbs;
+- void *rxbuf[GS_MAX_RX_URBS];
+- dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
+ };
+
+ /* usb interface struct */
+@@ -587,9 +585,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
+
+ if (urb->status)
+ netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
+-
+- usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+- urb->transfer_buffer, urb->transfer_dma);
+ }
+
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+@@ -618,8 +613,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ if (!urb)
+ goto nomem_urb;
+
+- hf = usb_alloc_coherent(dev->udev, dev->hf_size_tx, GFP_ATOMIC,
+- &urb->transfer_dma);
++ hf = kmalloc(dev->hf_size_tx, GFP_ATOMIC);
+ if (!hf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ goto nomem_hf;
+@@ -663,7 +657,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ hf, dev->hf_size_tx,
+ gs_usb_xmit_callback, txc);
+
+- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++ urb->transfer_flags |= URB_FREE_BUFFER;
+ usb_anchor_urb(urb, &dev->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, idx, 0);
+@@ -678,8 +672,6 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ gs_free_tx_context(txc);
+
+ usb_unanchor_urb(urb);
+- usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+- urb->transfer_buffer, urb->transfer_dma);
+
+ if (rc == -ENODEV) {
+ netif_device_detach(netdev);
+@@ -699,8 +691,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ return NETDEV_TX_OK;
+
+ badidx:
+- usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+- urb->transfer_buffer, urb->transfer_dma);
++ kfree(hf);
+ nomem_hf:
+ usb_free_urb(urb);
+
+@@ -744,7 +735,6 @@ static int gs_can_open(struct net_device *netdev)
+ for (i = 0; i < GS_MAX_RX_URBS; i++) {
+ struct urb *urb;
+ u8 *buf;
+- dma_addr_t buf_dma;
+
+ /* alloc rx urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -752,10 +742,8 @@ static int gs_can_open(struct net_device *netdev)
+ return -ENOMEM;
+
+ /* alloc rx buffer */
+- buf = usb_alloc_coherent(dev->udev,
+- dev->parent->hf_size_rx,
+- GFP_KERNEL,
+- &buf_dma);
++ buf = kmalloc(dev->parent->hf_size_rx,
++ GFP_KERNEL);
+ if (!buf) {
+ netdev_err(netdev,
+ "No memory left for USB buffer\n");
+@@ -763,8 +751,6 @@ static int gs_can_open(struct net_device *netdev)
+ return -ENOMEM;
+ }
+
+- urb->transfer_dma = buf_dma;
+-
+ /* fill, anchor, and submit rx urb */
+ usb_fill_bulk_urb(urb,
+ dev->udev,
+@@ -773,7 +759,7 @@ static int gs_can_open(struct net_device *netdev)
+ buf,
+ dev->parent->hf_size_rx,
+ gs_usb_receive_bulk_callback, parent);
+- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &parent->rx_submitted);
+
+@@ -786,17 +772,10 @@ static int gs_can_open(struct net_device *netdev)
+ "usb_submit failed (err=%d)\n", rc);
+
+ usb_unanchor_urb(urb);
+- usb_free_coherent(dev->udev,
+- sizeof(struct gs_host_frame),
+- buf,
+- buf_dma);
+ usb_free_urb(urb);
+ break;
+ }
+
+- dev->rxbuf[i] = buf;
+- dev->rxbuf_dma[i] = buf_dma;
+-
+ /* Drop reference,
+ * USB core will take care of freeing it
+ */
+@@ -854,7 +833,6 @@ static int gs_can_close(struct net_device *netdev)
+ int rc;
+ struct gs_can *dev = netdev_priv(netdev);
+ struct gs_usb *parent = dev->parent;
+- unsigned int i;
+
+ netif_stop_queue(netdev);
+
+@@ -862,11 +840,6 @@ static int gs_can_close(struct net_device *netdev)
+ parent->active_channels--;
+ if (!parent->active_channels) {
+ usb_kill_anchored_urbs(&parent->rx_submitted);
+- for (i = 0; i < GS_MAX_RX_URBS; i++)
+- usb_free_coherent(dev->udev,
+- sizeof(struct gs_host_frame),
+- dev->rxbuf[i],
+- dev->rxbuf_dma[i]);
+ }
+
+ /* Stop sending URBs */
+diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
+index 215dd17ca7906..4059fcc8c8326 100644
+--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
++++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
+@@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
+ u32 tmp;
+ int rc;
+
++ if (reg & MII_ADDR_C45)
++ return -EOPNOTSUPP;
++
+ rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
+ &tmp, NULL);
+ if (rc < 0)
+@@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
+ const struct sja1105_regs *regs = priv->info->regs;
+ u32 tmp = val;
+
++ if (reg & MII_ADDR_C45)
++ return -EOPNOTSUPP;
++
+ return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
+ &tmp, NULL);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+index 11d15cd036005..77d4cb4ad7823 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+@@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
+
+ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
+ {
+- struct pci_dev *dev;
+ struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
++ struct pci_dev *dev;
++ bool pending;
+
+ if (!vf)
+ return false;
+
+ dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
+- if (dev)
+- return bnx2x_is_pcie_pending(dev);
+- return false;
++ if (!dev)
++ return false;
++ pending = bnx2x_is_pcie_pending(dev);
++ pci_dev_put(dev);
++
++ return pending;
+ }
+
+ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index bf6a721430400..1e5dc0ea0e311 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1799,7 +1799,7 @@ static int liquidio_open(struct net_device *netdev)
+
+ ifstate_set(lio, LIO_IFSTATE_RUNNING);
+
+- if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++ if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) {
+ ret = setup_tx_poll_fn(netdev);
+ if (ret)
+ goto err_poll;
+@@ -1829,7 +1829,7 @@ static int liquidio_open(struct net_device *netdev)
+ return 0;
+
+ err_rx_ctrl:
+- if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++ if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on)
+ cleanup_tx_poll_fn(netdev);
+ err_poll:
+ if (lio->ptp_clock) {
+diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+index 2f6484dc186ab..7eb2ddbe9bad6 100644
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1436,8 +1436,10 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+ return AE_OK;
+ }
+
+- if (strncmp(string.pointer, bgx_sel, 4))
++ if (strncmp(string.pointer, bgx_sel, 4)) {
++ kfree(string.pointer);
+ return AE_OK;
++ }
+
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ bgx_acpi_register_phy, NULL, bgx, NULL);
+diff --git a/drivers/net/ethernet/davicom/dm9051.c b/drivers/net/ethernet/davicom/dm9051.c
+index a523ddda76093..de7105a847479 100644
+--- a/drivers/net/ethernet/davicom/dm9051.c
++++ b/drivers/net/ethernet/davicom/dm9051.c
+@@ -798,8 +798,10 @@ static int dm9051_loop_rx(struct board_info *db)
+ }
+
+ ret = dm9051_stop_mrcmd(db);
+- if (ret)
++ if (ret) {
++ dev_kfree_skb(skb);
+ return ret;
++ }
+
+ skb->protocol = eth_type_trans(skb, db->ndev);
+ if (db->ndev->features & NETIF_F_RXCSUM)
+diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c
+index a5f7152a17160..6a2617cc54908 100644
+--- a/drivers/net/ethernet/engleder/tsnep_main.c
++++ b/drivers/net/ethernet/engleder/tsnep_main.c
+@@ -504,6 +504,27 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
+ return (budget != 0);
+ }
+
++static bool tsnep_tx_pending(struct tsnep_tx *tx)
++{
++ unsigned long flags;
++ struct tsnep_tx_entry *entry;
++ bool pending = false;
++
++ spin_lock_irqsave(&tx->lock, flags);
++
++ if (tx->read != tx->write) {
++ entry = &tx->entry[tx->read];
++ if ((__le32_to_cpu(entry->desc_wb->properties) &
++ TSNEP_TX_DESC_OWNER_MASK) ==
++ (entry->properties & TSNEP_TX_DESC_OWNER_MASK))
++ pending = true;
++ }
++
++ spin_unlock_irqrestore(&tx->lock, flags);
++
++ return pending;
++}
++
+ static int tsnep_tx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ struct tsnep_tx *tx)
+ {
+@@ -751,6 +772,19 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
+ return done;
+ }
+
++static bool tsnep_rx_pending(struct tsnep_rx *rx)
++{
++ struct tsnep_rx_entry *entry;
++
++ entry = &rx->entry[rx->read];
++ if ((__le32_to_cpu(entry->desc_wb->properties) &
++ TSNEP_DESC_OWNER_COUNTER_MASK) ==
++ (entry->properties & TSNEP_DESC_OWNER_COUNTER_MASK))
++ return true;
++
++ return false;
++}
++
+ static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ struct tsnep_rx *rx)
+ {
+@@ -795,6 +829,17 @@ static void tsnep_rx_close(struct tsnep_rx *rx)
+ tsnep_rx_ring_cleanup(rx);
+ }
+
++static bool tsnep_pending(struct tsnep_queue *queue)
++{
++ if (queue->tx && tsnep_tx_pending(queue->tx))
++ return true;
++
++ if (queue->rx && tsnep_rx_pending(queue->rx))
++ return true;
++
++ return false;
++}
++
+ static int tsnep_poll(struct napi_struct *napi, int budget)
+ {
+ struct tsnep_queue *queue = container_of(napi, struct tsnep_queue,
+@@ -815,9 +860,19 @@ static int tsnep_poll(struct napi_struct *napi, int budget)
+ if (!complete)
+ return budget;
+
+- if (likely(napi_complete_done(napi, done)))
++ if (likely(napi_complete_done(napi, done))) {
+ tsnep_enable_irq(queue->adapter, queue->irq_mask);
+
++ /* reschedule if work is already pending, prevent rotten packets
++ * which are transmitted or received after polling but before
++ * interrupt enable
++ */
++ if (tsnep_pending(queue)) {
++ tsnep_disable_irq(queue->adapter, queue->irq_mask);
++ napi_schedule(napi);
++ }
++ }
++
+ return min(done, budget - 1);
+ }
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index d0fd3045ce111..1d8ec1b120a13 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2058,7 +2058,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ /* enable Tx ints by setting pkt thr to 1 */
+ enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
+
+- tbmr = ENETC_TBMR_EN;
++ tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio);
+ if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
+ tbmr |= ENETC_TBMR_VIH;
+
+@@ -2121,13 +2121,14 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+
+ static void enetc_setup_bdrs(struct enetc_ndev_priv *priv)
+ {
++ struct enetc_hw *hw = &priv->si->hw;
+ int i;
+
+ for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]);
++ enetc_setup_txbdr(hw, priv->tx_ring[i]);
+
+ for (i = 0; i < priv->num_rx_rings; i++)
+- enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++ enetc_setup_rxbdr(hw, priv->rx_ring[i]);
+ }
+
+ static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+@@ -2160,13 +2161,14 @@ static void enetc_clear_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+
+ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ {
++ struct enetc_hw *hw = &priv->si->hw;
+ int i;
+
+ for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]);
++ enetc_clear_txbdr(hw, priv->tx_ring[i]);
+
+ for (i = 0; i < priv->num_rx_rings; i++)
+- enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++ enetc_clear_rxbdr(hw, priv->rx_ring[i]);
+
+ udelay(1);
+ }
+@@ -2174,13 +2176,13 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
+ {
+ struct pci_dev *pdev = priv->si->pdev;
++ struct enetc_hw *hw = &priv->si->hw;
+ int i, j, err;
+
+ for (i = 0; i < priv->bdr_int_num; i++) {
+ int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i);
+ struct enetc_int_vector *v = priv->int_vector[i];
+ int entry = ENETC_BDR_INT_BASE_IDX + i;
+- struct enetc_hw *hw = &priv->si->hw;
+
+ snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
+ priv->ndev->name, i);
+@@ -2268,13 +2270,14 @@ static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
+
+ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
+ {
++ struct enetc_hw *hw = &priv->si->hw;
+ int i;
+
+ for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0);
++ enetc_txbdr_wr(hw, i, ENETC_TBIER, 0);
+
+ for (i = 0; i < priv->num_rx_rings; i++)
+- enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0);
++ enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0);
+ }
+
+ static int enetc_phylink_connect(struct net_device *ndev)
+@@ -2441,6 +2444,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ {
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ struct tc_mqprio_qopt *mqprio = type_data;
++ struct enetc_hw *hw = &priv->si->hw;
+ struct enetc_bdr *tx_ring;
+ int num_stack_tx_queues;
+ u8 num_tc;
+@@ -2457,7 +2461,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ /* Reset all ring priorities to 0 */
+ for (i = 0; i < priv->num_tx_rings; i++) {
+ tx_ring = priv->tx_ring[i];
+- enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0);
++ tx_ring->prio = 0;
++ enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ }
+
+ return 0;
+@@ -2476,7 +2481,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ */
+ for (i = 0; i < num_tc; i++) {
+ tx_ring = priv->tx_ring[i];
+- enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i);
++ tx_ring->prio = i;
++ enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ }
+
+ /* Reset the number of netdev queues based on the TC count */
+@@ -2589,19 +2595,21 @@ static int enetc_set_rss(struct net_device *ndev, int en)
+ static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
+ {
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
++ struct enetc_hw *hw = &priv->si->hw;
+ int i;
+
+ for (i = 0; i < priv->num_rx_rings; i++)
+- enetc_bdr_enable_rxvlan(&priv->si->hw, i, en);
++ enetc_bdr_enable_rxvlan(hw, i, en);
+ }
+
+ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
+ {
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
++ struct enetc_hw *hw = &priv->si->hw;
+ int i;
+
+ for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
++ enetc_bdr_enable_txvlan(hw, i, en);
+ }
+
+ void enetc_set_features(struct net_device *ndev, netdev_features_t features)
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
+index 2cfe6944ebd32..bb1b3b0e40e4d 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc.h
+@@ -95,6 +95,7 @@ struct enetc_bdr {
+ void __iomem *rcir;
+ };
+ u16 index;
++ u16 prio;
+ int bd_count; /* # of BDs */
+ int next_to_use;
+ int next_to_clean;
+@@ -467,19 +468,20 @@ int enetc_set_psfp(struct net_device *ndev, bool en);
+
+ static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
+ {
++ struct enetc_hw *hw = &priv->si->hw;
+ u32 reg;
+
+- reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR);
++ reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
+ priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
+ /* Port stream filter capability */
+- reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR);
++ reg = enetc_port_rd(hw, ENETC_PSFCAPR);
+ priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
+ /* Port stream gate capability */
+- reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR);
++ reg = enetc_port_rd(hw, ENETC_PSGCAPR);
+ priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
+ priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
+ /* Port flow meter capability */
+- reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR);
++ reg = enetc_port_rd(hw, ENETC_PFMCAPR);
+ priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
+ }
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index f8a2f02ce22de..5fcb02b006999 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -17,8 +17,9 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
+
+ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ {
++ struct enetc_hw *hw = &priv->si->hw;
+ u32 old_speed = priv->speed;
+- u32 pspeed;
++ u32 pspeed, tmp;
+
+ if (speed == old_speed)
+ return;
+@@ -39,16 +40,15 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ }
+
+ priv->speed = speed;
+- enetc_port_wr(&priv->si->hw, ENETC_PMR,
+- (enetc_port_rd(&priv->si->hw, ENETC_PMR)
+- & (~ENETC_PMR_PSPEED_MASK))
+- | pspeed);
++ tmp = enetc_port_rd(hw, ENETC_PMR);
++ enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed);
+ }
+
+ static int enetc_setup_taprio(struct net_device *ndev,
+ struct tc_taprio_qopt_offload *admin_conf)
+ {
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
++ struct enetc_hw *hw = &priv->si->hw;
+ struct enetc_cbd cbd = {.cmd = 0};
+ struct tgs_gcl_conf *gcl_config;
+ struct tgs_gcl_data *gcl_data;
+@@ -61,15 +61,13 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ int err;
+ int i;
+
+- if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw))
++ if (admin_conf->num_entries > enetc_get_max_gcl_len(hw))
+ return -EINVAL;
+ gcl_len = admin_conf->num_entries;
+
+- tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET);
++ tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET);
+ if (!admin_conf->enable) {
+- enetc_wr(&priv->si->hw,
+- ENETC_QBV_PTGCR_OFFSET,
+- tge & (~ENETC_QBV_TGE));
++ enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+
+ priv->active_offloads &= ~ENETC_F_QBV;
+
+@@ -117,14 +115,11 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ cbd.cls = BDCR_CMD_PORT_GCL;
+ cbd.status_flags = 0;
+
+- enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET,
+- tge | ENETC_QBV_TGE);
++ enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE);
+
+ err = enetc_send_cmd(priv->si, &cbd);
+ if (err)
+- enetc_wr(&priv->si->hw,
+- ENETC_QBV_PTGCR_OFFSET,
+- tge & (~ENETC_QBV_TGE));
++ enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+
+ enetc_cbd_free_data_mem(priv->si, data_size, tmp, &dma);
+
+@@ -138,6 +133,8 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ {
+ struct tc_taprio_qopt_offload *taprio = type_data;
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
++ struct enetc_hw *hw = &priv->si->hw;
++ struct enetc_bdr *tx_ring;
+ int err;
+ int i;
+
+@@ -146,18 +143,20 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ if (priv->tx_ring[i]->tsd_enable)
+ return -EBUSY;
+
+- for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_set_bdr_prio(&priv->si->hw,
+- priv->tx_ring[i]->index,
+- taprio->enable ? i : 0);
++ for (i = 0; i < priv->num_tx_rings; i++) {
++ tx_ring = priv->tx_ring[i];
++ tx_ring->prio = taprio->enable ? i : 0;
++ enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++ }
+
+ err = enetc_setup_taprio(ndev, taprio);
+-
+- if (err)
+- for (i = 0; i < priv->num_tx_rings; i++)
+- enetc_set_bdr_prio(&priv->si->hw,
+- priv->tx_ring[i]->index,
+- taprio->enable ? 0 : i);
++ if (err) {
++ for (i = 0; i < priv->num_tx_rings; i++) {
++ tx_ring = priv->tx_ring[i];
++ tx_ring->prio = taprio->enable ? 0 : i;
++ enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++ }
++ }
+
+ return err;
+ }
+@@ -178,7 +177,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ struct tc_cbs_qopt_offload *cbs = type_data;
+ u32 port_transmit_rate = priv->speed;
+ u8 tc_nums = netdev_get_num_tc(ndev);
+- struct enetc_si *si = priv->si;
++ struct enetc_hw *hw = &priv->si->hw;
+ u32 hi_credit_bit, hi_credit_reg;
+ u32 max_interference_size;
+ u32 port_frame_max_size;
+@@ -199,15 +198,15 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ * lower than this TC have been disabled.
+ */
+ if (tc == prio_top &&
+- enetc_get_cbs_enable(&si->hw, prio_next)) {
++ enetc_get_cbs_enable(hw, prio_next)) {
+ dev_err(&ndev->dev,
+ "Disable TC%d before disable TC%d\n",
+ prio_next, tc);
+ return -EINVAL;
+ }
+
+- enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0);
+- enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0);
++ enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0);
++ enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0);
+
+ return 0;
+ }
+@@ -224,13 +223,13 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ * higher than this TC have been enabled.
+ */
+ if (tc == prio_next) {
+- if (!enetc_get_cbs_enable(&si->hw, prio_top)) {
++ if (!enetc_get_cbs_enable(hw, prio_top)) {
+ dev_err(&ndev->dev,
+ "Enable TC%d first before enable TC%d\n",
+ prio_top, prio_next);
+ return -EINVAL;
+ }
+- bw_sum += enetc_get_cbs_bw(&si->hw, prio_top);
++ bw_sum += enetc_get_cbs_bw(hw, prio_top);
+ }
+
+ if (bw_sum + bw >= 100) {
+@@ -239,7 +238,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ return -EINVAL;
+ }
+
+- enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc));
++ enetc_port_rd(hw, ENETC_PTCMSDUR(tc));
+
+ /* For top prio TC, the max_interfrence_size is maxSizedFrame.
+ *
+@@ -259,8 +258,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ u32 m0, ma, r0, ra;
+
+ m0 = port_frame_max_size * 8;
+- ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8;
+- ra = enetc_get_cbs_bw(&si->hw, prio_top) *
++ ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8;
++ ra = enetc_get_cbs_bw(hw, prio_top) *
+ port_transmit_rate * 10000ULL;
+ r0 = port_transmit_rate * 1000000ULL;
+ max_interference_size = m0 + ma +
+@@ -280,10 +279,10 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
+ port_transmit_rate * 1000000ULL);
+
+- enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
++ enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
+
+ /* Set bw register and enable this traffic class */
+- enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
++ enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
+
+ return 0;
+ }
+@@ -293,6 +292,7 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ struct tc_etf_qopt_offload *qopt = type_data;
+ u8 tc_nums = netdev_get_num_tc(ndev);
++ struct enetc_hw *hw = &priv->si->hw;
+ int tc;
+
+ if (!tc_nums)
+@@ -304,12 +304,11 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ return -EINVAL;
+
+ /* TSD and Qbv are mutually exclusive in hardware */
+- if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
++ if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+ return -EBUSY;
+
+ priv->tx_ring[tc]->tsd_enable = qopt->enable;
+- enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+- qopt->enable ? ENETC_TSDE : 0);
++ enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0);
+
+ return 0;
+ }
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 3f6187c164240..0d1bab4ac1b07 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -298,7 +298,6 @@ struct iavf_adapter {
+ #define IAVF_FLAG_QUEUES_DISABLED BIT(17)
+ #define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18)
+ #define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20)
+-#define IAVF_FLAG_INITIAL_MAC_SET BIT(23)
+ /* duplicates for common code */
+ #define IAVF_FLAG_DCB_ENABLED 0
+ /* flags for admin queue service task */
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 79fef8c59d652..cff03723f4f9f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1087,12 +1087,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
+ if (ret)
+ return ret;
+
+- /* If this is an initial set MAC during VF spawn do not wait */
+- if (adapter->flags & IAVF_FLAG_INITIAL_MAC_SET) {
+- adapter->flags &= ~IAVF_FLAG_INITIAL_MAC_SET;
+- return 0;
+- }
+-
+ ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
+ iavf_is_mac_set_handled(netdev, addr->sa_data),
+ msecs_to_jiffies(2500));
+@@ -2605,8 +2599,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
+ ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
+ }
+
+- adapter->flags |= IAVF_FLAG_INITIAL_MAC_SET;
+-
+ adapter->tx_desc_count = IAVF_DEFAULT_TXD;
+ adapter->rx_desc_count = IAVF_DEFAULT_RXD;
+ err = iavf_init_interrupt_scheme(adapter);
+@@ -2921,7 +2913,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
+ iavf_free_queues(adapter);
+ memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
+ iavf_shutdown_adminq(&adapter->hw);
+- adapter->netdev->flags &= ~IFF_UP;
+ adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
+ iavf_change_state(adapter, __IAVF_DOWN);
+ wake_up(&adapter->down_waitqueue);
+@@ -3021,6 +3012,11 @@ static void iavf_reset_task(struct work_struct *work)
+ iavf_disable_vf(adapter);
+ mutex_unlock(&adapter->client_lock);
+ mutex_unlock(&adapter->crit_lock);
++ if (netif_running(netdev)) {
++ rtnl_lock();
++ dev_close(netdev);
++ rtnl_unlock();
++ }
+ return; /* Do not attempt to reinit. It's dead, Jim. */
+ }
+
+@@ -3033,6 +3029,7 @@ continue_reset:
+
+ if (running) {
+ netif_carrier_off(netdev);
++ netif_tx_stop_all_queues(netdev);
+ adapter->link_up = false;
+ iavf_napi_disable_all(adapter);
+ }
+@@ -3172,6 +3169,16 @@ reset_err:
+
+ mutex_unlock(&adapter->client_lock);
+ mutex_unlock(&adapter->crit_lock);
++
++ if (netif_running(netdev)) {
++ /* Close device to ensure that Tx queues will not be started
++ * during netif_device_attach() at the end of the reset task.
++ */
++ rtnl_lock();
++ dev_close(netdev);
++ rtnl_unlock();
++ }
++
+ dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
+ reset_finish:
+ rtnl_lock();
+@@ -5035,23 +5042,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
+ static void iavf_remove(struct pci_dev *pdev)
+ {
+ struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
+- struct net_device *netdev = adapter->netdev;
+ struct iavf_fdir_fltr *fdir, *fdirtmp;
+ struct iavf_vlan_filter *vlf, *vlftmp;
++ struct iavf_cloud_filter *cf, *cftmp;
+ struct iavf_adv_rss *rss, *rsstmp;
+ struct iavf_mac_filter *f, *ftmp;
+- struct iavf_cloud_filter *cf, *cftmp;
+- struct iavf_hw *hw = &adapter->hw;
++ struct net_device *netdev;
++ struct iavf_hw *hw;
+ int err;
+
+- /* When reboot/shutdown is in progress no need to do anything
+- * as the adapter is already REMOVE state that was set during
+- * iavf_shutdown() callback.
+- */
+- if (adapter->state == __IAVF_REMOVE)
++ netdev = adapter->netdev;
++ hw = &adapter->hw;
++
++ if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
+ return;
+
+- set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+ /* Wait until port initialization is complete.
+ * There are flows where register/unregister netdev may race.
+ */
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index eaa51cd7456b6..8f86be995092b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7352,6 +7352,7 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ struct mvpp2 *priv)
+ {
+ struct resource *res;
++ void __iomem *base;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!res) {
+@@ -7362,9 +7363,12 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ return 0;
+ }
+
+- priv->cm3_base = devm_ioremap_resource(&pdev->dev, res);
++ base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
+
+- return PTR_ERR_OR_ZERO(priv->cm3_base);
++ priv->cm3_base = base;
++ return 0;
+ }
+
+ static int mvpp2_probe(struct platform_device *pdev)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index f42a09f04b256..70cda15713245 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -535,6 +535,8 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+ sprintf(lmac, "LMAC%d", lmac_id);
+ seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n",
+ dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac);
++
++ pci_dev_put(pdev);
+ }
+ return 0;
+ }
+@@ -2221,6 +2223,7 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
+ }
+ }
+
++ pci_dev_put(pdev);
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 0879a48411f31..3dc90060d70d7 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -4979,6 +4979,8 @@ static int nix_setup_ipolicers(struct rvu *rvu,
+ ipolicer->ref_count = devm_kcalloc(rvu->dev,
+ ipolicer->band_prof.max,
+ sizeof(u16), GFP_KERNEL);
++ if (!ipolicer->ref_count)
++ return -ENOMEM;
+ }
+
+ /* Set policer timeunit to 2us ie (19 + 1) * 100 nsec = 2us */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index b04fb226f708a..ae50d56258ec6 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -62,15 +62,18 @@ int rvu_sdp_init(struct rvu *rvu)
+ pfvf->sdp_info = devm_kzalloc(rvu->dev,
+ sizeof(struct sdp_node_info),
+ GFP_KERNEL);
+- if (!pfvf->sdp_info)
++ if (!pfvf->sdp_info) {
++ pci_dev_put(pdev);
+ return -ENOMEM;
++ }
+
+ dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
+
+- put_device(&pdev->dev);
+ i++;
+ }
+
++ pci_dev_put(pdev);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+index a0ad0bcbf89f4..9f588ecba93e2 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -730,6 +730,7 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
+ return 0;
+
+ err_sfp_bind:
++ unregister_netdev(dev);
+ err_register_netdev:
+ prestera_port_list_del(port);
+ err_port_init:
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 84433f3a3e228..5380caf0acc2f 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2363,8 +2363,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
+ data + NET_SKB_PAD + eth->ip_align,
+ ring->buf_size, DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(eth->dma_dev,
+- dma_addr)))
++ dma_addr))) {
++ skb_free_frag(data);
+ return -ENOMEM;
++ }
+ }
+ rxd->rxd1 = (unsigned int)dma_addr;
+ ring->data[i] = data;
+@@ -2979,8 +2981,10 @@ static int mtk_open(struct net_device *dev)
+ u32 gdm_config = MTK_GDMA_TO_PDMA;
+
+ err = mtk_start_dma(eth);
+- if (err)
++ if (err) {
++ phylink_disconnect_phy(mac->phylink);
+ return err;
++ }
+
+ if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
+ gdm_config = MTK_GDMA_TO_PPE;
+@@ -4103,12 +4107,12 @@ static int mtk_probe(struct platform_device *pdev)
+ eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
+ if (!eth->ppe) {
+ err = -ENOMEM;
+- goto err_free_dev;
++ goto err_deinit_mdio;
+ }
+
+ err = mtk_eth_offload_init(eth);
+ if (err)
+- goto err_free_dev;
++ goto err_deinit_mdio;
+ }
+
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
+index b149e601f6737..48cfaa7eaf50c 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
+@@ -697,7 +697,8 @@ static int mlx4_create_zones(struct mlx4_dev *dev,
+ err = mlx4_bitmap_init(*bitmap + k, 1,
+ MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0,
+ 0);
+- mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
++ if (!err)
++ mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
+ }
+
+ if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 2e0d59ca62b50..74bd05e5dda23 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -45,6 +45,8 @@
+ #include "mlx5_core.h"
+ #include "lib/eq.h"
+ #include "lib/tout.h"
++#define CREATE_TRACE_POINTS
++#include "diag/cmd_tracepoint.h"
+
+ enum {
+ CMD_IF_REV = 5,
+@@ -785,27 +787,14 @@ EXPORT_SYMBOL(mlx5_cmd_out_err);
+ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out)
+ {
+ u16 opcode, op_mod;
+- u32 syndrome;
+- u8 status;
+ u16 uid;
+- int err;
+-
+- syndrome = MLX5_GET(mbox_out, out, syndrome);
+- status = MLX5_GET(mbox_out, out, status);
+
+ opcode = MLX5_GET(mbox_in, in, opcode);
+ op_mod = MLX5_GET(mbox_in, in, op_mod);
+ uid = MLX5_GET(mbox_in, in, uid);
+
+- err = cmd_status_to_err(status);
+-
+ if (!uid && opcode != MLX5_CMD_OP_DESTROY_MKEY)
+ mlx5_cmd_out_err(dev, opcode, op_mod, out);
+- else
+- mlx5_core_dbg(dev,
+- "%s(0x%x) op_mod(0x%x) uid(%d) failed, status %s(0x%x), syndrome (0x%x), err(%d)\n",
+- mlx5_command_str(opcode), opcode, op_mod, uid,
+- cmd_status_str(status), status, syndrome, err);
+ }
+
+ int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out)
+@@ -1016,6 +1005,7 @@ static void cmd_work_handler(struct work_struct *work)
+ cmd_ent_get(ent);
+ set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
+
++ cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ /* Skip sending command to fw if internal error */
+ if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
+ ent->ret = -ENXIO;
+@@ -1023,7 +1013,6 @@ static void cmd_work_handler(struct work_struct *work)
+ return;
+ }
+
+- cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ /* ring doorbell after the descriptor is valid */
+ mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
+ wmb();
+@@ -1672,8 +1661,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+ cmd_ent_put(ent); /* timeout work was canceled */
+
+ if (!forced || /* Real FW completion */
+- pci_channel_offline(dev->pdev) || /* FW is inaccessible */
+- dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
++ mlx5_cmd_is_down(dev) || /* No real FW completion is expected */
++ !opcode_allowed(cmd, ent->op))
+ cmd_ent_put(ent);
+
+ ent->ts2 = ktime_get_ns();
+@@ -1892,6 +1881,16 @@ out_in:
+ return err;
+ }
+
++static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)
++{
++ u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
++ u8 status = MLX5_GET(mbox_out, out, status);
++
++ trace_mlx5_cmd(mlx5_command_str(opcode), opcode, op_mod,
++ cmd_status_str(status), status, syndrome,
++ cmd_status_to_err(status));
++}
++
+ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ u32 syndrome, int err)
+ {
+@@ -1914,7 +1913,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ }
+
+ /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */
+-static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *out)
++static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op_mod, void *out)
+ {
+ u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
+ u8 status = MLX5_GET(mbox_out, out, status);
+@@ -1922,8 +1921,10 @@ static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *
+ if (err == -EREMOTEIO) /* -EREMOTEIO is preserved */
+ err = -EIO;
+
+- if (!err && status != MLX5_CMD_STAT_OK)
++ if (!err && status != MLX5_CMD_STAT_OK) {
+ err = -EREMOTEIO;
++ mlx5_cmd_err_trace(dev, opcode, op_mod, out);
++ }
+
+ cmd_status_log(dev, opcode, status, syndrome, err);
+ return err;
+@@ -1951,9 +1952,9 @@ int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int
+ {
+ int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false);
+ u16 opcode = MLX5_GET(mbox_in, in, opcode);
++ u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+
+- err = cmd_status_err(dev, err, opcode, out);
+- return err;
++ return cmd_status_err(dev, err, opcode, op_mod, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_do);
+
+@@ -1997,8 +1998,9 @@ int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size,
+ {
+ int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true);
+ u16 opcode = MLX5_GET(mbox_in, in, opcode);
++ u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+
+- err = cmd_status_err(dev, err, opcode, out);
++ err = cmd_status_err(dev, err, opcode, op_mod, out);
+ return mlx5_cmd_check(dev, err, in, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_exec_polling);
+@@ -2034,7 +2036,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
+ struct mlx5_async_ctx *ctx;
+
+ ctx = work->ctx;
+- status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
++ status = cmd_status_err(ctx->dev, status, work->opcode, work->op_mod, work->out);
+ work->user_callback(status, work);
+ if (atomic_dec_and_test(&ctx->num_inflight))
+ complete(&ctx->inflight_done);
+@@ -2049,6 +2051,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+ work->ctx = ctx;
+ work->user_callback = callback;
+ work->opcode = MLX5_GET(mbox_in, in, opcode);
++ work->op_mod = MLX5_GET(mbox_in, in, op_mod);
+ work->out = out;
+ if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight)))
+ return -EIO;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+new file mode 100644
+index 0000000000000..406ebe17405f9
+--- /dev/null
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+@@ -0,0 +1,45 @@
++/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
++/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM mlx5
++
++#if !defined(_MLX5_CMD_TP_H_) || defined(TRACE_HEADER_MULTI_READ)
++#define _MLX5_CMD_TP_H_
++
++#include <linux/tracepoint.h>
++#include <linux/trace_seq.h>
++
++TRACE_EVENT(mlx5_cmd,
++ TP_PROTO(const char *command_str, u16 opcode, u16 op_mod,
++ const char *status_str, u8 status, u32 syndrome, int err),
++ TP_ARGS(command_str, opcode, op_mod, status_str, status, syndrome, err),
++ TP_STRUCT__entry(__string(command_str, command_str)
++ __field(u16, opcode)
++ __field(u16, op_mod)
++ __string(status_str, status_str)
++ __field(u8, status)
++ __field(u32, syndrome)
++ __field(int, err)
++ ),
++ TP_fast_assign(__assign_str(command_str, command_str);
++ __entry->opcode = opcode;
++ __entry->op_mod = op_mod;
++ __assign_str(status_str, status_str);
++ __entry->status = status;
++ __entry->syndrome = syndrome;
++ __entry->err = err;
++ ),
++ TP_printk("%s(0x%x) op_mod(0x%x) failed, status %s(0x%x), syndrome (0x%x), err(%d)",
++ __get_str(command_str), __entry->opcode, __entry->op_mod,
++ __get_str(status_str), __entry->status, __entry->syndrome,
++ __entry->err)
++);
++
++#endif /* _MLX5_CMD_TP_H_ */
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH ./diag
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE cmd_tracepoint
++#include <trace/define_trace.h>
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 978a2bb8e1220..21831386b26e8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -638,7 +638,7 @@ static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
+ trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
+ (str_frmt->timestamp & MASK_6_0);
+ else
+- trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) |
++ trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) |
+ (str_frmt->timestamp & MASK_6_0);
+
+ mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index 5aff979143678..ff73d25bc6eb8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -224,15 +224,16 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ list_for_each_entry(flow, flow_list, tmp_list) {
+ if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
+ continue;
+- spec = &flow->attr->parse_attr->spec;
+-
+- /* update from encap rule to slow path rule */
+- rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+
+ attr = mlx5e_tc_get_encap_attr(flow);
+ esw_attr = attr->esw_attr;
+ /* mark the flow's encap dest as non-valid */
+ esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
++ esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
++
++ /* update from encap rule to slow path rule */
++ spec = &flow->attr->parse_attr->spec;
++ rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+
+ if (IS_ERR(rule)) {
+ err = PTR_ERR(rule);
+@@ -251,6 +252,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ /* we know that the encap is valid */
+ e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
+ mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat);
++ e->pkt_reformat = NULL;
+ }
+
+ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow,
+@@ -762,8 +764,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ struct net_device *mirred_dev,
+ int out_index,
+ struct netlink_ext_ack *extack,
+- struct net_device **encap_dev,
+- bool *encap_valid)
++ struct net_device **encap_dev)
+ {
+ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -878,9 +879,8 @@ attach_flow:
+ if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
+ attr->esw_attr->dests[out_index].pkt_reformat = e->pkt_reformat;
+ attr->esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_ENCAP_VALID;
+- *encap_valid = true;
+ } else {
+- *encap_valid = false;
++ flow_flag_set(flow, SLOW);
+ }
+ mutex_unlock(&esw->offloads.encap_tbl_lock);
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+index d542b8476491e..8ad273dde40ee 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+@@ -17,8 +17,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ struct net_device *mirred_dev,
+ int out_index,
+ struct netlink_ext_ack *extack,
+- struct net_device **encap_dev,
+- bool *encap_valid);
++ struct net_device **encap_dev);
+
+ int mlx5e_attach_decap(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow *flow,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 229c14b1af004..949ef560df787 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1620,7 +1620,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow *flow,
+ struct mlx5_flow_attr *attr,
+ struct netlink_ext_ack *extack,
+- bool *encap_valid,
+ bool *vf_tun)
+ {
+ struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -1637,7 +1636,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ parse_attr = attr->parse_attr;
+ esw_attr = attr->esw_attr;
+ *vf_tun = false;
+- *encap_valid = true;
+
+ for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
+ struct net_device *out_dev;
+@@ -1654,7 +1652,7 @@ set_encap_dests(struct mlx5e_priv *priv,
+ goto out;
+ }
+ err = mlx5e_attach_encap(priv, flow, attr, out_dev, out_index,
+- extack, &encap_dev, encap_valid);
++ extack, &encap_dev);
+ dev_put(out_dev);
+ if (err)
+ goto out;
+@@ -1718,8 +1716,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow_parse_attr *parse_attr;
+ struct mlx5_flow_attr *attr = flow->attr;
+ struct mlx5_esw_flow_attr *esw_attr;
+- bool vf_tun, encap_valid;
+ u32 max_prio, max_chain;
++ bool vf_tun;
+ int err = 0;
+
+ parse_attr = attr->parse_attr;
+@@ -1809,7 +1807,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ esw_attr->int_port = int_port;
+ }
+
+- err = set_encap_dests(priv, flow, attr, extack, &encap_valid, &vf_tun);
++ err = set_encap_dests(priv, flow, attr, extack, &vf_tun);
+ if (err)
+ goto err_out;
+
+@@ -1839,7 +1837,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ * (1) there's no error
+ * (2) there's an encap action and we don't have valid neigh
+ */
+- if (!encap_valid || flow_flag_test(flow, SLOW))
++ if (flow_flag_test(flow, SLOW))
+ flow->rule[0] = mlx5e_tc_offload_to_slow_path(esw, flow, &parse_attr->spec);
+ else
+ flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr);
+@@ -3737,7 +3735,7 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ struct mlx5e_post_act *post_act = get_post_action(flow->priv);
+ struct mlx5_flow_attr *attr, *next_attr = NULL;
+ struct mlx5e_post_act_handle *handle;
+- bool vf_tun, encap_valid = true;
++ bool vf_tun;
+ int err;
+
+ /* This is going in reverse order as needed.
+@@ -3759,13 +3757,10 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ if (list_is_last(&attr->list, &flow->attrs))
+ break;
+
+- err = set_encap_dests(flow->priv, flow, attr, extack, &encap_valid, &vf_tun);
++ err = set_encap_dests(flow->priv, flow, attr, extack, &vf_tun);
+ if (err)
+ goto out_free;
+
+- if (!encap_valid)
+- flow_flag_set(flow, SLOW);
+-
+ err = actions_prepare_mod_hdr_actions(flow->priv, flow, attr, extack);
+ if (err)
+ goto out_free;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 3c68cac4a9c2c..061ac87993546 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -431,7 +431,7 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f
+ mlx5_lag_mpesw_is_activated(esw->dev))
+ dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK;
+ }
+- if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) {
++ if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP_VALID) {
+ if (pkt_reformat) {
+ flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
+ flow_act->pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 9d908a0ccfef1..1e46f9afa40e0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -9,7 +9,8 @@ enum {
+ MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+ MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ MLX5_FW_RESET_FLAGS_PENDING_COMP,
+- MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS
++ MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
++ MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
+ };
+
+ struct mlx5_fw_reset {
+@@ -406,7 +407,7 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ err = mlx5_pci_link_toggle(dev);
+ if (err) {
+ mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
+- goto done;
++ set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
+ }
+
+ mlx5_enter_error_state(dev, true);
+@@ -482,6 +483,10 @@ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev)
+ goto out;
+ }
+ err = fw_reset->ret;
++ if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
++ mlx5_unload_one_devl_locked(dev);
++ mlx5_load_one_devl_locked(dev, false);
++ }
+ out:
+ clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
+ return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index e5e32430b6afd..ac178796e484f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1759,7 +1759,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
+ res = state == pci_channel_io_perm_failure ?
+ PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+
+- mlx5_pci_trace(dev, "Exit, result = %d, %s\n", res, result2str(res));
++ mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
++ __func__, dev->state, dev->pci_status, res, result2str(res));
+ return res;
+ }
+
+@@ -1798,7 +1799,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+ struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+ int err;
+
+- mlx5_pci_trace(dev, "Enter\n");
++ mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
++ __func__, dev->state, dev->pci_status);
+
+ err = mlx5_pci_enable_device(dev);
+ if (err) {
+@@ -1820,7 +1822,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+
+ res = PCI_ERS_RESULT_RECOVERED;
+ out:
+- mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res));
++ mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
++ __func__, dev->state, dev->pci_status, err, res, result2str(res));
+ return res;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+index 7da012ff0d419..8e2abbab05f04 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+@@ -18,6 +18,10 @@ struct mlx5_sf_dev_table {
+ phys_addr_t base_address;
+ u64 sf_bar_length;
+ struct notifier_block nb;
++ struct mutex table_lock; /* Serializes sf life cycle and vhca state change handler */
++ struct workqueue_struct *active_wq;
++ struct work_struct work;
++ u8 stop_active_wq:1;
+ struct mlx5_core_dev *dev;
+ };
+
+@@ -168,6 +172,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ return 0;
+
+ sf_index = event->function_id - base_id;
++ mutex_lock(&table->table_lock);
+ sf_dev = xa_load(&table->devices, sf_index);
+ switch (event->new_vhca_state) {
+ case MLX5_VHCA_STATE_INVALID:
+@@ -191,6 +196,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ default:
+ break;
+ }
++ mutex_unlock(&table->table_lock);
+ return 0;
+ }
+
+@@ -215,6 +221,78 @@ static int mlx5_sf_dev_vhca_arm_all(struct mlx5_sf_dev_table *table)
+ return 0;
+ }
+
++static void mlx5_sf_dev_add_active_work(struct work_struct *work)
++{
++ struct mlx5_sf_dev_table *table = container_of(work, struct mlx5_sf_dev_table, work);
++ u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {};
++ struct mlx5_core_dev *dev = table->dev;
++ u16 max_functions;
++ u16 function_id;
++ u16 sw_func_id;
++ int err = 0;
++ u8 state;
++ int i;
++
++ max_functions = mlx5_sf_max_functions(dev);
++ function_id = MLX5_CAP_GEN(dev, sf_base_id);
++ for (i = 0; i < max_functions; i++, function_id++) {
++ if (table->stop_active_wq)
++ return;
++ err = mlx5_cmd_query_vhca_state(dev, function_id, out, sizeof(out));
++ if (err)
++ /* A failure of specific vhca doesn't mean others will
++ * fail as well.
++ */
++ continue;
++ state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state);
++ if (state != MLX5_VHCA_STATE_ACTIVE)
++ continue;
++
++ sw_func_id = MLX5_GET(query_vhca_state_out, out, vhca_state_context.sw_function_id);
++ mutex_lock(&table->table_lock);
++ /* Don't probe device which is already probe */
++ if (!xa_load(&table->devices, i))
++ mlx5_sf_dev_add(dev, i, function_id, sw_func_id);
++ /* There is a race where SF got inactive after the query
++ * above. e.g.: the query returns that the state of the
++ * SF is active, and after that the eswitch manager set it to
++ * inactive.
++ * This case cannot be managed in SW, since the probing of the
++ * SF is on one system, and the inactivation is on a different
++ * system.
++ * If the inactive is done after the SF perform init_hca(),
++ * the SF will fully probe and then removed. If it was
++ * done before init_hca(), the SF probe will fail.
++ */
++ mutex_unlock(&table->table_lock);
++ }
++}
++
++/* In case SFs are generated externally, probe active SFs */
++static int mlx5_sf_dev_queue_active_work(struct mlx5_sf_dev_table *table)
++{
++ if (MLX5_CAP_GEN(table->dev, eswitch_manager))
++ return 0; /* the table is local */
++
++ /* Use a workqueue to probe active SFs, which are in large
++ * quantity and may take up to minutes to probe.
++ */
++ table->active_wq = create_singlethread_workqueue("mlx5_active_sf");
++ if (!table->active_wq)
++ return -ENOMEM;
++ INIT_WORK(&table->work, &mlx5_sf_dev_add_active_work);
++ queue_work(table->active_wq, &table->work);
++ return 0;
++}
++
++static void mlx5_sf_dev_destroy_active_work(struct mlx5_sf_dev_table *table)
++{
++ if (table->active_wq) {
++ table->stop_active_wq = true;
++ destroy_workqueue(table->active_wq);
++ }
++}
++
+ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_sf_dev_table *table;
+@@ -240,11 +318,17 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ table->base_address = pci_resource_start(dev->pdev, 2);
+ table->max_sfs = max_sfs;
+ xa_init(&table->devices);
++ mutex_init(&table->table_lock);
+ dev->priv.sf_dev_table = table;
+
+ err = mlx5_vhca_event_notifier_register(dev, &table->nb);
+ if (err)
+ goto vhca_err;
++
++ err = mlx5_sf_dev_queue_active_work(table);
++ if (err)
++ goto add_active_err;
++
+ err = mlx5_sf_dev_vhca_arm_all(table);
+ if (err)
+ goto arm_err;
+@@ -252,6 +336,8 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ return;
+
+ arm_err:
++ mlx5_sf_dev_destroy_active_work(table);
++add_active_err:
+ mlx5_vhca_event_notifier_unregister(dev, &table->nb);
+ vhca_err:
+ table->max_sfs = 0;
+@@ -279,7 +365,9 @@ void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev)
+ if (!table)
+ return;
+
++ mlx5_sf_dev_destroy_active_work(table);
+ mlx5_vhca_event_notifier_unregister(dev, &table->nb);
++ mutex_destroy(&table->table_lock);
+
+ /* Now that event handler is not running, it is safe to destroy
+ * the sf device without race.
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+index af4d3e1f1a6d9..3f112a897a601 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+@@ -103,7 +103,7 @@ static int sparx5_port_open(struct net_device *ndev)
+ err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
+ if (err) {
+ netdev_err(ndev, "Could not attach to PHY\n");
+- return err;
++ goto err_connect;
+ }
+
+ phylink_start(port->phylink);
+@@ -115,10 +115,20 @@ static int sparx5_port_open(struct net_device *ndev)
+ err = sparx5_serdes_set(port->sparx5, port, &port->conf);
+ else
+ err = phy_power_on(port->serdes);
+- if (err)
++ if (err) {
+ netdev_err(ndev, "%s failed\n", __func__);
++ goto out_power;
++ }
+ }
+
++ return 0;
++
++out_power:
++ phylink_stop(port->phylink);
++ phylink_disconnect_phy(port->phylink);
++err_connect:
++ sparx5_port_enable(port, false);
++
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+index 405786c003347..cb08d7bf95241 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+@@ -341,7 +341,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
+ return ret;
+
+ attrs.split = eth_port.is_split;
+- attrs.splittable = !attrs.split;
++ attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
+ attrs.lanes = eth_port.port_lanes;
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = eth_port.label_port;
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index b19bff0db1fdc..400b22ad6a346 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1395,6 +1395,9 @@ nfp_port_get_module_info(struct net_device *netdev,
+ u8 data;
+
+ port = nfp_port_from_netdev(netdev);
++ if (!port)
++ return -EOPNOTSUPP;
++
+ /* update port state to get latest interface */
+ set_bit(NFP_PORT_CHANGED, &port->flags);
+ eth_port = nfp_port_get_eth_port(port);
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 46da937ad27f8..63b6b7d86ccbe 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -1143,6 +1143,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
+ buffer_info->dma = 0;
+ buffer_info->time_stamp = 0;
+ tx_ring->next_to_use = ring_num;
++ dev_kfree_skb_any(skb);
+ return;
+ }
+ buffer_info->mapped = true;
+@@ -2459,6 +2460,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
+ unregister_netdev(netdev);
+
+ pch_gbe_phy_hw_reset(&adapter->hw);
++ pci_dev_put(adapter->ptp_pdev);
+
+ free_netdev(netdev);
+ }
+@@ -2534,7 +2536,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ /* setup the private structure */
+ ret = pch_gbe_sw_init(adapter);
+ if (ret)
+- goto err_free_netdev;
++ goto err_put_dev;
+
+ /* Initialize PHY */
+ ret = pch_gbe_init_phy(adapter);
+@@ -2592,6 +2594,8 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+
+ err_free_adapter:
+ pch_gbe_phy_hw_reset(&adapter->hw);
++err_put_dev:
++ pci_dev_put(adapter->ptp_pdev);
+ err_free_netdev:
+ free_netdev(netdev);
+ return ret;
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 06f4d9a9e9388..5a2d70a91868e 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -2471,6 +2471,7 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
+ skb_shinfo(skb)->nr_frags);
+ if (tx_cb->seg_count == -1) {
+ netdev_err(ndev, "%s: invalid segment count!\n", __func__);
++ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index 17b9d37218cbc..4c33c3b5f32b5 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -217,6 +217,7 @@ netdev_tx_t __ef100_hard_start_xmit(struct sk_buff *skb,
+ skb->len, skb->data_len, channel->channel);
+ if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+ netif_stop_queue(net_dev);
++ dev_kfree_skb_any(skb);
+ goto err;
+ }
+
+diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
+index de94921cbef9f..025e0c19ec255 100644
+--- a/drivers/net/ipvlan/ipvlan.h
++++ b/drivers/net/ipvlan/ipvlan.h
+@@ -98,6 +98,7 @@ struct ipvl_port {
+ struct sk_buff_head backlog;
+ int count;
+ struct ida ida;
++ netdevice_tracker dev_tracker;
+ };
+
+ struct ipvl_skb_cb {
+diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
+index 49ba8a50dfb1e..9043bcd1b41db 100644
+--- a/drivers/net/ipvlan/ipvlan_main.c
++++ b/drivers/net/ipvlan/ipvlan_main.c
+@@ -83,6 +83,7 @@ static int ipvlan_port_create(struct net_device *dev)
+ if (err)
+ goto err;
+
++ netdev_hold(dev, &port->dev_tracker, GFP_KERNEL);
+ return 0;
+
+ err:
+@@ -95,6 +96,7 @@ static void ipvlan_port_destroy(struct net_device *dev)
+ struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
+ struct sk_buff *skb;
+
++ netdev_put(dev, &port->dev_tracker);
+ if (port->mode == IPVLAN_MODE_L3S)
+ ipvlan_l3s_unregister(port);
+ netdev_rx_handler_unregister(dev);
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index ddfa853ec9b53..104fc564a766e 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2685,11 +2685,6 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ if (ret)
+ goto rollback;
+
+- /* Force features update, since they are different for SW MACSec and
+- * HW offloading cases.
+- */
+- netdev_update_features(dev);
+-
+ rtnl_unlock();
+ return 0;
+
+@@ -3457,16 +3452,9 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+ return ret;
+ }
+
+-#define SW_MACSEC_FEATURES \
++#define MACSEC_FEATURES \
+ (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+
+-/* If h/w offloading is enabled, use real device features save for
+- * VLAN_FEATURES - they require additional ops
+- * HW_MACSEC - no reason to report it
+- */
+-#define REAL_DEV_FEATURES(dev) \
+- ((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC))
+-
+ static int macsec_dev_init(struct net_device *dev)
+ {
+ struct macsec_dev *macsec = macsec_priv(dev);
+@@ -3483,12 +3471,8 @@ static int macsec_dev_init(struct net_device *dev)
+ return err;
+ }
+
+- if (macsec_is_offloaded(macsec)) {
+- dev->features = REAL_DEV_FEATURES(real_dev);
+- } else {
+- dev->features = real_dev->features & SW_MACSEC_FEATURES;
+- dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+- }
++ dev->features = real_dev->features & MACSEC_FEATURES;
++ dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+
+ dev->needed_headroom = real_dev->needed_headroom +
+ MACSEC_NEEDED_HEADROOM;
+@@ -3520,10 +3504,7 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
+ struct macsec_dev *macsec = macsec_priv(dev);
+ struct net_device *real_dev = macsec->real_dev;
+
+- if (macsec_is_offloaded(macsec))
+- return REAL_DEV_FEATURES(real_dev);
+-
+- features &= (real_dev->features & SW_MACSEC_FEATURES) |
++ features &= (real_dev->features & MACSEC_FEATURES) |
+ NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
+ features |= NETIF_F_LLTX;
+
+@@ -3874,7 +3855,6 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
+ if (macsec_is_offloaded(macsec)) {
+ const struct macsec_ops *ops;
+ struct macsec_context ctx;
+- int ret;
+
+ ops = macsec_get_ops(netdev_priv(dev), &ctx);
+ if (!ops) {
+diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
+index 59fe356942b51..249e7ee4a2bb9 100644
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -862,8 +862,10 @@ static int at803x_probe(struct phy_device *phydev)
+ .wolopts = 0,
+ };
+
+- if (ccr < 0)
++ if (ccr < 0) {
++ ret = ccr;
+ goto err;
++ }
+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
+
+ switch (mode_cfg) {
+diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
+index 8d5cbda33f66f..0897fdb6254b8 100644
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -1915,6 +1915,7 @@ static const struct driver_info cdc_ncm_zlp_info = {
+ .status = cdc_ncm_status,
+ .rx_fixup = cdc_ncm_rx_fixup,
+ .tx_fixup = cdc_ncm_tx_fixup,
++ .set_rx_mode = usbnet_cdc_update_filter,
+ };
+
+ /* Same as cdc_ncm_info, but with FLAG_WWAN */
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 26c34a7c21bdd..afd6faa4c2ec9 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1357,6 +1357,7 @@ static const struct usb_device_id products[] = {
+ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
+ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
++ {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)}, /* Telit FN980 */
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 9cce7dec7366d..f5c88d232b110 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -3933,12 +3933,11 @@ static int virtnet_probe(struct virtio_device *vdev)
+ return 0;
+
+ free_unregister_netdev:
+- virtio_reset_device(vdev);
+-
+ unregister_netdev(dev);
+ free_failover:
+ net_failover_destroy(vi->failover);
+ free_vqs:
++ virtio_reset_device(vdev);
+ cancel_delayed_work_sync(&vi->refill);
+ free_receive_page_frags(vi);
+ virtnet_del_vqs(vi);
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
+index 2ec56a34fa810..0909d53cefebc 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -27,7 +27,7 @@
+ #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
+ #define ATH11K_QMI_CALDB_SIZE 0x480000
+ #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20
+-#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 3
++#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5
+
+ #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
+ #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037
+diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
+index 10daef81c3553..fb2c35bd73bb1 100644
+--- a/drivers/net/wireless/cisco/airo.c
++++ b/drivers/net/wireless/cisco/airo.c
+@@ -5232,7 +5232,7 @@ static int get_wep_tx_idx(struct airo_info *ai)
+ return -1;
+ }
+
+-static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
++static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key,
+ u16 keylen, int perm, int lock)
+ {
+ static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
+@@ -5283,7 +5283,7 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ struct net_device *dev = pde_data(inode);
+ struct airo_info *ai = dev->ml_priv;
+ int i, rc;
+- char key[16];
++ u8 key[16];
+ u16 index = 0;
+ int j = 0;
+
+@@ -5311,12 +5311,22 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ }
+
+ for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
++ int val;
++
++ if (i % 3 == 2)
++ continue;
++
++ val = hex_to_bin(data->wbuffer[i+j]);
++ if (val < 0) {
++ airo_print_err(ai->dev->name, "WebKey passed invalid key hex");
++ return;
++ }
+ switch(i%3) {
+ case 0:
+- key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
++ key[i/3] = (u8)val << 4;
+ break;
+ case 1:
+- key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
++ key[i/3] |= (u8)val;
+ break;
+ }
+ }
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index a074552bcec3d..3179682daca70 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -910,6 +910,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
++ struct ieee80211_tx_info *cb;
+
+ if (!vp->assoc)
+ return;
+@@ -931,6 +932,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ memcpy(hdr->addr2, mac, ETH_ALEN);
+ memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
+
++ cb = IEEE80211_SKB_CB(skb);
++ cb->control.rates[0].count = 1;
++ cb->control.rates[1].idx = -1;
++
+ rcu_read_lock();
+ mac80211_hwsim_tx_frame(data->hw, skb,
+ rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan);
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index 3ac373d29d936..7362d4d5ea852 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -956,30 +956,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
+ return;
+
+ while (index + sizeof(*e) <= len) {
++ u16 attr_size;
++
+ e = (struct wilc_attr_entry *)&buf[index];
+- if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
++ attr_size = le16_to_cpu(e->attr_len);
++
++ if (index + sizeof(*e) + attr_size > len)
++ return;
++
++ if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
++ attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
+ ch_list_idx = index;
+- else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
++ else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
++ attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
+ op_ch_idx = index;
++
+ if (ch_list_idx && op_ch_idx)
+ break;
+- index += le16_to_cpu(e->attr_len) + sizeof(*e);
++
++ index += sizeof(*e) + attr_size;
+ }
+
+ if (ch_list_idx) {
+- u16 attr_size;
+- struct wilc_ch_list_elem *e;
+- int i;
++ u16 elem_size;
+
+ ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
+- attr_size = le16_to_cpu(ch_list->attr_len);
+- for (i = 0; i < attr_size;) {
++ /* the number of bytes following the final 'elem' member */
++ elem_size = le16_to_cpu(ch_list->attr_len) -
++ (sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
++ for (unsigned int i = 0; i < elem_size;) {
++ struct wilc_ch_list_elem *e;
++
+ e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
++
++ i += sizeof(*e);
++ if (i > elem_size)
++ break;
++
++ i += e->no_of_channels;
++ if (i > elem_size)
++ break;
++
+ if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
+ memset(e->ch_list, sta_ch, e->no_of_channels);
+ break;
+ }
+- i += e->no_of_channels;
+ }
+ }
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index eb1d1ba3a443a..67df8221b5aeb 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+
+ rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
+ if (rsn_ie) {
++ int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
+ int offset = 8;
+
+- param->mode_802_11i = 2;
+- param->rsn_found = true;
+ /* extract RSN capabilities */
+- offset += (rsn_ie[offset] * 4) + 2;
+- offset += (rsn_ie[offset] * 4) + 2;
+- memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++ if (offset < rsn_ie_len) {
++ /* skip over pairwise suites */
++ offset += (rsn_ie[offset] * 4) + 2;
++
++ if (offset < rsn_ie_len) {
++ /* skip over authentication suites */
++ offset += (rsn_ie[offset] * 4) + 2;
++
++ if (offset + 1 < rsn_ie_len) {
++ param->mode_802_11i = 2;
++ param->rsn_found = true;
++ memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++ }
++ }
++ }
+ }
+
+ if (param->rsn_found) {
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_coredump.c b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+index 9acd87724c9de..26ca30476f409 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_coredump.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+@@ -2,6 +2,7 @@
+ /*
+ * Copyright (C) 2020-2021 Intel Corporation.
+ */
++#include <linux/vmalloc.h>
+
+ #include "iosm_ipc_coredump.h"
+
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_devlink.c b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+index 17da85a8f3371..2fe724d623c06 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_devlink.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+@@ -2,6 +2,7 @@
+ /*
+ * Copyright (C) 2020-2021 Intel Corporation.
+ */
++#include <linux/vmalloc.h>
+
+ #include "iosm_ipc_chnl_cfg.h"
+ #include "iosm_ipc_coredump.h"
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 97cb6846c6ae2..f604d4a01e1b2 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -249,7 +249,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ if (object->integer.value == 3)
+ sleep_state = IPC_PCIE_D3L2;
+
+- kfree(object);
++ ACPI_FREE(object);
+
+ default_ret:
+ return sleep_state;
+diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+index 3458af31e8647..7d0f5e4f0a781 100644
+--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
++++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+@@ -165,6 +165,8 @@ static int t7xx_acpi_reset(struct t7xx_pci_dev *t7xx_dev, char *fn_name)
+ return -EFAULT;
+ }
+
++ kfree(buffer.pointer);
++
+ #endif
+ return 0;
+ }
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index 7764b1a4c3cf8..ec87dd21e054a 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -312,6 +312,8 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ int r = 0;
+ struct device *dev = &ndev->nfc_dev->dev;
+ struct nfc_evt_transaction *transaction;
++ u32 aid_len;
++ u8 params_len;
+
+ pr_debug("connectivity gate event: %x\n", event);
+
+@@ -325,26 +327,47 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ * Description Tag Length
+ * AID 81 5 to 16
+ * PARAMETERS 82 0 to 255
++ *
++ * The key differences are aid storage length is variably sized
++ * in the packet, but fixed in nfc_evt_transaction, and that
++ * the aid_len is u8 in the packet, but u32 in the structure,
++ * and the tags in the packet are not included in
++ * nfc_evt_transaction.
++ *
++ * size(b): 1 1 5-16 1 1 0-255
++ * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4
++ * mem name: aid_tag(M) aid_len aid params_tag(M) params_len params
++ * example: 0x81 5-16 X 0x82 0-255 X
+ */
+- if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
+- skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++ if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ return -EPROTO;
+
+- transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
+- if (!transaction)
+- return -ENOMEM;
++ aid_len = skb->data[1];
+
+- transaction->aid_len = skb->data[1];
+- memcpy(transaction->aid, &skb->data[2], transaction->aid_len);
++ if (skb->len < aid_len + 4 ||
++ aid_len > sizeof(transaction->aid))
++ return -EPROTO;
+
+- /* Check next byte is PARAMETERS tag (82) */
+- if (skb->data[transaction->aid_len + 2] !=
+- NFC_EVT_TRANSACTION_PARAMS_TAG)
++ params_len = skb->data[aid_len + 3];
++
++ /* Verify PARAMETERS tag is (82), and final check that there is
++ * enough space in the packet to read everything.
++ */
++ if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG ||
++ skb->len < aid_len + 4 + params_len)
+ return -EPROTO;
+
+- transaction->params_len = skb->data[transaction->aid_len + 3];
+- memcpy(transaction->params, skb->data +
+- transaction->aid_len + 4, transaction->params_len);
++ transaction = devm_kzalloc(dev, sizeof(*transaction) +
++ params_len, GFP_KERNEL);
++ if (!transaction)
++ return -ENOMEM;
++
++ transaction->aid_len = aid_len;
++ transaction->params_len = params_len;
++
++ memcpy(transaction->aid, &skb->data[2], aid_len);
++ memcpy(transaction->params, &skb->data[aid_len + 4],
++ params_len);
+
+ r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
+ break;
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ed47c256dbd27..01c36284e5428 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -675,6 +675,7 @@ void nvme_init_request(struct request *req, struct nvme_command *cmd)
+ if (req->mq_hctx->type == HCTX_TYPE_POLL)
+ req->cmd_flags |= REQ_POLLED;
+ nvme_clear_nvme_request(req);
++ req->rq_flags |= RQF_QUIET;
+ memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd));
+ }
+ EXPORT_SYMBOL_GPL(nvme_init_request);
+@@ -1037,7 +1038,6 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+ goto out;
+ }
+
+- req->rq_flags |= RQF_QUIET;
+ ret = nvme_execute_rq(req, at_head);
+ if (result && ret >= 0)
+ *result = nvme_req(req)->result;
+@@ -1225,7 +1225,6 @@ static void nvme_keep_alive_work(struct work_struct *work)
+ rq->timeout = ctrl->kato * HZ;
+ rq->end_io = nvme_keep_alive_end_io;
+ rq->end_io_data = ctrl;
+- rq->rq_flags |= RQF_QUIET;
+ blk_execute_rq_nowait(rq, false);
+ }
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 1a6423e94eb30..0f34114c4596d 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1438,7 +1438,6 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
+
+ abort_req->end_io = abort_endio;
+ abort_req->end_io_data = NULL;
+- abort_req->rq_flags |= RQF_QUIET;
+ blk_execute_rq_nowait(abort_req, false);
+
+ /*
+@@ -2489,7 +2488,6 @@ static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
+ req->end_io_data = nvmeq;
+
+ init_completion(&nvmeq->delete_done);
+- req->rq_flags |= RQF_QUIET;
+ blk_execute_rq_nowait(req, false);
+ return 0;
+ }
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 7f52d9dac4432..a79eadb953de9 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1215,6 +1215,7 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ const char *page, size_t count)
+ {
+ int pos = 0, len;
++ char *val;
+
+ if (subsys->subsys_discovered) {
+ pr_err("Can't set model number. %s is already assigned\n",
+@@ -1237,9 +1238,11 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ return -EINVAL;
+ }
+
+- subsys->model_number = kmemdup_nul(page, len, GFP_KERNEL);
+- if (!subsys->model_number)
++ val = kmemdup_nul(page, len, GFP_KERNEL);
++ if (!val)
+ return -ENOMEM;
++ kfree(subsys->model_number);
++ subsys->model_number = val;
+ return count;
+ }
+
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index ba64284eaf9fa..f1ec8931dfbc5 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -1613,7 +1613,7 @@ out:
+ }
+
+ static u32 hv_compose_msi_req_v1(
+- struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
++ struct pci_create_interrupt *int_pkt,
+ u32 slot, u8 vector, u16 vector_count)
+ {
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+@@ -1631,6 +1631,35 @@ static u32 hv_compose_msi_req_v1(
+ return sizeof(*int_pkt);
+ }
+
++/*
++ * The vCPU selected by hv_compose_multi_msi_req_get_cpu() and
++ * hv_compose_msi_req_get_cpu() is a "dummy" vCPU because the final vCPU to be
++ * interrupted is specified later in hv_irq_unmask() and communicated to Hyper-V
++ * via the HVCALL_RETARGET_INTERRUPT hypercall. But the choice of dummy vCPU is
++ * not irrelevant because Hyper-V chooses the physical CPU to handle the
++ * interrupts based on the vCPU specified in message sent to the vPCI VSP in
++ * hv_compose_msi_msg(). Hyper-V's choice of pCPU is not visible to the guest,
++ * but assigning too many vPCI device interrupts to the same pCPU can cause a
++ * performance bottleneck. So we spread out the dummy vCPUs to influence Hyper-V
++ * to spread out the pCPUs that it selects.
++ *
++ * For the single-MSI and MSI-X cases, it's OK for hv_compose_msi_req_get_cpu()
++ * to always return the same dummy vCPU, because a second call to
++ * hv_compose_msi_msg() contains the "real" vCPU, causing Hyper-V to choose a
++ * new pCPU for the interrupt. But for the multi-MSI case, the second call to
++ * hv_compose_msi_msg() exits without sending a message to the vPCI VSP, so the
++ * original dummy vCPU is used. This dummy vCPU must be round-robin'ed so that
++ * the pCPUs are spread out. All interrupts for a multi-MSI device end up using
++ * the same pCPU, even though the vCPUs will be spread out by later calls
++ * to hv_irq_unmask(), but that is the best we can do now.
++ *
++ * With Hyper-V in Nov 2022, the HVCALL_RETARGET_INTERRUPT hypercall does *not*
++ * cause Hyper-V to reselect the pCPU based on the specified vCPU. Such an
++ * enhancement is planned for a future version. With that enhancement, the
++ * dummy vCPU selection won't matter, and interrupts for the same multi-MSI
++ * device will be spread across multiple pCPUs.
++ */
++
+ /*
+ * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten
+ * by subsequent retarget in hv_irq_unmask().
+@@ -1640,18 +1669,39 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
+ return cpumask_first_and(affinity, cpu_online_mask);
+ }
+
+-static u32 hv_compose_msi_req_v2(
+- struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
+- u32 slot, u8 vector, u16 vector_count)
++/*
++ * Make sure the dummy vCPU values for multi-MSI don't all point to vCPU0.
++ */
++static int hv_compose_multi_msi_req_get_cpu(void)
+ {
++ static DEFINE_SPINLOCK(multi_msi_cpu_lock);
++
++ /* -1 means starting with CPU 0 */
++ static int cpu_next = -1;
++
++ unsigned long flags;
+ int cpu;
+
++ spin_lock_irqsave(&multi_msi_cpu_lock, flags);
++
++ cpu_next = cpumask_next_wrap(cpu_next, cpu_online_mask, nr_cpu_ids,
++ false);
++ cpu = cpu_next;
++
++ spin_unlock_irqrestore(&multi_msi_cpu_lock, flags);
++
++ return cpu;
++}
++
++static u32 hv_compose_msi_req_v2(
++ struct pci_create_interrupt2 *int_pkt, int cpu,
++ u32 slot, u8 vector, u16 vector_count)
++{
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2;
+ int_pkt->wslot.slot = slot;
+ int_pkt->int_desc.vector = vector;
+ int_pkt->int_desc.vector_count = vector_count;
+ int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+- cpu = hv_compose_msi_req_get_cpu(affinity);
+ int_pkt->int_desc.processor_array[0] =
+ hv_cpu_number_to_vp_number(cpu);
+ int_pkt->int_desc.processor_count = 1;
+@@ -1660,18 +1710,15 @@ static u32 hv_compose_msi_req_v2(
+ }
+
+ static u32 hv_compose_msi_req_v3(
+- struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
++ struct pci_create_interrupt3 *int_pkt, int cpu,
+ u32 slot, u32 vector, u16 vector_count)
+ {
+- int cpu;
+-
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE3;
+ int_pkt->wslot.slot = slot;
+ int_pkt->int_desc.vector = vector;
+ int_pkt->int_desc.reserved = 0;
+ int_pkt->int_desc.vector_count = vector_count;
+ int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+- cpu = hv_compose_msi_req_get_cpu(affinity);
+ int_pkt->int_desc.processor_array[0] =
+ hv_cpu_number_to_vp_number(cpu);
+ int_pkt->int_desc.processor_count = 1;
+@@ -1715,12 +1762,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ struct pci_create_interrupt3 v3;
+ } int_pkts;
+ } __packed ctxt;
++ bool multi_msi;
+ u64 trans_id;
+ u32 size;
+ int ret;
++ int cpu;
++
++ msi_desc = irq_data_get_msi_desc(data);
++ multi_msi = !msi_desc->pci.msi_attrib.is_msix &&
++ msi_desc->nvec_used > 1;
+
+ /* Reuse the previous allocation */
+- if (data->chip_data) {
++ if (data->chip_data && multi_msi) {
+ int_desc = data->chip_data;
+ msg->address_hi = int_desc->address >> 32;
+ msg->address_lo = int_desc->address & 0xffffffff;
+@@ -1728,7 +1781,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ return;
+ }
+
+- msi_desc = irq_data_get_msi_desc(data);
+ pdev = msi_desc_to_pci_dev(msi_desc);
+ dest = irq_data_get_effective_affinity_mask(data);
+ pbus = pdev->bus;
+@@ -1738,11 +1790,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ if (!hpdev)
+ goto return_null_message;
+
++ /* Free any previous message that might have already been composed. */
++ if (data->chip_data && !multi_msi) {
++ int_desc = data->chip_data;
++ data->chip_data = NULL;
++ hv_int_desc_free(hpdev, int_desc);
++ }
++
+ int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
+ if (!int_desc)
+ goto drop_reference;
+
+- if (!msi_desc->pci.msi_attrib.is_msix && msi_desc->nvec_used > 1) {
++ if (multi_msi) {
+ /*
+ * If this is not the first MSI of Multi MSI, we already have
+ * a mapping. Can exit early.
+@@ -1767,9 +1826,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ */
+ vector = 32;
+ vector_count = msi_desc->nvec_used;
++ cpu = hv_compose_multi_msi_req_get_cpu();
+ } else {
+ vector = hv_msi_get_int_vector(data);
+ vector_count = 1;
++ cpu = hv_compose_msi_req_get_cpu(dest);
+ }
+
+ /*
+@@ -1785,7 +1846,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ switch (hbus->protocol_version) {
+ case PCI_PROTOCOL_VERSION_1_1:
+ size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+- dest,
+ hpdev->desc.win_slot.slot,
+ (u8)vector,
+ vector_count);
+@@ -1794,7 +1854,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ case PCI_PROTOCOL_VERSION_1_2:
+ case PCI_PROTOCOL_VERSION_1_3:
+ size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+- dest,
++ cpu,
+ hpdev->desc.win_slot.slot,
+ (u8)vector,
+ vector_count);
+@@ -1802,7 +1862,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+
+ case PCI_PROTOCOL_VERSION_1_4:
+ size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3,
+- dest,
++ cpu,
+ hpdev->desc.win_slot.slot,
+ vector,
+ vector_count);
+diff --git a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+index aa2075390f3eb..e96c00686a25b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
++++ b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+@@ -1873,8 +1873,8 @@ static const struct msm_pingroup sc8280xp_groups[] = {
+ [225] = PINGROUP(225, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ [226] = PINGROUP(226, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ [227] = PINGROUP(227, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+- [228] = UFS_RESET(ufs_reset, 0xf1004),
+- [229] = UFS_RESET(ufs1_reset, 0xf3004),
++ [228] = UFS_RESET(ufs_reset, 0xf1000),
++ [229] = UFS_RESET(ufs1_reset, 0xf3000),
+ [230] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe8000, 14, 6),
+ [231] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe8000, 11, 3),
+ [232] = SDC_QDSD_PINGROUP(sdc2_data, 0xe8000, 9, 0),
+diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
+index 585911020cea0..023f126121d7d 100644
+--- a/drivers/platform/surface/surface_aggregator_registry.c
++++ b/drivers/platform/surface/surface_aggregator_registry.c
+@@ -234,6 +234,19 @@ static const struct software_node *ssam_node_group_sl3[] = {
+ NULL,
+ };
+
++/* Devices for Surface Laptop 5. */
++static const struct software_node *ssam_node_group_sl5[] = {
++ &ssam_node_root,
++ &ssam_node_bat_ac,
++ &ssam_node_bat_main,
++ &ssam_node_tmp_pprof,
++ &ssam_node_hid_main_keyboard,
++ &ssam_node_hid_main_touchpad,
++ &ssam_node_hid_main_iid5,
++ &ssam_node_hid_sam_ucm_ucsi,
++ NULL,
++};
++
+ /* Devices for Surface Laptop Studio. */
+ static const struct software_node *ssam_node_group_sls[] = {
+ &ssam_node_root,
+@@ -268,6 +281,7 @@ static const struct software_node *ssam_node_group_sp7[] = {
+ NULL,
+ };
+
++/* Devices for Surface Pro 8 */
+ static const struct software_node *ssam_node_group_sp8[] = {
+ &ssam_node_root,
+ &ssam_node_hub_kip,
+@@ -284,6 +298,23 @@ static const struct software_node *ssam_node_group_sp8[] = {
+ NULL,
+ };
+
++/* Devices for Surface Pro 9 */
++static const struct software_node *ssam_node_group_sp9[] = {
++ &ssam_node_root,
++ &ssam_node_hub_kip,
++ &ssam_node_bat_ac,
++ &ssam_node_bat_main,
++ &ssam_node_tmp_pprof,
++ /* TODO: Tablet mode switch (via POS subsystem) */
++ &ssam_node_hid_kip_keyboard,
++ &ssam_node_hid_kip_penstash,
++ &ssam_node_hid_kip_touchpad,
++ &ssam_node_hid_kip_fwupd,
++ &ssam_node_hid_sam_sensors,
++ &ssam_node_hid_sam_ucm_ucsi,
++ NULL,
++};
++
+
+ /* -- SSAM platform/meta-hub driver. ---------------------------------------- */
+
+@@ -303,6 +334,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ /* Surface Pro 8 */
+ { "MSHW0263", (unsigned long)ssam_node_group_sp8 },
+
++ /* Surface Pro 9 */
++ { "MSHW0343", (unsigned long)ssam_node_group_sp9 },
++
+ /* Surface Book 2 */
+ { "MSHW0107", (unsigned long)ssam_node_group_gen5 },
+
+@@ -324,6 +358,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ /* Surface Laptop 4 (13", Intel) */
+ { "MSHW0250", (unsigned long)ssam_node_group_sl3 },
+
++ /* Surface Laptop 5 */
++ { "MSHW0350", (unsigned long)ssam_node_group_sl5 },
++
+ /* Surface Laptop Go 1 */
+ { "MSHW0118", (unsigned long)ssam_node_group_slg1 },
+
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
+index f1259d81d86da..df4c1f08f0c6a 100644
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -564,6 +564,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
+ },
+ .driver_data = (void *)ACER_CAP_KBD_DOCK,
+ },
++ {
++ .callback = set_force_caps,
++ .ident = "Acer Aspire Switch V 10 SW5-017",
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++ },
++ .driver_data = (void *)ACER_CAP_KBD_DOCK,
++ },
+ {
+ .callback = set_force_caps,
+ .ident = "Acer One 10 (S1003)",
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index eec7d0ed7cf21..8e1979b477a7d 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -1656,6 +1656,8 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
+ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
+ cpu_to_le32(ports_available));
+
++ pci_dev_put(xhci_pdev);
++
+ pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
+ orig_ports_available, ports_available);
+ }
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index 4fbe91769c915..788381e4c6a64 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -90,6 +90,7 @@ enum hp_wmi_event_ids {
+ HPWMI_PEAKSHIFT_PERIOD = 0x0F,
+ HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
+ HPWMI_SANITIZATION_MODE = 0x17,
++ HPWMI_SMART_EXPERIENCE_APP = 0x21,
+ };
+
+ /*
+@@ -857,6 +858,8 @@ static void hp_wmi_notify(u32 value, void *context)
+ break;
+ case HPWMI_SANITIZATION_MODE:
+ break;
++ case HPWMI_SMART_EXPERIENCE_APP:
++ break;
+ default:
+ pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
+ break;
+diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
+index abd0c81d62c40..3ea8fc6a9ca36 100644
+--- a/drivers/platform/x86/ideapad-laptop.c
++++ b/drivers/platform/x86/ideapad-laptop.c
+@@ -136,6 +136,7 @@ struct ideapad_private {
+ bool dytc : 1;
+ bool fan_mode : 1;
+ bool fn_lock : 1;
++ bool set_fn_lock_led : 1;
+ bool hw_rfkill_switch : 1;
+ bool kbd_bl : 1;
+ bool touchpad_ctrl_via_ec : 1;
+@@ -154,7 +155,21 @@ MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
+
+ static bool allow_v4_dytc;
+ module_param(allow_v4_dytc, bool, 0444);
+-MODULE_PARM_DESC(allow_v4_dytc, "Enable DYTC version 4 platform-profile support.");
++MODULE_PARM_DESC(allow_v4_dytc,
++ "Enable DYTC version 4 platform-profile support. "
++ "If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool hw_rfkill_switch;
++module_param(hw_rfkill_switch, bool, 0444);
++MODULE_PARM_DESC(hw_rfkill_switch,
++ "Enable rfkill support for laptops with a hw on/off wifi switch/slider. "
++ "If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool set_fn_lock_led;
++module_param(set_fn_lock_led, bool, 0444);
++MODULE_PARM_DESC(set_fn_lock_led,
++ "Enable driver based updates of the fn-lock LED on fn-lock changes. "
++ "If you need this please report this to: platform-driver-x86@vger.kernel.org");
+
+ /*
+ * ACPI Helpers
+@@ -1501,6 +1516,9 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ ideapad_input_report(priv, value);
+ break;
+ case 208:
++ if (!priv->features.set_fn_lock_led)
++ break;
++
+ if (!eval_hals(priv->adev->handle, &result)) {
+ bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
+
+@@ -1514,6 +1532,18 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ }
+ #endif
+
++/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */
++static const struct dmi_system_id set_fn_lock_led_list[] = {
++ {
++ /* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"),
++ }
++ },
++ {}
++};
++
+ /*
+ * Some ideapads have a hardware rfkill switch, but most do not have one.
+ * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill,
+@@ -1533,15 +1563,41 @@ static const struct dmi_system_id hw_rfkill_list[] = {
+ {}
+ };
+
++static const struct dmi_system_id no_touchpad_switch_list[] = {
++ {
++ .ident = "Lenovo Yoga 3 Pro 1370",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
++ },
++ },
++ {
++ .ident = "ZhaoYang K4e-IML",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"),
++ },
++ },
++ {}
++};
++
+ static void ideapad_check_features(struct ideapad_private *priv)
+ {
+ acpi_handle handle = priv->adev->handle;
+ unsigned long val;
+
+- priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
++ priv->features.set_fn_lock_led =
++ set_fn_lock_led || dmi_check_system(set_fn_lock_led_list);
++ priv->features.hw_rfkill_switch =
++ hw_rfkill_switch || dmi_check_system(hw_rfkill_list);
+
+ /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
+- priv->features.touchpad_ctrl_via_ec = !acpi_dev_present("ELAN0634", NULL, -1);
++ if (acpi_dev_present("ELAN0634", NULL, -1))
++ priv->features.touchpad_ctrl_via_ec = 0;
++ else if (dmi_check_system(no_touchpad_switch_list))
++ priv->features.touchpad_ctrl_via_ec = 0;
++ else
++ priv->features.touchpad_ctrl_via_ec = 1;
+
+ if (!read_ec_data(handle, VPCCMD_R_FAN, &val))
+ priv->features.fan_mode = true;
+diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c
+index 79cff1fc675c2..b6313ecd190c0 100644
+--- a/drivers/platform/x86/intel/hid.c
++++ b/drivers/platform/x86/intel/hid.c
+@@ -27,6 +27,9 @@ static const struct acpi_device_id intel_hid_ids[] = {
+ {"INTC1051", 0},
+ {"INTC1054", 0},
+ {"INTC1070", 0},
++ {"INTC1076", 0},
++ {"INTC1077", 0},
++ {"INTC1078", 0},
+ {"", 0},
+ };
+ MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
+diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
+index 53d7fd2943b4c..46598dcb634aa 100644
+--- a/drivers/platform/x86/intel/pmt/class.c
++++ b/drivers/platform/x86/intel/pmt/class.c
+@@ -9,6 +9,7 @@
+ */
+
+ #include <linux/kernel.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/pci.h>
+@@ -19,6 +20,7 @@
+ #define PMT_XA_START 0
+ #define PMT_XA_MAX INT_MAX
+ #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX)
++#define GUID_SPR_PUNIT 0x9956f43f
+
+ bool intel_pmt_is_early_client_hw(struct device *dev)
+ {
+@@ -33,6 +35,29 @@ bool intel_pmt_is_early_client_hw(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw);
+
++static inline int
++pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
++{
++ int i, remain;
++ u64 *buf = to;
++
++ if (!IS_ALIGNED((unsigned long)from, 8))
++ return -EFAULT;
++
++ for (i = 0; i < count/8; i++)
++ buf[i] = readq(&from[i]);
++
++ /* Copy any remaining bytes */
++ remain = count % 8;
++ if (remain) {
++ u64 tmp = readq(&from[i]);
++
++ memcpy(&buf[i], &tmp, remain);
++ }
++
++ return count;
++}
++
+ /*
+ * sysfs
+ */
+@@ -54,7 +79,11 @@ intel_pmt_read(struct file *filp, struct kobject *kobj,
+ if (count > entry->size - off)
+ count = entry->size - off;
+
+- memcpy_fromio(buf, entry->base + off, count);
++ if (entry->guid == GUID_SPR_PUNIT)
++ /* PUNIT on SPR only supports aligned 64-bit read */
++ count = pmt_memcpy64_fromio(buf, entry->base + off, count);
++ else
++ memcpy_fromio(buf, entry->base + off, count);
+
+ return count;
+ }
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 353507d18e11c..67dc335fca0c6 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -4497,6 +4497,14 @@ static const struct dmi_system_id fwbug_list[] __initconst = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
+ }
+ },
++ {
++ .ident = "P14s Gen2 AMD",
++ .driver_data = &quirk_s2idle_bug,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
++ }
++ },
+ {}
+ };
+
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index bc97bfa8e8a65..baae3120efd05 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -770,6 +770,22 @@ static const struct ts_dmi_data predia_basic_data = {
+ .properties = predia_basic_props,
+ };
+
++static const struct property_entry rca_cambio_w101_v2_props[] = {
++ PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
++ PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1644),
++ PROPERTY_ENTRY_U32("touchscreen-size-y", 874),
++ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"),
++ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
++ { }
++};
++
++static const struct ts_dmi_data rca_cambio_w101_v2_data = {
++ .acpi_name = "MSSL1680:00",
++ .properties = rca_cambio_w101_v2_props,
++};
++
+ static const struct property_entry rwc_nanote_p8_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-min-y", 46),
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+@@ -1409,6 +1425,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
+ },
+ },
++ {
++ /* RCA Cambio W101 v2 */
++ /* https://github.com/onitake/gsl-firmware/discussions/193 */
++ .driver_data = (void *)&rca_cambio_w101_v2_data,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "RCA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "W101SA23T1"),
++ },
++ },
+ {
+ /* RWC NANOTE P8 */
+ .driver_data = (void *)&rwc_nanote_p8_data,
+diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
+index 863fabe05bdcf..307ee6f71042e 100644
+--- a/drivers/power/supply/ab8500_btemp.c
++++ b/drivers/power/supply/ab8500_btemp.c
+@@ -725,7 +725,14 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
+ /* Get thermal zone and ADC */
+ di->tz = thermal_zone_get_zone_by_name("battery-thermal");
+ if (IS_ERR(di->tz)) {
+- return dev_err_probe(dev, PTR_ERR(di->tz),
++ ret = PTR_ERR(di->tz);
++ /*
++ * This usually just means we are probing before the thermal
++ * zone, so just defer.
++ */
++ if (ret == -ENODEV)
++ ret = -EPROBE_DEFER;
++ return dev_err_probe(dev, ret,
+ "failed to get battery thermal zone\n");
+ }
+ di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl");
+diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c
+index 218e8e689a3fb..00221e9c0bfcc 100644
+--- a/drivers/power/supply/ip5xxx_power.c
++++ b/drivers/power/supply/ip5xxx_power.c
+@@ -352,7 +352,7 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
+ ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATIADC_DAT0,
+ IP5XXX_BATIADC_DAT1, &raw);
+
+- val->intval = DIV_ROUND_CLOSEST(raw * 745985, 1000);
++ val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200);
+ return 0;
+
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index c3871565fd7d2..c0f368f1b49f7 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5138,6 +5138,7 @@ static void regulator_dev_release(struct device *dev)
+ {
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+
++ debugfs_remove_recursive(rdev->debugfs);
+ kfree(rdev->constraints);
+ of_node_put(rdev->dev.of_node);
+ kfree(rdev);
+@@ -5616,11 +5617,15 @@ wash:
+ mutex_lock(®ulator_list_mutex);
+ regulator_ena_gpio_free(rdev);
+ mutex_unlock(®ulator_list_mutex);
++ put_device(&rdev->dev);
++ rdev = NULL;
+ clean:
+ if (dangling_of_gpiod)
+ gpiod_put(config->ena_gpiod);
++ if (rdev && rdev->dev.of_node)
++ of_node_put(rdev->dev.of_node);
++ kfree(rdev);
+ kfree(config);
+- put_device(&rdev->dev);
+ rinse:
+ if (dangling_cfg_gpiod)
+ gpiod_put(cfg->ena_gpiod);
+@@ -5649,7 +5654,6 @@ void regulator_unregister(struct regulator_dev *rdev)
+
+ mutex_lock(®ulator_list_mutex);
+
+- debugfs_remove_recursive(rdev->debugfs);
+ WARN_ON(rdev->open_count);
+ regulator_remove_coupling(rdev);
+ unset_regulator_supplies(rdev);
+diff --git a/drivers/regulator/rt5759-regulator.c b/drivers/regulator/rt5759-regulator.c
+index 6b96899eb27e3..8488417f4b2cf 100644
+--- a/drivers/regulator/rt5759-regulator.c
++++ b/drivers/regulator/rt5759-regulator.c
+@@ -243,6 +243,7 @@ static int rt5759_regulator_register(struct rt5759_priv *priv)
+ if (priv->chip_type == CHIP_TYPE_RT5759A)
+ reg_desc->uV_step = RT5759A_STEP_UV;
+
++ memset(®_cfg, 0, sizeof(reg_cfg));
+ reg_cfg.dev = priv->dev;
+ reg_cfg.of_node = np;
+ reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc);
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 430265c404d65..7c7e3648ea4bf 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -530,6 +530,7 @@ static const struct twlreg_info TWL6030_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_LDO(label, offset) \
+ static const struct twlreg_info TWL6032_INFO_##label = { \
+ .base = offset, \
++ .features = TWL6032_SUBCLASS, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL6032_REG_##label, \
+@@ -562,6 +563,7 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \
+ static const struct twlreg_info TWLSMPS_INFO_##label = { \
+ .base = offset, \
++ .features = TWL6032_SUBCLASS, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL6032_REG_##label, \
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 3cc93e2e4e15a..2dec81e7e6ab1 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -4681,7 +4681,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ struct dasd_device *basedev;
+ struct req_iterator iter;
+ struct dasd_ccw_req *cqr;
+- unsigned int first_offs;
+ unsigned int trkcount;
+ unsigned long *idaws;
+ unsigned int size;
+@@ -4715,7 +4714,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
+ DASD_RAW_SECTORS_PER_TRACK;
+ trkcount = last_trk - first_trk + 1;
+- first_offs = 0;
+
+ if (rq_data_dir(req) == READ)
+ cmd = DASD_ECKD_CCW_READ_TRACK;
+@@ -4759,13 +4757,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+
+ if (use_prefix) {
+ prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
+- startdev, 1, first_offs + 1, trkcount, 0, 0);
++ startdev, 1, 0, trkcount, 0, 0);
+ } else {
+ define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
+ ccw[-1].flags |= CCW_FLAG_CC;
+
+ data += sizeof(struct DE_eckd_data);
+- locate_record_ext(ccw++, data, first_trk, first_offs + 1,
++ locate_record_ext(ccw++, data, first_trk, 0,
+ trkcount, cmd, basedev, 0, 0);
+ }
+
+diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
+index 59ac98f2bd275..b02c631f3b71a 100644
+--- a/drivers/s390/crypto/ap_bus.c
++++ b/drivers/s390/crypto/ap_bus.c
+@@ -233,8 +233,11 @@ static void __init ap_init_qci_info(void)
+ if (!ap_qci_info)
+ return;
+ ap_qci_info_old = kzalloc(sizeof(*ap_qci_info_old), GFP_KERNEL);
+- if (!ap_qci_info_old)
++ if (!ap_qci_info_old) {
++ kfree(ap_qci_info);
++ ap_qci_info = NULL;
+ return;
++ }
+ if (ap_fetch_qci_info(ap_qci_info) != 0) {
+ kfree(ap_qci_info);
+ kfree(ap_qci_info_old);
+diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
+index 8fb34b8eeb189..5ad2514775931 100644
+--- a/drivers/s390/crypto/zcrypt_msgtype6.c
++++ b/drivers/s390/crypto/zcrypt_msgtype6.c
+@@ -342,7 +342,10 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ };
+ struct {
+ struct type6_hdr hdr;
+- struct CPRBX cprbx;
++ union {
++ struct CPRBX cprbx;
++ DECLARE_FLEX_ARRAY(u8, userdata);
++ };
+ } __packed * msg = ap_msg->msg;
+
+ int rcblen = CEIL4(xcrb->request_control_blk_length);
+@@ -403,7 +406,8 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ msg->hdr.fromcardlen2 = xcrb->reply_data_length;
+
+ /* prepare CPRB */
+- if (z_copy_from_user(userspace, &msg->cprbx, xcrb->request_control_blk_addr,
++ if (z_copy_from_user(userspace, msg->userdata,
++ xcrb->request_control_blk_addr,
+ xcrb->request_control_blk_length))
+ return -EFAULT;
+ if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
+@@ -469,9 +473,14 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+
+ struct {
+ struct type6_hdr hdr;
+- struct ep11_cprb cprbx;
+- unsigned char pld_tag; /* fixed value 0x30 */
+- unsigned char pld_lenfmt; /* payload length format */
++ union {
++ struct {
++ struct ep11_cprb cprbx;
++ unsigned char pld_tag; /* fixed value 0x30 */
++ unsigned char pld_lenfmt; /* length format */
++ } __packed;
++ DECLARE_FLEX_ARRAY(u8, userdata);
++ };
+ } __packed * msg = ap_msg->msg;
+
+ struct pld_hdr {
+@@ -500,7 +509,7 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+ msg->hdr.fromcardlen1 = xcrb->resp_len;
+
+ /* Import CPRB data from the ioctl input parameter */
+- if (z_copy_from_user(userspace, &msg->cprbx.cprb_len,
++ if (z_copy_from_user(userspace, msg->userdata,
+ (char __force __user *)xcrb->req, xcrb->req_len)) {
+ return -EFAULT;
+ }
+diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
+index 00684e11976be..1a0c0b7289d26 100644
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -708,8 +708,13 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost)
+ memset(vhost->async_crq.msgs.async, 0, PAGE_SIZE);
+ vhost->async_crq.cur = 0;
+
+- list_for_each_entry(tgt, &vhost->targets, queue)
+- ibmvfc_del_tgt(tgt);
++ list_for_each_entry(tgt, &vhost->targets, queue) {
++ if (vhost->client_migrated)
++ tgt->need_login = 1;
++ else
++ ibmvfc_del_tgt(tgt);
++ }
++
+ scsi_block_requests(vhost->host);
+ ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+ vhost->job_step = ibmvfc_npiv_login;
+@@ -3235,9 +3240,12 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost,
+ /* We need to re-setup the interpartition connection */
+ dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n");
+ vhost->client_migrated = 1;
++
++ scsi_block_requests(vhost->host);
+ ibmvfc_purge_requests(vhost, DID_REQUEUE);
+- ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
++ ibmvfc_set_host_state(vhost, IBMVFC_LINK_DOWN);
+ ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE);
++ wake_up(&vhost->work_wait_q);
+ } else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) {
+ dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format);
+ ibmvfc_purge_requests(vhost, DID_ERROR);
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index bfa1165e23b67..1b4d1e562de86 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -2930,7 +2930,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,
+ }
+
+ if (scmd->result != (DID_OK << 16) && (scmd->cmnd[0] != ATA_12) &&
+- (scmd->cmnd[0] != ATA_16)) {
++ (scmd->cmnd[0] != ATA_16) &&
++ mrioc->logging_level & MPI3_DEBUG_SCSI_ERROR) {
+ ioc_info(mrioc, "%s :scmd->result 0x%x\n", __func__,
+ scmd->result);
+ scsi_print_command(scmd);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 95f940f5c996d..7346098c1c68f 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -1899,6 +1899,13 @@ static int resp_readcap16(struct scsi_cmnd *scp,
+ arr[14] |= 0x40;
+ }
+
++ /*
++ * Since the scsi_debug READ CAPACITY implementation always reports the
++ * total disk capacity, set RC BASIS = 1 for host-managed ZBC devices.
++ */
++ if (devip->zmodel == BLK_ZONED_HM)
++ arr[12] |= 1 << 4;
++
+ arr[15] = sdebug_lowest_aligned & 0xff;
+
+ if (have_dif_prot) {
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index cd3db9684e52d..f473c002fa4d6 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -231,7 +231,7 @@ iscsi_create_endpoint(int dd_size)
+ dev_set_name(&ep->dev, "ep-%d", id);
+ err = device_register(&ep->dev);
+ if (err)
+- goto free_id;
++ goto put_dev;
+
+ err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
+ if (err)
+@@ -245,10 +245,12 @@ unregister_dev:
+ device_unregister(&ep->dev);
+ return NULL;
+
+-free_id:
++put_dev:
+ mutex_lock(&iscsi_ep_idr_mutex);
+ idr_remove(&iscsi_ep_idr, id);
+ mutex_unlock(&iscsi_ep_idr_mutex);
++ put_device(&ep->dev);
++ return NULL;
+ free_ep:
+ kfree(ep);
+ return NULL;
+@@ -766,7 +768,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
+
+ err = device_register(&iface->dev);
+ if (err)
+- goto free_iface;
++ goto put_dev;
+
+ err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
+ if (err)
+@@ -780,9 +782,8 @@ unreg_iface:
+ device_unregister(&iface->dev);
+ return NULL;
+
+-free_iface:
+- put_device(iface->dev.parent);
+- kfree(iface);
++put_dev:
++ put_device(&iface->dev);
+ return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_iface);
+@@ -1251,15 +1252,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
+
+ err = device_register(&fnode_sess->dev);
+ if (err)
+- goto free_fnode_sess;
++ goto put_dev;
+
+ if (dd_size)
+ fnode_sess->dd_data = &fnode_sess[1];
+
+ return fnode_sess;
+
+-free_fnode_sess:
+- kfree(fnode_sess);
++put_dev:
++ put_device(&fnode_sess->dev);
+ return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
+@@ -1299,15 +1300,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
+
+ err = device_register(&fnode_conn->dev);
+ if (err)
+- goto free_fnode_conn;
++ goto put_dev;
+
+ if (dd_size)
+ fnode_conn->dd_data = &fnode_conn[1];
+
+ return fnode_conn;
+
+-free_fnode_conn:
+- kfree(fnode_conn);
++put_dev:
++ put_device(&fnode_conn->dev);
+ return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
+@@ -4815,7 +4816,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ dev_set_name(&priv->dev, "%s", tt->name);
+ err = device_register(&priv->dev);
+ if (err)
+- goto free_priv;
++ goto put_dev;
+
+ err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
+ if (err)
+@@ -4850,8 +4851,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ unregister_dev:
+ device_unregister(&priv->dev);
+ return NULL;
+-free_priv:
+- kfree(priv);
++put_dev:
++ put_device(&priv->dev);
+ return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_register_transport);
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 8ced292c4b962..d93604318ecd3 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -300,16 +300,21 @@ enum storvsc_request_type {
+ };
+
+ /*
+- * SRB status codes and masks; a subset of the codes used here.
++ * SRB status codes and masks. In the 8-bit field, the two high order bits
++ * are flags, while the remaining 6 bits are an integer status code. The
++ * definitions here include only the subset of the integer status codes that
++ * are tested for in this driver.
+ */
+-
+ #define SRB_STATUS_AUTOSENSE_VALID 0x80
+ #define SRB_STATUS_QUEUE_FROZEN 0x40
+-#define SRB_STATUS_INVALID_LUN 0x20
+-#define SRB_STATUS_SUCCESS 0x01
+-#define SRB_STATUS_ABORTED 0x02
+-#define SRB_STATUS_ERROR 0x04
+-#define SRB_STATUS_DATA_OVERRUN 0x12
++
++/* SRB status integer codes */
++#define SRB_STATUS_SUCCESS 0x01
++#define SRB_STATUS_ABORTED 0x02
++#define SRB_STATUS_ERROR 0x04
++#define SRB_STATUS_INVALID_REQUEST 0x06
++#define SRB_STATUS_DATA_OVERRUN 0x12
++#define SRB_STATUS_INVALID_LUN 0x20
+
+ #define SRB_STATUS(status) \
+ (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -966,38 +971,25 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ void (*process_err_fn)(struct work_struct *work);
+ struct hv_host_device *host_dev = shost_priv(host);
+
+- /*
+- * In some situations, Hyper-V sets multiple bits in the
+- * srb_status, such as ABORTED and ERROR. So process them
+- * individually, with the most specific bits first.
+- */
+-
+- if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) {
+- set_host_byte(scmnd, DID_NO_CONNECT);
+- process_err_fn = storvsc_remove_lun;
+- goto do_work;
+- }
++ switch (SRB_STATUS(vm_srb->srb_status)) {
++ case SRB_STATUS_ERROR:
++ case SRB_STATUS_ABORTED:
++ case SRB_STATUS_INVALID_REQUEST:
++ if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) {
++ /* Check for capacity change */
++ if ((asc == 0x2a) && (ascq == 0x9)) {
++ process_err_fn = storvsc_device_scan;
++ /* Retry the I/O that triggered this. */
++ set_host_byte(scmnd, DID_REQUEUE);
++ goto do_work;
++ }
+
+- if (vm_srb->srb_status & SRB_STATUS_ABORTED) {
+- if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+- /* Capacity data has changed */
+- (asc == 0x2a) && (ascq == 0x9)) {
+- process_err_fn = storvsc_device_scan;
+ /*
+- * Retry the I/O that triggered this.
++ * Otherwise, let upper layer deal with the
++ * error when sense message is present
+ */
+- set_host_byte(scmnd, DID_REQUEUE);
+- goto do_work;
+- }
+- }
+-
+- if (vm_srb->srb_status & SRB_STATUS_ERROR) {
+- /*
+- * Let upper layer deal with error when
+- * sense message is present.
+- */
+- if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
+ return;
++ }
+
+ /*
+ * If there is an error; offline the device since all
+@@ -1020,6 +1012,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ default:
+ set_host_byte(scmnd, DID_ERROR);
+ }
++ return;
++
++ case SRB_STATUS_INVALID_LUN:
++ set_host_byte(scmnd, DID_NO_CONNECT);
++ process_err_fn = storvsc_remove_lun;
++ goto do_work;
++
+ }
+ return;
+
+diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
+index 1322b8cce5b7c..ababb910b3914 100644
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -128,12 +128,15 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
+
+ dw_spi_dma_sg_burst_init(dws);
+
++ pci_dev_put(dma_dev);
++
+ return 0;
+
+ free_rxchan:
+ dma_release_channel(dws->rxchan);
+ dws->rxchan = NULL;
+ err_exit:
++ pci_dev_put(dma_dev);
+ return -EBUSY;
+ }
+
+diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
+index 30d82cc7300b2..d209930069cf3 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -444,8 +444,7 @@ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
+ unsigned int pre, post;
+ unsigned int fin = spi_imx->spi_clk;
+
+- if (unlikely(fspi > fin))
+- return 0;
++ fspi = min(fspi, fin);
+
+ post = fls(fin) - fls(fspi);
+ if (fin > fspi << post)
+@@ -1607,6 +1606,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ if (spi_imx->slave_mode)
+ return spi_imx_pio_transfer_slave(spi, transfer);
+
++ /*
++ * If we decided in spi_imx_can_dma() that we want to do a DMA
++ * transfer, the SPI transfer has already been mapped, so we
++ * have to do the DMA transfer here.
++ */
++ if (spi_imx->usedma)
++ return spi_imx_dma_transfer(spi_imx, transfer);
+ /*
+ * Calculate the estimated time in us the transfer runs. Find
+ * the number of Hz per byte per polling limit.
+@@ -1618,9 +1624,6 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ if (transfer->len < byte_limit)
+ return spi_imx_poll_transfer(spi, transfer);
+
+- if (spi_imx->usedma)
+- return spi_imx_dma_transfer(spi_imx, transfer);
+-
+ return spi_imx_pio_transfer(spi, transfer);
+ }
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 3c2fa2e2f94a3..def09cf0dc147 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -434,7 +434,7 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
+ u32 div, mbrdiv;
+
+ /* Ensure spi->clk_rate is even */
+- div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
++ div = DIV_ROUND_CLOSEST(spi->clk_rate & ~0x1, speed_hz);
+
+ /*
+ * SPI framework set xfer->speed_hz to master->max_speed_hz if
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 904972606bd45..9f356612ba7e5 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -720,6 +720,9 @@ static int tegra_qspi_start_cpu_based_transfer(struct tegra_qspi *qspi, struct s
+
+ static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi)
+ {
++ if (!tqspi->soc_data->has_dma)
++ return;
++
+ if (tqspi->tx_dma_buf) {
+ dma_free_coherent(tqspi->dev, tqspi->dma_buf_size,
+ tqspi->tx_dma_buf, tqspi->tx_dma_phys);
+@@ -750,6 +753,9 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
+ u32 *dma_buf;
+ int err;
+
++ if (!tqspi->soc_data->has_dma)
++ return 0;
++
+ dma_chan = dma_request_chan(tqspi->dev, "rx");
+ if (IS_ERR(dma_chan)) {
+ err = PTR_ERR(dma_chan);
+@@ -918,8 +924,9 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi,
+ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi)
+ {
+ struct tegra_qspi_client_data *cdata;
++ struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master);
+
+- cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL);
++ cdata = devm_kzalloc(tqspi->dev, sizeof(*cdata), GFP_KERNEL);
+ if (!cdata)
+ return NULL;
+
+diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
+index f3947be13e2e5..64f0e047c23d2 100644
+--- a/drivers/tee/optee/device.c
++++ b/drivers/tee/optee/device.c
+@@ -80,7 +80,7 @@ static int optee_register_device(const uuid_t *device_uuid)
+ rc = device_register(&optee_device->dev);
+ if (rc) {
+ pr_err("device registration failed, err: %d\n", rc);
+- kfree(optee_device);
++ put_device(&optee_device->dev);
+ }
+
+ return rc;
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 2a0de70e0be41..ae02aed6bd0c2 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -248,7 +248,7 @@ struct gsm_mux {
+ bool constipated; /* Asked by remote to shut up */
+ bool has_devices; /* Devices were registered */
+
+- struct mutex tx_mutex;
++ spinlock_t tx_lock;
+ unsigned int tx_bytes; /* TX data outstanding */
+ #define TX_THRESH_HI 8192
+ #define TX_THRESH_LO 2048
+@@ -256,7 +256,7 @@ struct gsm_mux {
+ struct list_head tx_data_list; /* Pending data packets */
+
+ /* Control messages */
+- struct delayed_work kick_timeout; /* Kick TX queuing on timeout */
++ struct timer_list kick_timer; /* Kick TX queuing on timeout */
+ struct timer_list t2_timer; /* Retransmit timer for commands */
+ int cretries; /* Command retry counter */
+ struct gsm_control *pending_cmd;/* Our current pending command */
+@@ -680,6 +680,7 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ struct gsm_msg *msg;
+ u8 *dp;
+ int ocr;
++ unsigned long flags;
+
+ msg = gsm_data_alloc(gsm, addr, 0, control);
+ if (!msg)
+@@ -701,10 +702,10 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+
+ gsm_print_packet("Q->", addr, cr, control, NULL, 0);
+
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ list_add_tail(&msg->list, &gsm->tx_ctrl_list);
+ gsm->tx_bytes += msg->len;
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ gsmld_write_trigger(gsm);
+
+ return 0;
+@@ -729,7 +730,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ spin_unlock_irqrestore(&dlci->lock, flags);
+
+ /* Clear data packets in MUX write queue */
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
+ if (msg->addr != addr)
+ continue;
+@@ -737,7 +738,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ list_del(&msg->list);
+ kfree(msg);
+ }
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+
+ /**
+@@ -1008,7 +1009,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ gsm->tx_bytes += msg->len;
+
+ gsmld_write_trigger(gsm);
+- schedule_delayed_work(&gsm->kick_timeout, 10 * gsm->t1 * HZ / 100);
++ mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+
+ /**
+@@ -1023,9 +1024,10 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+
+ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ {
+- mutex_lock(&dlci->gsm->tx_mutex);
++ unsigned long flags;
++ spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ __gsm_data_queue(dlci, msg);
+- mutex_unlock(&dlci->gsm->tx_mutex);
++ spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+
+ /**
+@@ -1037,7 +1039,7 @@ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ * is data. Keep to the MRU of the mux. This path handles the usual tty
+ * interface which is a byte stream with optional modem data.
+ *
+- * Caller must hold the tx_mutex of the mux.
++ * Caller must hold the tx_lock of the mux.
+ */
+
+ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+@@ -1097,7 +1099,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ * is data. Keep to the MRU of the mux. This path handles framed data
+ * queued as skbuffs to the DLCI.
+ *
+- * Caller must hold the tx_mutex of the mux.
++ * Caller must hold the tx_lock of the mux.
+ */
+
+ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+@@ -1113,7 +1115,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+ if (dlci->adaption == 4)
+ overhead = 1;
+
+- /* dlci->skb is locked by tx_mutex */
++ /* dlci->skb is locked by tx_lock */
+ if (dlci->skb == NULL) {
+ dlci->skb = skb_dequeue_tail(&dlci->skb_list);
+ if (dlci->skb == NULL)
+@@ -1167,7 +1169,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+ * Push an empty frame in to the transmit queue to update the modem status
+ * bits and to transmit an optional break.
+ *
+- * Caller must hold the tx_mutex of the mux.
++ * Caller must hold the tx_lock of the mux.
+ */
+
+ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+@@ -1281,12 +1283,13 @@ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+
+ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ {
++ unsigned long flags;
+ int sweep;
+
+ if (dlci->constipated)
+ return;
+
+- mutex_lock(&dlci->gsm->tx_mutex);
++ spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ /* If we have nothing running then we need to fire up */
+ sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO);
+ if (dlci->gsm->tx_bytes == 0) {
+@@ -1297,7 +1300,7 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ }
+ if (sweep)
+ gsm_dlci_data_sweep(dlci->gsm);
+- mutex_unlock(&dlci->gsm->tx_mutex);
++ spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+
+ /*
+@@ -1981,23 +1984,24 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len)
+ }
+
+ /**
+- * gsm_kick_timeout - transmit if possible
+- * @work: work contained in our gsm object
++ * gsm_kick_timer - transmit if possible
++ * @t: timer contained in our gsm object
+ *
+ * Transmit data from DLCIs if the queue is empty. We can't rely on
+ * a tty wakeup except when we filled the pipe so we need to fire off
+ * new data ourselves in other cases.
+ */
+-static void gsm_kick_timeout(struct work_struct *work)
++static void gsm_kick_timer(struct timer_list *t)
+ {
+- struct gsm_mux *gsm = container_of(work, struct gsm_mux, kick_timeout.work);
++ struct gsm_mux *gsm = from_timer(gsm, t, kick_timer);
++ unsigned long flags;
+ int sent = 0;
+
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ /* If we have nothing running then we need to fire up */
+ if (gsm->tx_bytes < TX_THRESH_LO)
+ sent = gsm_dlci_data_sweep(gsm);
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+
+ if (sent && debug & 4)
+ pr_info("%s TX queue stalled\n", __func__);
+@@ -2454,7 +2458,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ }
+
+ /* Finish outstanding timers, making sure they are done */
+- cancel_delayed_work_sync(&gsm->kick_timeout);
++ del_timer_sync(&gsm->kick_timer);
+ del_timer_sync(&gsm->t2_timer);
+
+ /* Finish writing to ldisc */
+@@ -2527,7 +2531,6 @@ static void gsm_free_mux(struct gsm_mux *gsm)
+ break;
+ }
+ }
+- mutex_destroy(&gsm->tx_mutex);
+ mutex_destroy(&gsm->mutex);
+ kfree(gsm->txframe);
+ kfree(gsm->buf);
+@@ -2599,15 +2602,15 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ }
+ spin_lock_init(&gsm->lock);
+ mutex_init(&gsm->mutex);
+- mutex_init(&gsm->tx_mutex);
+ kref_init(&gsm->ref);
+ INIT_LIST_HEAD(&gsm->tx_ctrl_list);
+ INIT_LIST_HEAD(&gsm->tx_data_list);
+- INIT_DELAYED_WORK(&gsm->kick_timeout, gsm_kick_timeout);
++ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+ init_waitqueue_head(&gsm->event);
+ spin_lock_init(&gsm->control_lock);
++ spin_lock_init(&gsm->tx_lock);
+
+ gsm->t1 = T1;
+ gsm->t2 = T2;
+@@ -2632,7 +2635,6 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ }
+ spin_unlock(&gsm_mux_lock);
+ if (i == MAX_MUX) {
+- mutex_destroy(&gsm->tx_mutex);
+ mutex_destroy(&gsm->mutex);
+ kfree(gsm->txframe);
+ kfree(gsm->buf);
+@@ -2788,16 +2790,17 @@ static void gsmld_write_trigger(struct gsm_mux *gsm)
+ static void gsmld_write_task(struct work_struct *work)
+ {
+ struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++ unsigned long flags;
+ int i, ret;
+
+ /* All outstanding control channel and control messages and one data
+ * frame is sent.
+ */
+ ret = -ENODEV;
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ if (gsm->tty)
+ ret = gsm_data_kick(gsm);
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+
+ if (ret >= 0)
+ for (i = 0; i < NUM_DLCI; i++)
+@@ -3005,6 +3008,7 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ const unsigned char *buf, size_t nr)
+ {
+ struct gsm_mux *gsm = tty->disc_data;
++ unsigned long flags;
+ int space;
+ int ret;
+
+@@ -3012,13 +3016,13 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ return -ENODEV;
+
+ ret = -ENOBUFS;
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ space = tty_write_room(tty);
+ if (space >= nr)
+ ret = tty->ops->write(tty, buf, nr);
+ else
+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+
+ return ret;
+ }
+@@ -3315,13 +3319,14 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
+ static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
+ {
+ struct gsm_mux *gsm = dlci->gsm;
++ unsigned long flags;
+
+ if (dlci->state != DLCI_OPEN || dlci->adaption != 2)
+ return;
+
+- mutex_lock(&gsm->tx_mutex);
++ spin_lock_irqsave(&gsm->tx_lock, flags);
+ gsm_dlci_modem_output(gsm, dlci, brk);
+- mutex_unlock(&gsm->tx_mutex);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+
+ /**
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index b96fbf8d31df7..2ad735dd6c05d 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -293,6 +293,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ {
+ struct omap8250_priv *priv = up->port.private_data;
+ struct uart_8250_dma *dma = up->dma;
++ u8 mcr = serial8250_in_MCR(up);
+
+ if (dma && dma->tx_running) {
+ /*
+@@ -309,7 +310,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ serial_out(up, UART_EFR, UART_EFR_ECB);
+
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+- serial8250_out_MCR(up, UART_MCR_TCRTLR);
++ serial8250_out_MCR(up, mcr | UART_MCR_TCRTLR);
+ serial_out(up, UART_FCR, up->fcr);
+
+ omap8250_update_scr(up, priv);
+@@ -325,7 +326,8 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ serial_out(up, UART_LCR, 0);
+
+ /* drop TCR + TLR access, we setup XON/XOFF later */
+- serial8250_out_MCR(up, up->mcr);
++ serial8250_out_MCR(up, mcr);
++
+ serial_out(up, UART_IER, up->ier);
+
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+@@ -670,7 +672,6 @@ static int omap_8250_startup(struct uart_port *port)
+
+ pm_runtime_get_sync(port->dev);
+
+- up->mcr = 0;
+ serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+
+ serial_out(up, UART_LCR, UART_LCR_WLEN8);
+diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
+index c67715f6f756d..f9aa50ff14d42 100644
+--- a/drivers/usb/cdns3/cdnsp-gadget.c
++++ b/drivers/usb/cdns3/cdnsp-gadget.c
+@@ -600,11 +600,11 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+
+ trace_cdnsp_ep_halt(value ? "Set" : "Clear");
+
+- if (value) {
+- ret = cdnsp_cmd_stop_ep(pdev, pep);
+- if (ret)
+- return ret;
++ ret = cdnsp_cmd_stop_ep(pdev, pep);
++ if (ret)
++ return ret;
+
++ if (value) {
+ if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
+ cdnsp_queue_halt_endpoint(pdev, pep->idx);
+ cdnsp_ring_cmd_db(pdev);
+@@ -613,10 +613,6 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+
+ pep->ep_state |= EP_HALTED;
+ } else {
+- /*
+- * In device mode driver can call reset endpoint command
+- * from any endpoint state.
+- */
+ cdnsp_queue_reset_ep(pdev, pep->idx);
+ cdnsp_ring_cmd_db(pdev);
+ ret = cdnsp_wait_for_cmd_compl(pdev);
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 794e413800ae8..2f29431f612e0 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -1763,10 +1763,15 @@ static u32 cdnsp_td_remainder(struct cdnsp_device *pdev,
+ int trb_buff_len,
+ unsigned int td_total_len,
+ struct cdnsp_request *preq,
+- bool more_trbs_coming)
++ bool more_trbs_coming,
++ bool zlp)
+ {
+ u32 maxp, total_packet_count;
+
++ /* Before ZLP driver needs set TD_SIZE = 1. */
++ if (zlp)
++ return 1;
++
+ /* One TRB with a zero-length data packet. */
+ if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
+ trb_buff_len == td_total_len)
+@@ -1960,7 +1965,8 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ /* Set the TRB length, TD size, and interrupter fields. */
+ remainder = cdnsp_td_remainder(pdev, enqd_len, trb_buff_len,
+ full_len, preq,
+- more_trbs_coming);
++ more_trbs_coming,
++ zero_len_trb);
+
+ length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
+ TRB_INTR_TARGET(0);
+@@ -2025,7 +2031,7 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+
+ if (preq->request.length > 0) {
+ remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
+- preq->request.length, preq, 1);
++ preq->request.length, preq, 1, 0);
+
+ length_field = TRB_LEN(preq->request.length) |
+ TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
+@@ -2076,7 +2082,8 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
+ u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx);
+ int ret = 0;
+
+- if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) {
++ if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED ||
++ ep_state == EP_STATE_HALTED) {
+ trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx);
+ goto ep_stopped;
+ }
+@@ -2225,7 +2232,7 @@ static int cdnsp_queue_isoc_tx(struct cdnsp_device *pdev,
+ /* Set the TRB length, TD size, & interrupter fields. */
+ remainder = cdnsp_td_remainder(pdev, running_total,
+ trb_buff_len, td_len, preq,
+- more_trbs_coming);
++ more_trbs_coming, 0);
+
+ length_field = TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0);
+
+diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
+index 0ecf20eeceee9..4be6a873bd071 100644
+--- a/drivers/usb/dwc3/dwc3-exynos.c
++++ b/drivers/usb/dwc3/dwc3-exynos.c
+@@ -37,15 +37,6 @@ struct dwc3_exynos {
+ struct regulator *vdd10;
+ };
+
+-static int dwc3_exynos_remove_child(struct device *dev, void *unused)
+-{
+- struct platform_device *pdev = to_platform_device(dev);
+-
+- platform_device_unregister(pdev);
+-
+- return 0;
+-}
+-
+ static int dwc3_exynos_probe(struct platform_device *pdev)
+ {
+ struct dwc3_exynos *exynos;
+@@ -142,7 +133,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
+ struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
+ int i;
+
+- device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
++ of_platform_depopulate(&pdev->dev);
+
+ for (i = exynos->num_clks - 1; i >= 0; i--)
+ clk_disable_unprepare(exynos->clks[i]);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 0ed9826a4c470..6f61a288073bb 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -965,7 +965,7 @@ out:
+ return 0;
+ }
+
+-static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
++static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status)
+ {
+ struct dwc3_request *req;
+
+@@ -975,19 +975,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
+ while (!list_empty(&dep->started_list)) {
+ req = next_request(&dep->started_list);
+
+- dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++ dwc3_gadget_giveback(dep, req, status);
+ }
+
+ while (!list_empty(&dep->pending_list)) {
+ req = next_request(&dep->pending_list);
+
+- dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++ dwc3_gadget_giveback(dep, req, status);
+ }
+
+ while (!list_empty(&dep->cancelled_list)) {
+ req = next_request(&dep->cancelled_list);
+
+- dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++ dwc3_gadget_giveback(dep, req, status);
+ }
+ }
+
+@@ -1016,18 +1016,18 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
+ reg &= ~DWC3_DALEPENA_EP(dep->number);
+ dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+
++ dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
++
++ dep->stream_capable = false;
++ dep->type = 0;
++ dep->flags &= DWC3_EP_TXFIFO_RESIZED;
++
+ /* Clear out the ep descriptors for non-ep0 */
+ if (dep->number > 1) {
+ dep->endpoint.comp_desc = NULL;
+ dep->endpoint.desc = NULL;
+ }
+
+- dwc3_remove_requests(dwc, dep);
+-
+- dep->stream_capable = false;
+- dep->type = 0;
+- dep->flags &= DWC3_EP_TXFIFO_RESIZED;
+-
+ return 0;
+ }
+
+@@ -2350,7 +2350,7 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
+ if (!dep)
+ continue;
+
+- dwc3_remove_requests(dwc, dep);
++ dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
+ }
+ }
+
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index f422f9c58ba79..1ea6d2e5b2187 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -67,8 +67,27 @@ static bool is_vmpck_empty(struct snp_guest_dev *snp_dev)
+ return true;
+ }
+
++/*
++ * If an error is received from the host or AMD Secure Processor (ASP) there
++ * are two options. Either retry the exact same encrypted request or discontinue
++ * using the VMPCK.
++ *
++ * This is because in the current encryption scheme GHCB v2 uses AES-GCM to
++ * encrypt the requests. The IV for this scheme is the sequence number. GCM
++ * cannot tolerate IV reuse.
++ *
++ * The ASP FW v1.51 only increments the sequence numbers on a successful
++ * guest<->ASP back and forth and only accepts messages at its exact sequence
++ * number.
++ *
++ * So if the sequence number were to be reused the encryption scheme is
++ * vulnerable. If the sequence number were incremented for a fresh IV the ASP
++ * will reject the request.
++ */
+ static void snp_disable_vmpck(struct snp_guest_dev *snp_dev)
+ {
++ dev_alert(snp_dev->dev, "Disabling vmpck_id %d to prevent IV reuse.\n",
++ vmpck_id);
+ memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN);
+ snp_dev->vmpck = NULL;
+ }
+@@ -321,34 +340,71 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
+ if (rc)
+ return rc;
+
+- /* Call firmware to process the request */
++ /*
++ * Call firmware to process the request. In this function the encrypted
++ * message enters shared memory with the host. So after this call the
++ * sequence number must be incremented or the VMPCK must be deleted to
++ * prevent reuse of the IV.
++ */
+ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++ /*
++ * If the extended guest request fails due to having too small of a
++ * certificate data buffer, retry the same guest request without the
++ * extended data request in order to increment the sequence number
++ * and thus avoid IV reuse.
++ */
++ if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
++ err == SNP_GUEST_REQ_INVALID_LEN) {
++ const unsigned int certs_npages = snp_dev->input.data_npages;
++
++ exit_code = SVM_VMGEXIT_GUEST_REQUEST;
++
++ /*
++ * If this call to the firmware succeeds, the sequence number can
++ * be incremented allowing for continued use of the VMPCK. If
++ * there is an error reflected in the return value, this value
++ * is checked further down and the result will be the deletion
++ * of the VMPCK and the error code being propagated back to the
++ * user as an ioctl() return code.
++ */
++ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++ /*
++ * Override the error to inform callers the given extended
++ * request buffer size was too small and give the caller the
++ * required buffer size.
++ */
++ err = SNP_GUEST_REQ_INVALID_LEN;
++ snp_dev->input.data_npages = certs_npages;
++ }
++
+ if (fw_err)
+ *fw_err = err;
+
+- if (rc)
+- return rc;
++ if (rc) {
++ dev_alert(snp_dev->dev,
++ "Detected error from ASP request. rc: %d, fw_err: %llu\n",
++ rc, *fw_err);
++ goto disable_vmpck;
++ }
+
+- /*
+- * The verify_and_dec_payload() will fail only if the hypervisor is
+- * actively modifying the message header or corrupting the encrypted payload.
+- * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that
+- * the key cannot be used for any communication. The key is disabled to ensure
+- * that AES-GCM does not use the same IV while encrypting the request payload.
+- */
+ rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz);
+ if (rc) {
+ dev_alert(snp_dev->dev,
+- "Detected unexpected decode failure, disabling the vmpck_id %d\n",
+- vmpck_id);
+- snp_disable_vmpck(snp_dev);
+- return rc;
++ "Detected unexpected decode failure from ASP. rc: %d\n",
++ rc);
++ goto disable_vmpck;
+ }
+
+ /* Increment to new message sequence after payload decryption was successful. */
+ snp_inc_msg_seqno(snp_dev);
+
+ return 0;
++
++disable_vmpck:
++ snp_disable_vmpck(snp_dev);
++ return rc;
+ }
+
+ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index 18f0ed8b1f93b..6ebd819338ecb 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -144,7 +144,7 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ if (ret) {
+ dev_warn(&pdev->dev, "Unable to set the evtchn callback "
+ "err=%d\n", ret);
+- goto out;
++ goto irq_out;
+ }
+ }
+
+@@ -152,13 +152,16 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+ ret = gnttab_setup_auto_xlat_frames(grant_frames);
+ if (ret)
+- goto out;
++ goto irq_out;
+ ret = gnttab_init();
+ if (ret)
+ goto grant_out;
+ return 0;
+ grant_out:
+ gnttab_free_auto_xlat_frames();
++irq_out:
++ if (!xen_have_vector_callback)
++ free_irq(pdev->irq, pdev);
+ out:
+ pci_release_region(pdev, 0);
+ mem_out:
+diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
+index 5e53b4817f167..097316a741268 100644
+--- a/drivers/xen/xen-pciback/conf_space_capability.c
++++ b/drivers/xen/xen-pciback/conf_space_capability.c
+@@ -190,13 +190,16 @@ static const struct config_field caplist_pm[] = {
+ };
+
+ static struct msi_msix_field_config {
+- u16 enable_bit; /* bit for enabling MSI/MSI-X */
+- unsigned int int_type; /* interrupt type for exclusiveness check */
++ u16 enable_bit; /* bit for enabling MSI/MSI-X */
++ u16 allowed_bits; /* bits allowed to be changed */
++ unsigned int int_type; /* interrupt type for exclusiveness check */
+ } msi_field_config = {
+ .enable_bit = PCI_MSI_FLAGS_ENABLE,
++ .allowed_bits = PCI_MSI_FLAGS_ENABLE,
+ .int_type = INTERRUPT_TYPE_MSI,
+ }, msix_field_config = {
+ .enable_bit = PCI_MSIX_FLAGS_ENABLE,
++ .allowed_bits = PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL,
+ .int_type = INTERRUPT_TYPE_MSIX,
+ };
+
+@@ -229,7 +232,7 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+ return 0;
+
+ if (!dev_data->allow_interrupt_control ||
+- (new_value ^ old_value) & ~field_config->enable_bit)
++ (new_value ^ old_value) & ~field_config->allowed_bits)
+ return PCIBIOS_SET_FAILED;
+
+ if (new_value & field_config->enable_bit) {
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index fe0cc816b4eba..4fff0067bd2a9 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3105,6 +3105,8 @@ static int btrfs_ioctl_get_subvol_info(struct inode *inode, void __user *argp)
+ }
+ }
+
++ btrfs_free_path(path);
++ path = NULL;
+ if (copy_to_user(argp, subvol_info, sizeof(*subvol_info)))
+ ret = -EFAULT;
+
+@@ -3194,6 +3196,8 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
+ }
+
+ out:
++ btrfs_free_path(path);
++
+ if (!ret || ret == -EOVERFLOW) {
+ rootrefs->num_items = found;
+ /* update min_treeid for next search */
+@@ -3205,7 +3209,6 @@ out:
+ }
+
+ kfree(rootrefs);
+- btrfs_free_path(path);
+
+ return ret;
+ }
+@@ -4231,6 +4234,8 @@ static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
+ ipath->fspath->val[i] = rel_ptr;
+ }
+
++ btrfs_free_path(path);
++ path = NULL;
+ ret = copy_to_user((void __user *)(unsigned long)ipa->fspath,
+ ipath->fspath, size);
+ if (ret) {
+@@ -4281,21 +4286,20 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ size = min_t(u32, loi->size, SZ_16M);
+ }
+
+- path = btrfs_alloc_path();
+- if (!path) {
+- ret = -ENOMEM;
+- goto out;
+- }
+-
+ inodes = init_data_container(size);
+ if (IS_ERR(inodes)) {
+ ret = PTR_ERR(inodes);
+- inodes = NULL;
+- goto out;
++ goto out_loi;
+ }
+
++ path = btrfs_alloc_path();
++ if (!path) {
++ ret = -ENOMEM;
++ goto out;
++ }
+ ret = iterate_inodes_from_logical(loi->logical, fs_info, path,
+ inodes, ignore_offset);
++ btrfs_free_path(path);
+ if (ret == -EINVAL)
+ ret = -ENOENT;
+ if (ret < 0)
+@@ -4307,7 +4311,6 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ ret = -EFAULT;
+
+ out:
+- btrfs_free_path(path);
+ kvfree(inodes);
+ out_loi:
+ kfree(loi);
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index d5d0717fd09a3..00b97e6eb5078 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -2251,8 +2251,11 @@ int __init btrfs_init_sysfs(void)
+
+ #ifdef CONFIG_BTRFS_DEBUG
+ ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_debug_feature_attr_group);
+- if (ret)
+- goto out2;
++ if (ret) {
++ sysfs_unmerge_group(&btrfs_kset->kobj,
++ &btrfs_static_feature_attr_group);
++ goto out_remove_group;
++ }
+ #endif
+
+ return 0;
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 9205c4a5ca81d..11f70ba981407 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3834,15 +3834,29 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
+ u64 *last_old_dentry_offset)
+ {
+ struct btrfs_root *log = inode->root->log_root;
+- struct extent_buffer *src = path->nodes[0];
+- const int nritems = btrfs_header_nritems(src);
++ struct extent_buffer *src;
++ const int nritems = btrfs_header_nritems(path->nodes[0]);
+ const u64 ino = btrfs_ino(inode);
+ bool last_found = false;
+ int batch_start = 0;
+ int batch_size = 0;
+ int i;
+
+- for (i = path->slots[0]; i < nritems; i++) {
++ /*
++ * We need to clone the leaf, release the read lock on it, and use the
++ * clone before modifying the log tree. See the comment at copy_items()
++ * about why we need to do this.
++ */
++ src = btrfs_clone_extent_buffer(path->nodes[0]);
++ if (!src)
++ return -ENOMEM;
++
++ i = path->slots[0];
++ btrfs_release_path(path);
++ path->nodes[0] = src;
++ path->slots[0] = i;
++
++ for (; i < nritems; i++) {
+ struct btrfs_dir_item *di;
+ struct btrfs_key key;
+ int ret;
+@@ -4414,7 +4428,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ {
+ struct btrfs_root *log = inode->root->log_root;
+ struct btrfs_file_extent_item *extent;
+- struct extent_buffer *src = src_path->nodes[0];
++ struct extent_buffer *src;
+ int ret = 0;
+ struct btrfs_key *ins_keys;
+ u32 *ins_sizes;
+@@ -4425,6 +4439,43 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM);
+ const u64 i_size = i_size_read(&inode->vfs_inode);
+
++ /*
++ * To keep lockdep happy and avoid deadlocks, clone the source leaf and
++ * use the clone. This is because otherwise we would be changing the log
++ * tree, to insert items from the subvolume tree or insert csum items,
++ * while holding a read lock on a leaf from the subvolume tree, which
++ * creates a nasty lock dependency when COWing log tree nodes/leaves:
++ *
++ * 1) Modifying the log tree triggers an extent buffer allocation while
++ * holding a write lock on a parent extent buffer from the log tree.
++ * Allocating the pages for an extent buffer, or the extent buffer
++ * struct, can trigger inode eviction and finally the inode eviction
++ * will trigger a release/remove of a delayed node, which requires
++ * taking the delayed node's mutex;
++ *
++ * 2) Allocating a metadata extent for a log tree can trigger the async
++ * reclaim thread and make us wait for it to release enough space and
++ * unblock our reservation ticket. The reclaim thread can start
++ * flushing delayed items, and that in turn results in the need to
++ * lock delayed node mutexes and in the need to write lock extent
++ * buffers of a subvolume tree - all this while holding a write lock
++ * on the parent extent buffer in the log tree.
++ *
++ * So one task in scenario 1) running in parallel with another task in
++ * scenario 2) could lead to a deadlock, one wanting to lock a delayed
++ * node mutex while having a read lock on a leaf from the subvolume,
++ * while the other is holding the delayed node's mutex and wants to
++ * write lock the same subvolume leaf for flushing delayed items.
++ */
++ src = btrfs_clone_extent_buffer(src_path->nodes[0]);
++ if (!src)
++ return -ENOMEM;
++
++ i = src_path->slots[0];
++ btrfs_release_path(src_path);
++ src_path->nodes[0] = src;
++ src_path->slots[0] = i;
++
+ ins_data = kmalloc(nr * sizeof(struct btrfs_key) +
+ nr * sizeof(u32), GFP_NOFS);
+ if (!ins_data)
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index a227d27a63bfd..9ea40ddcc4251 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -134,7 +134,8 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
+ super[i] = page_address(page[i]);
+ }
+
+- if (super[0]->generation > super[1]->generation)
++ if (btrfs_super_generation(super[0]) >
++ btrfs_super_generation(super[1]))
+ sector = zones[1].start;
+ else
+ sector = zones[0].start;
+@@ -466,7 +467,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ goto out;
+ }
+
+- zones = kcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
++ zones = kvcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
+ if (!zones) {
+ ret = -ENOMEM;
+ goto out;
+@@ -585,7 +586,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ }
+
+
+- kfree(zones);
++ kvfree(zones);
+
+ switch (bdev_zoned_model(bdev)) {
+ case BLK_ZONED_HM:
+@@ -617,7 +618,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ return 0;
+
+ out:
+- kfree(zones);
++ kvfree(zones);
+ out_free_zone_info:
+ btrfs_destroy_dev_zone_info(device);
+
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 53cfe026b3ea5..02b5c0ac56547 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2247,7 +2247,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_mds_request *req1 = NULL, *req2 = NULL;
+- unsigned int max_sessions;
+ int ret, err = 0;
+
+ spin_lock(&ci->i_unsafe_lock);
+@@ -2265,28 +2264,24 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ }
+ spin_unlock(&ci->i_unsafe_lock);
+
+- /*
+- * The mdsc->max_sessions is unlikely to be changed
+- * mostly, here we will retry it by reallocating the
+- * sessions array memory to get rid of the mdsc->mutex
+- * lock.
+- */
+-retry:
+- max_sessions = mdsc->max_sessions;
+-
+ /*
+ * Trigger to flush the journal logs in all the relevant MDSes
+ * manually, or in the worst case we must wait at most 5 seconds
+ * to wait the journal logs to be flushed by the MDSes periodically.
+ */
+- if ((req1 || req2) && likely(max_sessions)) {
+- struct ceph_mds_session **sessions = NULL;
+- struct ceph_mds_session *s;
++ if (req1 || req2) {
+ struct ceph_mds_request *req;
++ struct ceph_mds_session **sessions;
++ struct ceph_mds_session *s;
++ unsigned int max_sessions;
+ int i;
+
+- sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL);
++ mutex_lock(&mdsc->mutex);
++ max_sessions = mdsc->max_sessions;
++
++ sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL);
+ if (!sessions) {
++ mutex_unlock(&mdsc->mutex);
+ err = -ENOMEM;
+ goto out;
+ }
+@@ -2298,16 +2293,6 @@ retry:
+ s = req->r_session;
+ if (!s)
+ continue;
+- if (unlikely(s->s_mds >= max_sessions)) {
+- spin_unlock(&ci->i_unsafe_lock);
+- for (i = 0; i < max_sessions; i++) {
+- s = sessions[i];
+- if (s)
+- ceph_put_mds_session(s);
+- }
+- kfree(sessions);
+- goto retry;
+- }
+ if (!sessions[s->s_mds]) {
+ s = ceph_get_mds_session(s);
+ sessions[s->s_mds] = s;
+@@ -2320,16 +2305,6 @@ retry:
+ s = req->r_session;
+ if (!s)
+ continue;
+- if (unlikely(s->s_mds >= max_sessions)) {
+- spin_unlock(&ci->i_unsafe_lock);
+- for (i = 0; i < max_sessions; i++) {
+- s = sessions[i];
+- if (s)
+- ceph_put_mds_session(s);
+- }
+- kfree(sessions);
+- goto retry;
+- }
+ if (!sessions[s->s_mds]) {
+ s = ceph_get_mds_session(s);
+ sessions[s->s_mds] = s;
+@@ -2341,11 +2316,12 @@ retry:
+ /* the auth MDS */
+ spin_lock(&ci->i_ceph_lock);
+ if (ci->i_auth_cap) {
+- s = ci->i_auth_cap->session;
+- if (!sessions[s->s_mds])
+- sessions[s->s_mds] = ceph_get_mds_session(s);
++ s = ci->i_auth_cap->session;
++ if (!sessions[s->s_mds])
++ sessions[s->s_mds] = ceph_get_mds_session(s);
+ }
+ spin_unlock(&ci->i_ceph_lock);
++ mutex_unlock(&mdsc->mutex);
+
+ /* send flush mdlog request to MDSes */
+ for (i = 0; i < max_sessions; i++) {
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 6bc8be9ed2a56..ccad85feb24e8 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1252,7 +1252,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ rc = filemap_write_and_wait_range(src_inode->i_mapping, off,
+ off + len - 1);
+ if (rc)
+- goto out;
++ goto unlock;
+
+ /* should we flush first and last page first */
+ truncate_inode_pages(&target_inode->i_data, 0);
+@@ -1268,6 +1268,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ * that target is updated on the server
+ */
+ CIFS_I(target_inode)->time = 0;
++
++unlock:
+ /* although unlocking in the reverse order from locking is not
+ * strictly necessary here it is a little cleaner to be consistent
+ */
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 11cd06aa74f0a..6a85136da27ce 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -302,14 +302,14 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
+
+ /* now drop the ref to the current iface */
+ if (old_iface && iface) {
+- kref_put(&old_iface->refcount, release_iface);
+ cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n",
+ &old_iface->sockaddr,
+ &iface->sockaddr);
+- } else if (old_iface) {
+ kref_put(&old_iface->refcount, release_iface);
++ } else if (old_iface) {
+ cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
+ &old_iface->sockaddr);
++ kref_put(&old_iface->refcount, release_iface);
+ } else {
+ WARN_ON(!iface);
+ cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 5235974126bd3..8378b86c1b496 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5183,6 +5183,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ * and it is decreased till we reach start.
+ */
+ again:
++ ret = 0;
+ if (SHIFT == SHIFT_LEFT)
+ iterator = &start;
+ else
+@@ -5226,14 +5227,21 @@ again:
+ ext4_ext_get_actual_len(extent);
+ } else {
+ extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+- if (le32_to_cpu(extent->ee_block) > 0)
++ if (le32_to_cpu(extent->ee_block) > start)
+ *iterator = le32_to_cpu(extent->ee_block) - 1;
+- else
+- /* Beginning is reached, end of the loop */
++ else if (le32_to_cpu(extent->ee_block) == start)
+ iterator = NULL;
+- /* Update path extent in case we need to stop */
+- while (le32_to_cpu(extent->ee_block) < start)
++ else {
++ extent = EXT_LAST_EXTENT(path[depth].p_hdr);
++ while (le32_to_cpu(extent->ee_block) >= start)
++ extent--;
++
++ if (extent == EXT_LAST_EXTENT(path[depth].p_hdr))
++ break;
++
+ extent++;
++ iterator = NULL;
++ }
+ path[depth].p_ext = extent;
+ }
+ ret = ext4_ext_shift_path_extents(path, shift, inode,
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 443f83382b9bd..9958d40207712 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1712,18 +1712,26 @@ static int writeback_single_inode(struct inode *inode,
+ wb = inode_to_wb_and_lock_list(inode);
+ spin_lock(&inode->i_lock);
+ /*
+- * If the inode is now fully clean, then it can be safely removed from
+- * its writeback list (if any). Otherwise the flusher threads are
+- * responsible for the writeback lists.
++ * If the inode is freeing, its i_io_list shoudn't be updated
++ * as it can be finally deleted at this moment.
+ */
+- if (!(inode->i_state & I_DIRTY_ALL))
+- inode_cgwb_move_to_attached(inode, wb);
+- else if (!(inode->i_state & I_SYNC_QUEUED)) {
+- if ((inode->i_state & I_DIRTY))
+- redirty_tail_locked(inode, wb);
+- else if (inode->i_state & I_DIRTY_TIME) {
+- inode->dirtied_when = jiffies;
+- inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++ if (!(inode->i_state & I_FREEING)) {
++ /*
++ * If the inode is now fully clean, then it can be safely
++ * removed from its writeback list (if any). Otherwise the
++ * flusher threads are responsible for the writeback lists.
++ */
++ if (!(inode->i_state & I_DIRTY_ALL))
++ inode_cgwb_move_to_attached(inode, wb);
++ else if (!(inode->i_state & I_SYNC_QUEUED)) {
++ if ((inode->i_state & I_DIRTY))
++ redirty_tail_locked(inode, wb);
++ else if (inode->i_state & I_DIRTY_TIME) {
++ inode->dirtied_when = jiffies;
++ inode_io_list_move_locked(inode,
++ wb,
++ &wb->b_dirty_time);
++ }
+ }
+ }
+
+diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
+index a058e0136bfeb..ab8ceddf9efad 100644
+--- a/fs/fscache/volume.c
++++ b/fs/fscache/volume.c
+@@ -203,7 +203,11 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ struct fscache_volume *volume;
+ struct fscache_cache *cache;
+ size_t klen, hlen;
+- char *key;
++ u8 *key;
++
++ klen = strlen(volume_key);
++ if (klen > NAME_MAX)
++ return NULL;
+
+ if (!coherency_data)
+ coherency_len = 0;
+@@ -229,7 +233,6 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ /* Stick the length on the front of the key and pad it out to make
+ * hashing easier.
+ */
+- klen = strlen(volume_key);
+ hlen = round_up(1 + klen + 1, sizeof(__le32));
+ key = kzalloc(hlen, GFP_KERNEL);
+ if (!key)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 71bfb663aac58..89f4741728ba3 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -2963,11 +2963,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ .mode = mode
+ };
+ int err;
+- bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
+- (mode & (FALLOC_FL_PUNCH_HOLE |
+- FALLOC_FL_ZERO_RANGE));
+-
+- bool block_faults = FUSE_IS_DAX(inode) && lock_inode;
++ bool block_faults = FUSE_IS_DAX(inode) &&
++ (!(mode & FALLOC_FL_KEEP_SIZE) ||
++ (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)));
+
+ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+ FALLOC_FL_ZERO_RANGE))
+@@ -2976,22 +2974,20 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ if (fm->fc->no_fallocate)
+ return -EOPNOTSUPP;
+
+- if (lock_inode) {
+- inode_lock(inode);
+- if (block_faults) {
+- filemap_invalidate_lock(inode->i_mapping);
+- err = fuse_dax_break_layouts(inode, 0, 0);
+- if (err)
+- goto out;
+- }
++ inode_lock(inode);
++ if (block_faults) {
++ filemap_invalidate_lock(inode->i_mapping);
++ err = fuse_dax_break_layouts(inode, 0, 0);
++ if (err)
++ goto out;
++ }
+
+- if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
+- loff_t endbyte = offset + length - 1;
++ if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
++ loff_t endbyte = offset + length - 1;
+
+- err = fuse_writeback_range(inode, offset, endbyte);
+- if (err)
+- goto out;
+- }
++ err = fuse_writeback_range(inode, offset, endbyte);
++ if (err)
++ goto out;
+ }
+
+ if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+@@ -3039,8 +3035,7 @@ out:
+ if (block_faults)
+ filemap_invalidate_unlock(inode->i_mapping);
+
+- if (lock_inode)
+- inode_unlock(inode);
++ inode_unlock(inode);
+
+ fuse_flush_time_update(inode);
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index fc17b0ac87297..f3cd614e1f1e9 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -847,10 +847,11 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ struct svc_rqst *rqstp = sd->u.data;
+ struct page *page = buf->page; // may be a compound one
+ unsigned offset = buf->offset;
++ struct page *last_page;
+
+- page += offset / PAGE_SIZE;
+- for (int i = sd->len; i > 0; i -= PAGE_SIZE)
+- svc_rqst_replace_page(rqstp, page++);
++ last_page = page + (offset + sd->len - 1) / PAGE_SIZE;
++ for (page += offset / PAGE_SIZE; page <= last_page; page++)
++ svc_rqst_replace_page(rqstp, page);
+ if (rqstp->rq_res.page_len == 0) // first call
+ rqstp->rq_res.page_base = offset % PAGE_SIZE;
+ rqstp->rq_res.page_len += sd->len;
+diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
+index 77ff8e95421fa..dc359b56fdfac 100644
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -495,14 +495,22 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
+ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
+ {
+ struct buffer_head *bh;
++ void *kaddr;
++ struct nilfs_segment_usage *su;
+ int ret;
+
++ down_write(&NILFS_MDT(sufile)->mi_sem);
+ ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+ if (!ret) {
+ mark_buffer_dirty(bh);
+ nilfs_mdt_mark_dirty(sufile);
++ kaddr = kmap_atomic(bh->b_page);
++ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
++ nilfs_segment_usage_set_dirty(su);
++ kunmap_atomic(kaddr);
+ brelse(bh);
+ }
++ up_write(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+ }
+
+diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
+index 860f0b1032c65..2c53fbb8d918e 100644
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -40,6 +40,13 @@ static void zonefs_account_active(struct inode *inode)
+ if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+ return;
+
++ /*
++ * For zones that transitioned to the offline or readonly condition,
++ * we only need to clear the active state.
++ */
++ if (zi->i_flags & (ZONEFS_ZONE_OFFLINE | ZONEFS_ZONE_READONLY))
++ goto out;
++
+ /*
+ * If the zone is active, that is, if it is explicitly open or
+ * partially written, check if it was already accounted as active.
+@@ -53,6 +60,7 @@ static void zonefs_account_active(struct inode *inode)
+ return;
+ }
+
++out:
+ /* The zone is not active. If it was, update the active count */
+ if (zi->i_flags & ZONEFS_ZONE_ACTIVE) {
+ zi->i_flags &= ~ZONEFS_ZONE_ACTIVE;
+@@ -324,6 +332,7 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ inode->i_flags |= S_IMMUTABLE;
+ inode->i_mode &= ~0777;
+ zone->wp = zone->start;
++ zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ return 0;
+ case BLK_ZONE_COND_READONLY:
+ /*
+@@ -342,8 +351,10 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ zone->cond = BLK_ZONE_COND_OFFLINE;
+ inode->i_mode &= ~0777;
+ zone->wp = zone->start;
++ zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ return 0;
+ }
++ zi->i_flags |= ZONEFS_ZONE_READONLY;
+ inode->i_mode &= ~0222;
+ return i_size_read(inode);
+ case BLK_ZONE_COND_FULL:
+@@ -478,14 +489,22 @@ static void __zonefs_io_error(struct inode *inode, bool write)
+ struct super_block *sb = inode->i_sb;
+ struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
+ unsigned int noio_flag;
+- unsigned int nr_zones =
+- zi->i_zone_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++ unsigned int nr_zones = 1;
+ struct zonefs_ioerr_data err = {
+ .inode = inode,
+ .write = write,
+ };
+ int ret;
+
++ /*
++ * The only files that have more than one zone are conventional zone
++ * files with aggregated conventional zones, for which the inode zone
++ * size is always larger than the device zone size.
++ */
++ if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev))
++ nr_zones = zi->i_zone_size >>
++ (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++
+ /*
+ * Memory allocations in blkdev_report_zones() can trigger a memory
+ * reclaim which may in turn cause a recursion into zonefs as well as
+@@ -1407,6 +1426,14 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
+ zi->i_ztype = type;
+ zi->i_zsector = zone->start;
+ zi->i_zone_size = zone->len << SECTOR_SHIFT;
++ if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT &&
++ !(sbi->s_features & ZONEFS_F_AGGRCNV)) {
++ zonefs_err(sb,
++ "zone size %llu doesn't match device's zone sectors %llu\n",
++ zi->i_zone_size,
++ bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT);
++ return -EINVAL;
++ }
+
+ zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
+ zone->capacity << SECTOR_SHIFT);
+@@ -1456,11 +1483,11 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ struct inode *dir = d_inode(parent);
+ struct dentry *dentry;
+ struct inode *inode;
+- int ret;
++ int ret = -ENOMEM;
+
+ dentry = d_alloc_name(parent, name);
+ if (!dentry)
+- return NULL;
++ return ERR_PTR(ret);
+
+ inode = new_inode(parent->d_sb);
+ if (!inode)
+@@ -1485,7 +1512,7 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ dput:
+ dput(dentry);
+
+- return NULL;
++ return ERR_PTR(ret);
+ }
+
+ struct zonefs_zone_data {
+@@ -1505,7 +1532,7 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ struct blk_zone *zone, *next, *end;
+ const char *zgroup_name;
+ char *file_name;
+- struct dentry *dir;
++ struct dentry *dir, *dent;
+ unsigned int n = 0;
+ int ret;
+
+@@ -1523,8 +1550,8 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ zgroup_name = "seq";
+
+ dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type);
+- if (!dir) {
+- ret = -ENOMEM;
++ if (IS_ERR(dir)) {
++ ret = PTR_ERR(dir);
+ goto free;
+ }
+
+@@ -1570,8 +1597,9 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ * Use the file number within its group as file name.
+ */
+ snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n);
+- if (!zonefs_create_inode(dir, file_name, zone, type)) {
+- ret = -ENOMEM;
++ dent = zonefs_create_inode(dir, file_name, zone, type);
++ if (IS_ERR(dent)) {
++ ret = PTR_ERR(dent);
+ goto free;
+ }
+
+@@ -1905,18 +1933,18 @@ static int __init zonefs_init(void)
+ if (ret)
+ return ret;
+
+- ret = register_filesystem(&zonefs_type);
++ ret = zonefs_sysfs_init();
+ if (ret)
+ goto destroy_inodecache;
+
+- ret = zonefs_sysfs_init();
++ ret = register_filesystem(&zonefs_type);
+ if (ret)
+- goto unregister_fs;
++ goto sysfs_exit;
+
+ return 0;
+
+-unregister_fs:
+- unregister_filesystem(&zonefs_type);
++sysfs_exit:
++ zonefs_sysfs_exit();
+ destroy_inodecache:
+ zonefs_destroy_inodecache();
+
+@@ -1925,9 +1953,9 @@ destroy_inodecache:
+
+ static void __exit zonefs_exit(void)
+ {
++ unregister_filesystem(&zonefs_type);
+ zonefs_sysfs_exit();
+ zonefs_destroy_inodecache();
+- unregister_filesystem(&zonefs_type);
+ }
+
+ MODULE_AUTHOR("Damien Le Moal");
+diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
+index 4b3de66c32334..1dbe78119ff16 100644
+--- a/fs/zonefs/zonefs.h
++++ b/fs/zonefs/zonefs.h
+@@ -39,8 +39,10 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
+ return ZONEFS_ZTYPE_SEQ;
+ }
+
+-#define ZONEFS_ZONE_OPEN (1 << 0)
+-#define ZONEFS_ZONE_ACTIVE (1 << 1)
++#define ZONEFS_ZONE_OPEN (1U << 0)
++#define ZONEFS_ZONE_ACTIVE (1U << 1)
++#define ZONEFS_ZONE_OFFLINE (1U << 2)
++#define ZONEFS_ZONE_READONLY (1U << 3)
+
+ /*
+ * In-memory inode data.
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 79624711fda7c..e6bf06dc07704 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -946,7 +946,6 @@ extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+ extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);
+ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+ extern void blk_set_queue_depth(struct request_queue *q, unsigned int depth);
+-extern void blk_set_default_limits(struct queue_limits *lim);
+ extern void blk_set_stacking_limits(struct queue_limits *lim);
+ extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset);
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 73662fbabd78f..e811e2f99a617 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -27,6 +27,7 @@
+ #include <linux/bpfptr.h>
+ #include <linux/btf.h>
+ #include <linux/rcupdate_trace.h>
++#include <linux/static_call.h>
+
+ struct bpf_verifier_env;
+ struct bpf_verifier_log;
+@@ -894,6 +895,10 @@ struct bpf_dispatcher {
+ void *rw_image;
+ u32 image_off;
+ struct bpf_ksym ksym;
++#ifdef CONFIG_HAVE_STATIC_CALL
++ struct static_call_key *sc_key;
++ void *sc_tramp;
++#endif
+ };
+
+ static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
+@@ -911,6 +916,34 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
++
++/*
++ * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn
++ * indirection with a direct call to the bpf program. If the architecture does
++ * not have STATIC_CALL, avoid a double-indirection.
++ */
++#ifdef CONFIG_HAVE_STATIC_CALL
++
++#define __BPF_DISPATCHER_SC_INIT(_name) \
++ .sc_key = &STATIC_CALL_KEY(_name), \
++ .sc_tramp = STATIC_CALL_TRAMP_ADDR(_name),
++
++#define __BPF_DISPATCHER_SC(name) \
++ DEFINE_STATIC_CALL(bpf_dispatcher_##name##_call, bpf_dispatcher_nop_func)
++
++#define __BPF_DISPATCHER_CALL(name) \
++ static_call(bpf_dispatcher_##name##_call)(ctx, insnsi, bpf_func)
++
++#define __BPF_DISPATCHER_UPDATE(_d, _new) \
++ __static_call_update((_d)->sc_key, (_d)->sc_tramp, (_new))
++
++#else
++#define __BPF_DISPATCHER_SC_INIT(name)
++#define __BPF_DISPATCHER_SC(name)
++#define __BPF_DISPATCHER_CALL(name) bpf_func(ctx, insnsi)
++#define __BPF_DISPATCHER_UPDATE(_d, _new)
++#endif
++
+ #define BPF_DISPATCHER_INIT(_name) { \
+ .mutex = __MUTEX_INITIALIZER(_name.mutex), \
+ .func = &_name##_func, \
+@@ -922,25 +955,29 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func
+ .name = #_name, \
+ .lnode = LIST_HEAD_INIT(_name.ksym.lnode), \
+ }, \
++ __BPF_DISPATCHER_SC_INIT(_name##_call) \
+ }
+
+ #define DEFINE_BPF_DISPATCHER(name) \
++ __BPF_DISPATCHER_SC(name); \
+ noinline __nocfi unsigned int bpf_dispatcher_##name##_func( \
+ const void *ctx, \
+ const struct bpf_insn *insnsi, \
+ bpf_func_t bpf_func) \
+ { \
+- return bpf_func(ctx, insnsi); \
++ return __BPF_DISPATCHER_CALL(name); \
+ } \
+ EXPORT_SYMBOL(bpf_dispatcher_##name##_func); \
+ struct bpf_dispatcher bpf_dispatcher_##name = \
+ BPF_DISPATCHER_INIT(bpf_dispatcher_##name);
++
+ #define DECLARE_BPF_DISPATCHER(name) \
+ unsigned int bpf_dispatcher_##name##_func( \
+ const void *ctx, \
+ const struct bpf_insn *insnsi, \
+ bpf_func_t bpf_func); \
+ extern struct bpf_dispatcher bpf_dispatcher_##name;
++
+ #define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func
+ #define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name)
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h
+index 9f6e25467844a..444236dadcf08 100644
+--- a/include/linux/fault-inject.h
++++ b/include/linux/fault-inject.h
+@@ -20,7 +20,6 @@ struct fault_attr {
+ atomic_t space;
+ unsigned long verbose;
+ bool task_filter;
+- bool no_warn;
+ unsigned long stacktrace_depth;
+ unsigned long require_start;
+ unsigned long require_end;
+@@ -32,6 +31,10 @@ struct fault_attr {
+ struct dentry *dname;
+ };
+
++enum fault_flags {
++ FAULT_NOWARN = 1 << 0,
++};
++
+ #define FAULT_ATTR_INITIALIZER { \
+ .interval = 1, \
+ .times = ATOMIC_INIT(1), \
+@@ -40,11 +43,11 @@ struct fault_attr {
+ .ratelimit_state = RATELIMIT_STATE_INIT_DISABLED, \
+ .verbose = 2, \
+ .dname = NULL, \
+- .no_warn = false, \
+ }
+
+ #define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER
+ int setup_fault_attr(struct fault_attr *attr, char *str);
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags);
+ bool should_fail(struct fault_attr *attr, ssize_t size);
+
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/include/linux/fscache.h b/include/linux/fscache.h
+index 36e5dd84cf599..8e312c8323a8e 100644
+--- a/include/linux/fscache.h
++++ b/include/linux/fscache.h
+@@ -75,7 +75,7 @@ struct fscache_volume {
+ atomic_t n_accesses; /* Number of cache accesses in progress */
+ unsigned int debug_id;
+ unsigned int key_hash; /* Hash of key string */
+- char *key; /* Volume ID, eg. "afs@example.com@1234" */
++ u8 *key; /* Volume ID, eg. "afs@example.com@1234" */
+ struct list_head proc_link; /* Link in /proc/fs/fscache/volumes */
+ struct hlist_bl_node hash_link; /* Link in hash table */
+ struct work_struct work;
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 454dab40baf69..2d56cfe0911d7 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -984,6 +984,7 @@ struct mlx5_async_work {
+ struct mlx5_async_ctx *ctx;
+ mlx5_async_cbk_t user_callback;
+ u16 opcode; /* cmd opcode */
++ u16 op_mod; /* cmd op_mod */
+ void *out; /* pointer to the cmd output buffer */
+ };
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 3827a6b395fdb..bce6b228cf56e 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -83,7 +83,7 @@ struct neigh_parms {
+ struct rcu_head rcu_head;
+
+ int reachable_time;
+- int qlen;
++ u32 qlen;
+ int data[NEIGH_VAR_DATA_MAX];
+ DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
+ };
+diff --git a/include/sound/sof/info.h b/include/sound/sof/info.h
+index 65e86e4e9fd8e..75193850ead0c 100644
+--- a/include/sound/sof/info.h
++++ b/include/sound/sof/info.h
+@@ -36,6 +36,10 @@ enum sof_ipc_ext_data {
+ SOF_IPC_EXT_USER_ABI_INFO = 4,
+ };
+
++/* Build u32 number in format MMmmmppp */
++#define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \
++ ((MAJOR) << 24) | ((MINOR) << 12) | (PATCH)))
++
+ /* FW version - SOF_IPC_GLB_VERSION */
+ struct sof_ipc_fw_version {
+ struct sof_ipc_hdr hdr;
+diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
+index 7c1dc818b1d56..d676ed2b246ec 100644
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -187,7 +187,7 @@
+ #define AUDIT_MAX_KEY_LEN 256
+ #define AUDIT_BITMASK_SIZE 64
+ #define AUDIT_WORD(nr) ((__u32)((nr)/32))
+-#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32))
++#define AUDIT_BIT(nr) (1U << ((nr) - AUDIT_WORD(nr)*32))
+
+ #define AUDIT_SYSCALL_CLASSES 16
+ #define AUDIT_CLASS_DIR_WRITE 0
+diff --git a/init/Kconfig b/init/Kconfig
+index 532362fcfe31f..d1d779d6ba430 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -76,7 +76,7 @@ config CC_HAS_ASM_GOTO_OUTPUT
+ config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ depends on CC_HAS_ASM_GOTO_OUTPUT
+ # Detect buggy gcc and clang, fixed in gcc-11 clang-14.
+- def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
++ def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
+
+ config TOOLS_SUPPORT_RELR
+ def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index 7b473259f3f45..68dfc6936aa72 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -101,8 +101,6 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ err:
+ if (needs_switch)
+ io_rsrc_node_switch(ctx, ctx->file_data);
+- if (ret)
+- fput(file);
+ return ret;
+ }
+
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 1b552d2137635..585f97b31a93d 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -229,9 +229,14 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
+
+ static inline bool io_run_task_work(void)
+ {
++ /*
++ * Always check-and-clear the task_work notification signal. With how
++ * signaling works for task_work, we can find it set with nothing to
++ * run. We need to clear it for that case, like get_signal() does.
++ */
++ if (test_thread_flag(TIF_NOTIFY_SIGNAL))
++ clear_notify_signal();
+ if (task_work_pending(current)) {
+- if (test_thread_flag(TIF_NOTIFY_SIGNAL))
+- clear_notify_signal();
+ __set_current_state(TASK_RUNNING);
+ task_work_run();
+ return 1;
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index ba0f684669306..d9bf1767867e6 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -40,7 +40,14 @@ struct io_poll_table {
+ };
+
+ #define IO_POLL_CANCEL_FLAG BIT(31)
+-#define IO_POLL_REF_MASK GENMASK(30, 0)
++#define IO_POLL_RETRY_FLAG BIT(30)
++#define IO_POLL_REF_MASK GENMASK(29, 0)
++
++/*
++ * We usually have 1-2 refs taken, 128 is more than enough and we want to
++ * maximise the margin between this amount and the moment when it overflows.
++ */
++#define IO_POLL_REF_BIAS 128
+
+ #define IO_WQE_F_DOUBLE 1
+
+@@ -58,6 +65,21 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+ return priv & IO_WQE_F_DOUBLE;
+ }
+
++static bool io_poll_get_ownership_slowpath(struct io_kiocb *req)
++{
++ int v;
++
++ /*
++ * poll_refs are already elevated and we don't have much hope for
++ * grabbing the ownership. Instead of incrementing set a retry flag
++ * to notify the loop that there might have been some change.
++ */
++ v = atomic_fetch_or(IO_POLL_RETRY_FLAG, &req->poll_refs);
++ if (v & IO_POLL_REF_MASK)
++ return false;
++ return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
++}
++
+ /*
+ * If refs part of ->poll_refs (see IO_POLL_REF_MASK) is 0, it's free. We can
+ * bump it and acquire ownership. It's disallowed to modify requests while not
+@@ -66,6 +88,8 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+ */
+ static inline bool io_poll_get_ownership(struct io_kiocb *req)
+ {
++ if (unlikely(atomic_read(&req->poll_refs) >= IO_POLL_REF_BIAS))
++ return io_poll_get_ownership_slowpath(req);
+ return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
+ }
+
+@@ -116,6 +140,8 @@ static void io_poll_req_insert_locked(struct io_kiocb *req)
+ struct io_hash_table *table = &req->ctx->cancel_table_locked;
+ u32 index = hash_long(req->cqe.user_data, table->hash_bits);
+
++ lockdep_assert_held(&req->ctx->uring_lock);
++
+ hlist_add_head(&req->hash_node, &table->hbs[index].list);
+ }
+
+@@ -233,6 +259,16 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ */
+ if ((v & IO_POLL_REF_MASK) != 1)
+ req->cqe.res = 0;
++ if (v & IO_POLL_RETRY_FLAG) {
++ req->cqe.res = 0;
++ /*
++ * We won't find new events that came in between
++ * vfs_poll and the ref put unless we clear the flag
++ * in advance.
++ */
++ atomic_andnot(IO_POLL_RETRY_FLAG, &req->poll_refs);
++ v &= ~IO_POLL_RETRY_FLAG;
++ }
+
+ /* the mask was stashed in __io_poll_execute */
+ if (!req->cqe.res) {
+@@ -272,7 +308,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ * Release all references, retry if someone tried to restart
+ * task_work while we were executing it.
+ */
+- } while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs));
++ } while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs) &
++ IO_POLL_REF_MASK);
+
+ return IOU_POLL_NO_ACTION;
+ }
+@@ -516,7 +553,6 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+ unsigned issue_flags)
+ {
+ struct io_ring_ctx *ctx = req->ctx;
+- int v;
+
+ INIT_HLIST_NODE(&req->hash_node);
+ req->work.cancel_seq = atomic_read(&ctx->cancel_seq);
+@@ -584,11 +620,10 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+
+ if (ipt->owning) {
+ /*
+- * Release ownership. If someone tried to queue a tw while it was
+- * locked, kick it off for them.
++ * Try to release ownership. If we see a change of state, e.g.
++ * poll was waken up, queue up a tw, it'll deal with it.
+ */
+- v = atomic_dec_return(&req->poll_refs);
+- if (unlikely(v & IO_POLL_REF_MASK))
++ if (atomic_cmpxchg(&req->poll_refs, 1, 0) != 1)
+ __io_poll_execute(req, 0);
+ }
+ return 0;
+diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
+index fa64b80b8bcab..c19719f48ce06 100644
+--- a/kernel/bpf/dispatcher.c
++++ b/kernel/bpf/dispatcher.c
+@@ -4,6 +4,7 @@
+ #include <linux/hash.h>
+ #include <linux/bpf.h>
+ #include <linux/filter.h>
++#include <linux/static_call.h>
+
+ /* The BPF dispatcher is a multiway branch code generator. The
+ * dispatcher is a mechanism to avoid the performance penalty of an
+@@ -104,17 +105,11 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *b
+
+ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ {
+- void *old, *new, *tmp;
+- u32 noff;
+- int err;
+-
+- if (!prev_num_progs) {
+- old = NULL;
+- noff = 0;
+- } else {
+- old = d->image + d->image_off;
++ void *new, *tmp;
++ u32 noff = 0;
++
++ if (prev_num_progs)
+ noff = d->image_off ^ (PAGE_SIZE / 2);
+- }
+
+ new = d->num_progs ? d->image + noff : NULL;
+ tmp = d->num_progs ? d->rw_image + noff : NULL;
+@@ -128,11 +123,10 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ return;
+ }
+
+- err = bpf_arch_text_poke(d->func, BPF_MOD_JUMP, old, new);
+- if (err || !new)
+- return;
++ __BPF_DISPATCHER_UPDATE(d, new ?: (void *)&bpf_dispatcher_nop_func);
+
+- d->image_off = noff;
++ if (new)
++ d->image_off = noff;
+ }
+
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c
+index cbb0bed958abd..7670a811a5657 100644
+--- a/kernel/gcov/clang.c
++++ b/kernel/gcov/clang.c
+@@ -280,6 +280,8 @@ void gcov_info_add(struct gcov_info *dst, struct gcov_info *src)
+
+ for (i = 0; i < sfn_ptr->num_counters; i++)
+ dfn_ptr->counters[i] += sfn_ptr->counters[i];
++
++ sfn_ptr = list_next_entry(sfn_ptr, head);
+ }
+ }
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index cb131fad117cc..997d23641448a 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -2095,6 +2095,7 @@ config KPROBES_SANITY_TEST
+ depends on DEBUG_KERNEL
+ depends on KPROBES
+ depends on KUNIT
++ select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+ default KUNIT_ALL_TESTS
+ help
+ This option provides for testing basic kprobes functionality on
+diff --git a/lib/fault-inject.c b/lib/fault-inject.c
+index 423784d9c058e..70768d8a2200b 100644
+--- a/lib/fault-inject.c
++++ b/lib/fault-inject.c
+@@ -41,9 +41,6 @@ EXPORT_SYMBOL_GPL(setup_fault_attr);
+
+ static void fail_dump(struct fault_attr *attr)
+ {
+- if (attr->no_warn)
+- return;
+-
+ if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) {
+ printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
+ "name %pd, interval %lu, probability %lu, "
+@@ -103,7 +100,7 @@ static inline bool fail_stacktrace(struct fault_attr *attr)
+ * http://www.nongnu.org/failmalloc/
+ */
+
+-bool should_fail(struct fault_attr *attr, ssize_t size)
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags)
+ {
+ if (in_task()) {
+ unsigned int fail_nth = READ_ONCE(current->fail_nth);
+@@ -146,13 +143,19 @@ bool should_fail(struct fault_attr *attr, ssize_t size)
+ return false;
+
+ fail:
+- fail_dump(attr);
++ if (!(flags & FAULT_NOWARN))
++ fail_dump(attr);
+
+ if (atomic_read(&attr->times) != -1)
+ atomic_dec_not_zero(&attr->times);
+
+ return true;
+ }
++
++bool should_fail(struct fault_attr *attr, ssize_t size)
++{
++ return should_fail_ex(attr, size, 0);
++}
+ EXPORT_SYMBOL_GPL(should_fail);
+
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/lib/vdso/Makefile b/lib/vdso/Makefile
+index c415a685d61bb..e814061d6aa01 100644
+--- a/lib/vdso/Makefile
++++ b/lib/vdso/Makefile
+@@ -17,6 +17,6 @@ $(error ARCH_REL_TYPE_ABS is not set)
+ endif
+
+ quiet_cmd_vdso_check = VDSOCHK $@
+- cmd_vdso_check = if $(OBJDUMP) -R $@ | egrep -h "$(ARCH_REL_TYPE_ABS)"; \
++ cmd_vdso_check = if $(OBJDUMP) -R $@ | grep -E -h "$(ARCH_REL_TYPE_ABS)"; \
+ then (echo >&2 "$@: dynamic relocations are not supported"; \
+ rm -f $@; /bin/false); fi
+diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
+index bdef9682d0a00..b4b9614eecbed 100644
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -2342,6 +2342,10 @@ static int damon_sysfs_upd_schemes_stats(struct damon_sysfs_kdamond *kdamond)
+ damon_for_each_scheme(scheme, ctx) {
+ struct damon_sysfs_stats *sysfs_stats;
+
++ /* user could have removed the scheme sysfs dir */
++ if (schemes_idx >= sysfs_schemes->nr)
++ break;
++
+ sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
+ sysfs_stats->nr_tried = scheme->stat.nr_tried;
+ sysfs_stats->sz_tried = scheme->stat.sz_tried;
+diff --git a/mm/failslab.c b/mm/failslab.c
+index 58df9789f1d22..ffc420c0e767f 100644
+--- a/mm/failslab.c
++++ b/mm/failslab.c
+@@ -16,6 +16,8 @@ static struct {
+
+ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ {
++ int flags = 0;
++
+ /* No fault-injection for bootstrap cache */
+ if (unlikely(s == kmem_cache))
+ return false;
+@@ -30,10 +32,16 @@ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB))
+ return false;
+
++ /*
++ * In some cases, it expects to specify __GFP_NOWARN
++ * to avoid printing any information(not just a warning),
++ * thus avoiding deadlocks. See commit 6b9dbedbe349 for
++ * details.
++ */
+ if (gfpflags & __GFP_NOWARN)
+- failslab.attr.no_warn = true;
++ flags |= FAULT_NOWARN;
+
+- return should_fail(&failslab.attr, s->object_size);
++ return should_fail_ex(&failslab.attr, s->object_size, flags);
+ }
+
+ static int __init setup_failslab(char *str)
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index b69979c9ced5c..6a95ea7c5ee70 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2971,7 +2971,7 @@ struct obj_cgroup *get_obj_cgroup_from_page(struct page *page)
+ {
+ struct obj_cgroup *objcg;
+
+- if (!memcg_kmem_enabled() || memcg_kmem_bypass())
++ if (!memcg_kmem_enabled())
+ return NULL;
+
+ if (PageMemcgKmem(page)) {
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 19749f5409e72..5d9b98774a826 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -3883,6 +3883,8 @@ __setup("fail_page_alloc=", setup_fail_page_alloc);
+
+ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ {
++ int flags = 0;
++
+ if (order < fail_page_alloc.min_order)
+ return false;
+ if (gfp_mask & __GFP_NOFAIL)
+@@ -3893,10 +3895,11 @@ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ (gfp_mask & __GFP_DIRECT_RECLAIM))
+ return false;
+
++ /* See comment in __should_failslab() */
+ if (gfp_mask & __GFP_NOWARN)
+- fail_page_alloc.attr.no_warn = true;
++ flags |= FAULT_NOWARN;
+
+- return should_fail(&fail_page_alloc.attr, 1 << order);
++ return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags);
+ }
+
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 382dbe97329f3..a69f32dd5ce5d 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2472,8 +2472,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
+ * the flushers simply cannot keep up with the allocation
+ * rate. Nudge the flusher threads in case they are asleep.
+ */
+- if (stat.nr_unqueued_dirty == nr_taken)
++ if (stat.nr_unqueued_dirty == nr_taken) {
+ wakeup_flusher_threads(WB_REASON_VMSCAN);
++ /*
++ * For cgroupv1 dirty throttling is achieved by waking up
++ * the kernel flusher here and later waiting on folios
++ * which are in writeback to finish (see shrink_folio_list()).
++ *
++ * Flusher may not be able to issue writeback quickly
++ * enough for cgroupv1 writeback throttling to work
++ * on a large system.
++ */
++ if (!writeback_throttling_sane(sc))
++ reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
++ }
+
+ sc->nr.dirty += stat.nr_dirty;
+ sc->nr.congested += stat.nr_congested;
+@@ -2955,8 +2967,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ enum lru_list lru;
+ unsigned long nr_reclaimed = 0;
+ unsigned long nr_to_reclaim = sc->nr_to_reclaim;
++ bool proportional_reclaim;
+ struct blk_plug plug;
+- bool scan_adjusted;
+
+ get_scan_count(lruvec, sc, nr);
+
+@@ -2974,8 +2986,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ * abort proportional reclaim if either the file or anon lru has already
+ * dropped to zero at the first pass.
+ */
+- scan_adjusted = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
+- sc->priority == DEF_PRIORITY);
++ proportional_reclaim = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
++ sc->priority == DEF_PRIORITY);
+
+ blk_start_plug(&plug);
+ while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+@@ -2995,7 +3007,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+
+ cond_resched();
+
+- if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
++ if (nr_reclaimed < nr_to_reclaim || proportional_reclaim)
+ continue;
+
+ /*
+@@ -3046,8 +3058,6 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ nr_scanned = targets[lru] - nr[lru];
+ nr[lru] = targets[lru] * (100 - percentage) / 100;
+ nr[lru] -= min(nr[lru], nr_scanned);
+-
+- scan_adjusted = true;
+ }
+ blk_finish_plug(&plug);
+ sc->nr_reclaimed += nr_reclaimed;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 0191f22d1ec35..8487321c1fc78 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -202,9 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+
+ list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ list_move(&req->req_list, &cancel_list);
++ req->status = REQ_STATUS_ERROR;
+ }
+ list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ list_move(&req->req_list, &cancel_list);
++ req->status = REQ_STATUS_ERROR;
+ }
+
+ spin_unlock(&m->req_lock);
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 7105529abb0f6..c433b1fb961ab 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -272,7 +272,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
+ key->ct_zone = ct->zone.id;
+ #endif
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+- key->ct_mark = ct->mark;
++ key->ct_mark = READ_ONCE(ct->mark);
+ #endif
+
+ cl = nf_ct_labels_find(ct);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 84755db81e9d9..35f5a3125808d 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -307,7 +307,31 @@ static int neigh_del_timer(struct neighbour *n)
+ return 0;
+ }
+
+-static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
++static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
++ int family)
++{
++ switch (family) {
++ case AF_INET:
++ return __in_dev_arp_parms_get_rcu(dev);
++ case AF_INET6:
++ return __in6_dev_nd_parms_get_rcu(dev);
++ }
++ return NULL;
++}
++
++static void neigh_parms_qlen_dec(struct net_device *dev, int family)
++{
++ struct neigh_parms *p;
++
++ rcu_read_lock();
++ p = neigh_get_dev_parms_rcu(dev, family);
++ if (p)
++ p->qlen--;
++ rcu_read_unlock();
++}
++
++static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net,
++ int family)
+ {
+ struct sk_buff_head tmp;
+ unsigned long flags;
+@@ -321,13 +345,7 @@ static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
+ struct net_device *dev = skb->dev;
+
+ if (net == NULL || net_eq(dev_net(dev), net)) {
+- struct in_device *in_dev;
+-
+- rcu_read_lock();
+- in_dev = __in_dev_get_rcu(dev);
+- if (in_dev)
+- in_dev->arp_parms->qlen--;
+- rcu_read_unlock();
++ neigh_parms_qlen_dec(dev, family);
+ __skb_unlink(skb, list);
+ __skb_queue_tail(&tmp, skb);
+ }
+@@ -409,7 +427,8 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
+ write_lock_bh(&tbl->lock);
+ neigh_flush_dev(tbl, dev, skip_perm);
+ pneigh_ifdown_and_unlock(tbl, dev);
+- pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
++ pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL,
++ tbl->family);
+ if (skb_queue_empty_lockless(&tbl->proxy_queue))
+ del_timer_sync(&tbl->proxy_timer);
+ return 0;
+@@ -1621,13 +1640,8 @@ static void neigh_proxy_process(struct timer_list *t)
+
+ if (tdif <= 0) {
+ struct net_device *dev = skb->dev;
+- struct in_device *in_dev;
+
+- rcu_read_lock();
+- in_dev = __in_dev_get_rcu(dev);
+- if (in_dev)
+- in_dev->arp_parms->qlen--;
+- rcu_read_unlock();
++ neigh_parms_qlen_dec(dev, tbl->family);
+ __skb_unlink(skb, &tbl->proxy_queue);
+
+ if (tbl->proxy_redo && netif_running(dev)) {
+@@ -1821,7 +1835,7 @@ int neigh_table_clear(int index, struct neigh_table *tbl)
+ cancel_delayed_work_sync(&tbl->managed_work);
+ cancel_delayed_work_sync(&tbl->gc_work);
+ del_timer_sync(&tbl->proxy_timer);
+- pneigh_queue_purge(&tbl->proxy_queue, NULL);
++ pneigh_queue_purge(&tbl->proxy_queue, NULL, tbl->family);
+ neigh_ifdown(tbl, NULL);
+ if (atomic_read(&tbl->entries))
+ pr_crit("neighbour leakage\n");
+@@ -3542,18 +3556,6 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write,
+ return ret;
+ }
+
+-static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
+- int family)
+-{
+- switch (family) {
+- case AF_INET:
+- return __in_dev_arp_parms_get_rcu(dev);
+- case AF_INET6:
+- return __in6_dev_nd_parms_get_rcu(dev);
+- }
+- return NULL;
+-}
+-
+ static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p,
+ int index)
+ {
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index da6e3b20cd758..60379ad7ae06d 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -136,6 +136,8 @@ failure:
+ * This unhashes the socket and releases the local port, if necessary.
+ */
+ dccp_set_state(sk, DCCP_CLOSED);
++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++ inet_reset_saddr(sk);
+ ip_rt_put(rt);
+ sk->sk_route_caps = 0;
+ inet->inet_dport = 0;
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index fd44638ec16b8..f9ed81a0ddbb9 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -967,6 +967,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+
+ late_failure:
+ dccp_set_state(sk, DCCP_CLOSED);
++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++ inet_reset_saddr(sk);
+ __sk_dst_reset(sk);
+ failure:
+ inet->inet_dport = 0;
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index e983bb0c50127..2dfb12230f089 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -402,6 +402,16 @@ config INET_IPCOMP
+
+ If unsure, say Y.
+
++config INET_TABLE_PERTURB_ORDER
++ int "INET: Source port perturbation table size (as power of 2)" if EXPERT
++ default 16
++ help
++ Source port perturbation table size (as power of 2) for
++ RFC 6056 3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm.
++
++ The default is almost always what you want.
++ Only change this if you know what you are doing.
++
+ config INET_XFRM_TUNNEL
+ tristate
+ select INET_TUNNEL
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index 170152772d332..3969fa805679c 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -314,6 +314,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features_
+ xo->seq.low += skb_shinfo(skb)->gso_segs;
+ }
+
++ if (xo->seq.low < seq)
++ xo->seq.hi++;
++
+ esp.seqno = cpu_to_be64(seq + ((u64)xo->seq.hi << 32));
+
+ ip_hdr(skb)->tot_len = htons(skb->len);
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 452ff177e4da9..f26d5ac117d62 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1381,8 +1381,10 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+
+ /* The alias was already inserted, so the node must exist. */
+ l = l ? l : fib_find_node(t, &tp, key);
+- if (WARN_ON_ONCE(!l))
++ if (WARN_ON_ONCE(!l)) {
++ err = -ENOENT;
+ goto out_free_new_fa;
++ }
+
+ if (fib_find_alias(&l->leaf, new_fa->fa_slen, 0, 0, tb->tb_id, true) ==
+ new_fa) {
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index f5950a7172d61..1e45fe6276f72 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -679,13 +679,13 @@ EXPORT_SYMBOL_GPL(inet_unhash);
+ * Note that we use 32bit integers (vs RFC 'short integers')
+ * because 2^16 is not a multiple of num_ephemeral and this
+ * property might be used by clever attacker.
++ *
+ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though
+- * attacks were since demonstrated, thus we use 65536 instead to really
+- * give more isolation and privacy, at the expense of 256kB of kernel
+- * memory.
++ * attacks were since demonstrated, thus we use 65536 by default instead
++ * to really give more isolation and privacy, at the expense of 256kB
++ * of kernel memory.
+ */
+-#define INET_TABLE_PERTURB_SHIFT 16
+-#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT)
++#define INET_TABLE_PERTURB_SIZE (1 << CONFIG_INET_TABLE_PERTURB_ORDER)
+ static u32 *table_perturb;
+
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 1b512390b3cf3..e880ce77322aa 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -366,6 +366,11 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ iph->tos, dev);
+ if (unlikely(err))
+ goto drop_error;
++ } else {
++ struct in_device *in_dev = __in_dev_get_rcu(dev);
++
++ if (in_dev && IN_DEV_ORCONF(in_dev, NOPOLICY))
++ IPCB(skb)->flags |= IPSKB_NOPOLICY;
+ }
+
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+index f8e176c77d1c1..b3cc416ed2923 100644
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -435,7 +435,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+
+ switch (ctinfo) {
+ case IP_CT_NEW:
+- ct->mark = hash;
++ WRITE_ONCE(ct->mark, hash);
+ break;
+ case IP_CT_RELATED:
+ case IP_CT_RELATED_REPLY:
+@@ -452,7 +452,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ #ifdef DEBUG
+ nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ #endif
+- pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
++ pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark));
+ if (!clusterip_responsible(cipinfo->config, hash)) {
+ pr_debug("not responsible\n");
+ return NF_DROP;
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index fe9a6022db66d..ef8013e2134fd 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -323,6 +323,8 @@ failure:
+ * if necessary.
+ */
+ tcp_set_state(sk, TCP_CLOSE);
++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++ inet_reset_saddr(sk);
+ ip_rt_put(rt);
+ sk->sk_route_caps = 0;
+ inet->inet_dport = 0;
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 79d43548279cb..242f4295940e6 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -346,6 +346,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features
+ xo->seq.low += skb_shinfo(skb)->gso_segs;
+ }
+
++ if (xo->seq.low < seq)
++ xo->seq.hi++;
++
+ esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
+
+ len = skb->len - sizeof(struct ipv6hdr);
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index e54eee80ce5f3..5516cfb96c488 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -340,6 +340,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+
+ late_failure:
+ tcp_set_state(sk, TCP_CLOSE);
++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++ inet_reset_saddr(sk);
+ failure:
+ inet->inet_dport = 0;
+ sk->sk_route_caps = 0;
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 4a4b0e49ec92d..ea435eba30534 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -287,9 +287,13 @@ int __init xfrm6_init(void)
+ if (ret)
+ goto out_state;
+
+- register_pernet_subsys(&xfrm6_net_ops);
++ ret = register_pernet_subsys(&xfrm6_net_ops);
++ if (ret)
++ goto out_protocol;
+ out:
+ return ret;
++out_protocol:
++ xfrm6_protocol_fini();
+ out_state:
+ xfrm6_state_fini();
+ out_policy:
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index c85df5b958d26..95edcbedf6ef2 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2905,7 +2905,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
+ break;
+ if (!aalg->pfkey_supported)
+ continue;
+- if (aalg_tmpl_set(t, aalg) && aalg->available)
++ if (aalg_tmpl_set(t, aalg))
+ sz += sizeof(struct sadb_comb);
+ }
+ return sz + sizeof(struct sadb_prop);
+@@ -2923,7 +2923,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ if (!ealg->pfkey_supported)
+ continue;
+
+- if (!(ealg_tmpl_set(t, ealg) && ealg->available))
++ if (!(ealg_tmpl_set(t, ealg)))
+ continue;
+
+ for (k = 1; ; k++) {
+@@ -2934,16 +2934,17 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ if (!aalg->pfkey_supported)
+ continue;
+
+- if (aalg_tmpl_set(t, aalg) && aalg->available)
++ if (aalg_tmpl_set(t, aalg))
+ sz += sizeof(struct sadb_comb);
+ }
+ }
+ return sz + sizeof(struct sadb_prop);
+ }
+
+-static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ struct sadb_prop *p;
++ int sz = 0;
+ int i;
+
+ p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -2971,13 +2972,17 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ c->sadb_comb_soft_addtime = 20*60*60;
+ c->sadb_comb_hard_usetime = 8*60*60;
+ c->sadb_comb_soft_usetime = 7*60*60;
++ sz += sizeof(*c);
+ }
+ }
++
++ return sz + sizeof(*p);
+ }
+
+-static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ struct sadb_prop *p;
++ int sz = 0;
+ int i, k;
+
+ p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -3019,8 +3024,11 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ c->sadb_comb_soft_addtime = 20*60*60;
+ c->sadb_comb_hard_usetime = 8*60*60;
+ c->sadb_comb_soft_usetime = 7*60*60;
++ sz += sizeof(*c);
+ }
+ }
++
++ return sz + sizeof(*p);
+ }
+
+ static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c)
+@@ -3150,6 +3158,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ struct sadb_x_sec_ctx *sec_ctx;
+ struct xfrm_sec_ctx *xfrm_ctx;
+ int ctx_size = 0;
++ int alg_size = 0;
+
+ sockaddr_size = pfkey_sockaddr_size(x->props.family);
+ if (!sockaddr_size)
+@@ -3161,16 +3170,16 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ sizeof(struct sadb_x_policy);
+
+ if (x->id.proto == IPPROTO_AH)
+- size += count_ah_combs(t);
++ alg_size = count_ah_combs(t);
+ else if (x->id.proto == IPPROTO_ESP)
+- size += count_esp_combs(t);
++ alg_size = count_esp_combs(t);
+
+ if ((xfrm_ctx = x->security)) {
+ ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+ size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
+ }
+
+- skb = alloc_skb(size + 16, GFP_ATOMIC);
++ skb = alloc_skb(size + alg_size + 16, GFP_ATOMIC);
+ if (skb == NULL)
+ return -ENOMEM;
+
+@@ -3224,10 +3233,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ pol->sadb_x_policy_priority = xp->priority;
+
+ /* Set sadb_comb's. */
++ alg_size = 0;
+ if (x->id.proto == IPPROTO_AH)
+- dump_ah_combs(skb, t);
++ alg_size = dump_ah_combs(skb, t);
+ else if (x->id.proto == IPPROTO_ESP)
+- dump_esp_combs(skb, t);
++ alg_size = dump_esp_combs(skb, t);
++
++ hdr->sadb_msg_len += alg_size / 8;
+
+ /* security context */
+ if (xfrm_ctx) {
+@@ -3382,7 +3394,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
+ hdr->sadb_msg_len = size / sizeof(uint64_t);
+ hdr->sadb_msg_errno = 0;
+ hdr->sadb_msg_reserved = 0;
+- hdr->sadb_msg_seq = x->km.seq = get_acqseq();
++ hdr->sadb_msg_seq = x->km.seq;
+ hdr->sadb_msg_pid = 0;
+
+ /* SA */
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 5b1c47ed0cc08..87e24bba4c673 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1437,8 +1437,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ ieee80211_led_exit(local);
+ destroy_workqueue(local->workqueue);
+ fail_workqueue:
+- if (local->wiphy_ciphers_allocated)
++ if (local->wiphy_ciphers_allocated) {
+ kfree(local->hw.wiphy->cipher_suites);
++ local->wiphy_ciphers_allocated = false;
++ }
+ kfree(local->int_scan_req);
+ return result;
+ }
+@@ -1506,8 +1508,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
+ mutex_destroy(&local->iflist_mtx);
+ mutex_destroy(&local->mtx);
+
+- if (local->wiphy_ciphers_allocated)
++ if (local->wiphy_ciphers_allocated) {
+ kfree(local->hw.wiphy->cipher_suites);
++ local->wiphy_ciphers_allocated = false;
++ }
+
+ idr_for_each(&local->ack_status_frames,
+ ieee80211_free_ack_frame, NULL);
+diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
+index acc1c299f1ae5..69d5e1ec6edef 100644
+--- a/net/mac80211/mesh_pathtbl.c
++++ b/net/mac80211/mesh_pathtbl.c
+@@ -710,7 +710,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
+ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
+ {
+- kfree_skb(skb);
++ ieee80211_free_txskb(&sdata->local->hw, skb);
+ sdata->u.mesh.mshstats.dropped_frames_no_route++;
+ }
+
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 3adc291d9ce18..7499192af5866 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -916,7 +916,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ #ifdef IP_SET_HASH_WITH_MULTI
+ if (h->bucketsize >= AHASH_MAX_TUNED)
+ goto set_full;
+- else if (h->bucketsize < multi)
++ else if (h->bucketsize <= multi)
+ h->bucketsize += AHASH_INIT_SIZE;
+ #endif
+ if (n->size >= AHASH_MAX(h)) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index dd30c03d5a23f..75d556d71652d 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -151,18 +151,16 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+ return -ERANGE;
+
+- if (retried) {
++ if (retried)
+ ip = ntohl(h->next.ip);
+- e.ip = htonl(ip);
+- }
+ for (; ip <= ip_to;) {
++ e.ip = htonl(ip);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+
+ ip += hosts;
+- e.ip = htonl(ip);
+- if (e.ip == 0)
++ if (ip == 0)
+ return 0;
+
+ ret = 0;
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 8f261cd5b3a50..60289c074eef4 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1781,7 +1781,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- ct->mark = exp->master->mark;
++ ct->mark = READ_ONCE(exp->master->mark);
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+ ct->secmark = exp->master->secmark;
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 7562b215b932a..d71150a40fb08 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,9 +328,9 @@ nla_put_failure:
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
++static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
+ {
+- if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
++ if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ goto nla_put_failure;
+ return 0;
+
+@@ -543,7 +543,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ if (ctnetlink_dump_status(skb, ct) < 0 ||
+- ctnetlink_dump_mark(skb, ct) < 0 ||
++ ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
+ ctnetlink_dump_secctx(skb, ct) < 0 ||
+ ctnetlink_dump_id(skb, ct) < 0 ||
+ ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,6 +722,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ struct sk_buff *skb;
+ unsigned int type;
+ unsigned int flags = 0, group;
++ u32 mark;
+ int err;
+
+ if (events & (1 << IPCT_DESTROY)) {
+@@ -826,8 +827,9 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- if ((events & (1 << IPCT_MARK) || ct->mark)
+- && ctnetlink_dump_mark(skb, ct) < 0)
++ mark = READ_ONCE(ct->mark);
++ if ((events & (1 << IPCT_MARK) || mark) &&
++ ctnetlink_dump_mark(skb, mark) < 0)
+ goto nla_put_failure;
+ #endif
+ nlmsg_end(skb, nlh);
+@@ -1154,7 +1156,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- if ((ct->mark & filter->mark.mask) != filter->mark.val)
++ if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val)
+ goto ignore_entry;
+ #endif
+ status = (u32)READ_ONCE(ct->status);
+@@ -2002,9 +2004,9 @@ static void ctnetlink_change_mark(struct nf_conn *ct,
+ mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+
+ mark = ntohl(nla_get_be32(cda[CTA_MARK]));
+- newmark = (ct->mark & mask) ^ mark;
+- if (newmark != ct->mark)
+- ct->mark = newmark;
++ newmark = (READ_ONCE(ct->mark) & mask) ^ mark;
++ if (newmark != READ_ONCE(ct->mark))
++ WRITE_ONCE(ct->mark, newmark);
+ }
+ #endif
+
+@@ -2669,6 +2671,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ const struct nf_conntrack_zone *zone;
+ struct nlattr *nest_parms;
++ u32 mark;
+
+ zone = nf_ct_zone(ct);
+
+@@ -2730,7 +2733,8 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ goto nla_put_failure;
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
++ mark = READ_ONCE(ct->mark);
++ if (mark && ctnetlink_dump_mark(skb, mark) < 0)
+ goto nla_put_failure;
+ #endif
+ if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 4ffe84c5a82cb..bca839ab1ae8d 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -366,7 +366,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
+ goto release;
+
+ #if defined(CONFIG_NF_CONNTRACK_MARK)
+- seq_printf(s, "mark=%u ", ct->mark);
++ seq_printf(s, "mark=%u ", READ_ONCE(ct->mark));
+ #endif
+
+ ct_show_secctx(s, ct);
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index b04645ced89ba..00b522890d77b 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -1098,6 +1098,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ struct flow_block_cb *block_cb, *next;
+ int err = 0;
+
++ down_write(&flowtable->flow_block_lock);
+ switch (cmd) {
+ case FLOW_BLOCK_BIND:
+ list_splice(&bo->cb_list, &flowtable->flow_block.cb_list);
+@@ -1112,6 +1113,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ WARN_ON_ONCE(1);
+ err = -EOPNOTSUPP;
+ }
++ up_write(&flowtable->flow_block_lock);
+
+ return err;
+ }
+@@ -1168,7 +1170,9 @@ static int nf_flow_table_offload_cmd(struct flow_block_offload *bo,
+
+ nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
+ extack);
++ down_write(&flowtable->flow_block_lock);
+ err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
++ up_write(&flowtable->flow_block_lock);
+ if (err < 0)
+ return err;
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 42e370575c304..0a6f3c1e9ab75 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5958,7 +5958,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ &timeout);
+ if (err)
+ return err;
+- } else if (set->flags & NFT_SET_TIMEOUT) {
++ } else if (set->flags & NFT_SET_TIMEOUT &&
++ !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ timeout = set->timeout;
+ }
+
+@@ -6024,7 +6025,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ err = -EOPNOTSUPP;
+ goto err_set_elem_expr;
+ }
+- } else if (set->num_exprs > 0) {
++ } else if (set->num_exprs > 0 &&
++ !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ err = nft_set_elem_expr_clone(ctx, set, expr_array);
+ if (err < 0)
+ goto err_set_elem_expr_clone;
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index a3f01f209a533..641dc21f92b43 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -98,7 +98,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
+ return;
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ case NFT_CT_MARK:
+- *dest = ct->mark;
++ *dest = READ_ONCE(ct->mark);
+ return;
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+@@ -297,8 +297,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
+ switch (priv->key) {
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ case NFT_CT_MARK:
+- if (ct->mark != value) {
+- ct->mark = value;
++ if (READ_ONCE(ct->mark) != value) {
++ WRITE_ONCE(ct->mark, value);
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ }
+ break;
+diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
+index e5ebc0810675a..ad3c033db64e7 100644
+--- a/net/netfilter/xt_connmark.c
++++ b/net/netfilter/xt_connmark.c
+@@ -30,6 +30,7 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ u_int32_t new_targetmark;
+ struct nf_conn *ct;
+ u_int32_t newmark;
++ u_int32_t oldmark;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct == NULL)
+@@ -37,14 +38,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+
+ switch (info->mode) {
+ case XT_CONNMARK_SET:
+- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
++ oldmark = READ_ONCE(ct->mark);
++ newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
+ if (info->shift_dir == D_SHIFT_RIGHT)
+ newmark >>= info->shift_bits;
+ else
+ newmark <<= info->shift_bits;
+
+- if (ct->mark != newmark) {
+- ct->mark = newmark;
++ if (READ_ONCE(ct->mark) != newmark) {
++ WRITE_ONCE(ct->mark, newmark);
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ }
+ break;
+@@ -55,15 +57,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ else
+ new_targetmark <<= info->shift_bits;
+
+- newmark = (ct->mark & ~info->ctmask) ^
++ newmark = (READ_ONCE(ct->mark) & ~info->ctmask) ^
+ new_targetmark;
+- if (ct->mark != newmark) {
+- ct->mark = newmark;
++ if (READ_ONCE(ct->mark) != newmark) {
++ WRITE_ONCE(ct->mark, newmark);
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ }
+ break;
+ case XT_CONNMARK_RESTORE:
+- new_targetmark = (ct->mark & info->ctmask);
++ new_targetmark = (READ_ONCE(ct->mark) & info->ctmask);
+ if (info->shift_dir == D_SHIFT_RIGHT)
+ new_targetmark >>= info->shift_bits;
+ else
+@@ -126,7 +128,7 @@ connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ if (ct == NULL)
+ return false;
+
+- return ((ct->mark & info->mask) == info->mark) ^ info->invert;
++ return ((READ_ONCE(ct->mark) & info->mask) == info->mark) ^ info->invert;
+ }
+
+ static int connmark_mt_check(const struct xt_mtchk_param *par)
+diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
+index 6a193cce2a754..4ffdf2f45c444 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -542,7 +542,7 @@ static int nci_open_device(struct nci_dev *ndev)
+ skb_queue_purge(&ndev->tx_q);
+
+ ndev->ops->close(ndev);
+- ndev->flags = 0;
++ ndev->flags &= BIT(NCI_UNREG);
+ }
+
+ done:
+diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
+index aa5e712adf078..3d36ea5701f02 100644
+--- a/net/nfc/nci/data.c
++++ b/net/nfc/nci/data.c
+@@ -279,8 +279,10 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
+ nci_plen(skb->data));
+
+ conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data));
+- if (!conn_info)
++ if (!conn_info) {
++ kfree_skb(skb);
+ return;
++ }
+
+ /* strip the nci data header */
+ skb_pull(skb, NCI_DATA_HDR_SIZE);
+diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
+index 4e70df91d0f2a..fc5b374fe5686 100644
+--- a/net/openvswitch/conntrack.c
++++ b/net/openvswitch/conntrack.c
+@@ -152,7 +152,7 @@ static u8 ovs_ct_get_state(enum ip_conntrack_info ctinfo)
+ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
+ {
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+- return ct ? ct->mark : 0;
++ return ct ? READ_ONCE(ct->mark) : 0;
+ #else
+ return 0;
+ #endif
+@@ -340,9 +340,9 @@ static int ovs_ct_set_mark(struct nf_conn *ct, struct sw_flow_key *key,
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+ u32 new_mark;
+
+- new_mark = ct_mark | (ct->mark & ~(mask));
+- if (ct->mark != new_mark) {
+- ct->mark = new_mark;
++ new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask));
++ if (READ_ONCE(ct->mark) != new_mark) {
++ WRITE_ONCE(ct->mark, new_mark);
+ if (nf_ct_is_confirmed(ct))
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ key->ct.mark = new_mark;
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 62c70709d7980..e0123efa2a623 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -399,6 +399,7 @@ enum rxrpc_conn_proto_state {
+ struct rxrpc_bundle {
+ struct rxrpc_conn_parameters params;
+ refcount_t ref;
++ atomic_t active; /* Number of active users */
+ unsigned int debug_id;
+ bool try_upgrade; /* True if the bundle is attempting upgrade */
+ bool alloc_conn; /* True if someone's getting a conn */
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 3c9eeb5b750c1..bdb335cb2d057 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -40,6 +40,8 @@ __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
+ DEFINE_IDR(rxrpc_client_conn_ids);
+ static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
+
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
++
+ /*
+ * Get a connection ID and epoch for a client connection from the global pool.
+ * The connection struct pointer is then recorded in the idr radix tree. The
+@@ -123,6 +125,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+ bundle->params = *cp;
+ rxrpc_get_peer(bundle->params.peer);
+ refcount_set(&bundle->ref, 1);
++ atomic_set(&bundle->active, 1);
+ spin_lock_init(&bundle->channel_lock);
+ INIT_LIST_HEAD(&bundle->waiting_calls);
+ }
+@@ -149,7 +152,7 @@ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+
+ dead = __refcount_dec_and_test(&bundle->ref, &r);
+
+- _debug("PUT B=%x %d", d, r);
++ _debug("PUT B=%x %d", d, r - 1);
+ if (dead)
+ rxrpc_free_bundle(bundle);
+ }
+@@ -338,6 +341,7 @@ found_bundle_free:
+ rxrpc_free_bundle(candidate);
+ found_bundle:
+ rxrpc_get_bundle(bundle);
++ atomic_inc(&bundle->active);
+ spin_unlock(&local->client_bundles_lock);
+ _leave(" = %u [found]", bundle->debug_id);
+ return bundle;
+@@ -435,6 +439,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
+ if (old)
+ trace_rxrpc_client(old, -1, rxrpc_client_replace);
+ candidate->bundle_shift = shift;
++ atomic_inc(&bundle->active);
+ bundle->conns[i] = candidate;
+ for (j = 0; j < RXRPC_MAXCALLS; j++)
+ set_bit(shift + j, &bundle->avail_chans);
+@@ -725,6 +730,7 @@ granted_channel:
+ smp_rmb();
+
+ out_put_bundle:
++ rxrpc_deactivate_bundle(bundle);
+ rxrpc_put_bundle(bundle);
+ out:
+ _leave(" = %d", ret);
+@@ -900,9 +906,8 @@ out:
+ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ {
+ struct rxrpc_bundle *bundle = conn->bundle;
+- struct rxrpc_local *local = bundle->params.local;
+ unsigned int bindex;
+- bool need_drop = false, need_put = false;
++ bool need_drop = false;
+ int i;
+
+ _enter("C=%x", conn->debug_id);
+@@ -921,15 +926,22 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ }
+ spin_unlock(&bundle->channel_lock);
+
+- /* If there are no more connections, remove the bundle */
+- if (!bundle->avail_chans) {
+- _debug("maybe unbundle");
+- spin_lock(&local->client_bundles_lock);
++ if (need_drop) {
++ rxrpc_deactivate_bundle(bundle);
++ rxrpc_put_connection(conn);
++ }
++}
+
+- for (i = 0; i < ARRAY_SIZE(bundle->conns); i++)
+- if (bundle->conns[i])
+- break;
+- if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) {
++/*
++ * Drop the active count on a bundle.
++ */
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
++{
++ struct rxrpc_local *local = bundle->params.local;
++ bool need_put = false;
++
++ if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
++ if (!bundle->params.exclusive) {
+ _debug("erase bundle");
+ rb_erase(&bundle->local_node, &local->client_bundles);
+ need_put = true;
+@@ -939,10 +951,6 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ if (need_put)
+ rxrpc_put_bundle(bundle);
+ }
+-
+- if (need_drop)
+- rxrpc_put_connection(conn);
+- _leave("");
+ }
+
+ /*
+diff --git a/net/sched/Kconfig b/net/sched/Kconfig
+index 1e8ab4749c6c3..4662a6ce8a7e7 100644
+--- a/net/sched/Kconfig
++++ b/net/sched/Kconfig
+@@ -976,7 +976,7 @@ config NET_ACT_TUNNEL_KEY
+
+ config NET_ACT_CT
+ tristate "connection tracking tc action"
+- depends on NET_CLS_ACT && NF_CONNTRACK && NF_NAT && NF_FLOW_TABLE
++ depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
+ help
+ Say Y here to allow sending the packets to conntrack module.
+
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 09e2aafc8943b..0deb4e96a6c2e 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -62,7 +62,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+
+ c = nf_ct_get(skb, &ctinfo);
+ if (c) {
+- skb->mark = c->mark;
++ skb->mark = READ_ONCE(c->mark);
+ /* using overlimits stats to count how many packets marked */
+ ca->tcf_qstats.overlimits++;
+ goto out;
+@@ -82,7 +82,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+ c = nf_ct_tuplehash_to_ctrack(thash);
+ /* using overlimits stats to count how many packets marked */
+ ca->tcf_qstats.overlimits++;
+- skb->mark = c->mark;
++ skb->mark = READ_ONCE(c->mark);
+ nf_ct_put(c);
+
+ out:
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index 5950974ae8f64..a015915e5b726 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -178,7 +178,7 @@ static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct,
+ entry = tcf_ct_flow_table_flow_action_get_next(action);
+ entry->id = FLOW_ACTION_CT_METADATA;
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+- entry->ct_metadata.mark = ct->mark;
++ entry->ct_metadata.mark = READ_ONCE(ct->mark);
+ #endif
+ ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED :
+ IP_CT_ESTABLISHED_REPLY;
+@@ -940,9 +940,9 @@ static void tcf_ct_act_set_mark(struct nf_conn *ct, u32 mark, u32 mask)
+ if (!mask)
+ return;
+
+- new_mark = mark | (ct->mark & ~(mask));
+- if (ct->mark != new_mark) {
+- ct->mark = new_mark;
++ new_mark = mark | (READ_ONCE(ct->mark) & ~(mask));
++ if (READ_ONCE(ct->mark) != new_mark) {
++ WRITE_ONCE(ct->mark, new_mark);
+ if (nf_ct_is_confirmed(ct))
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ }
+diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c
+index 0281e45987a47..65a20f3c9514e 100644
+--- a/net/sched/act_ctinfo.c
++++ b/net/sched/act_ctinfo.c
+@@ -33,7 +33,7 @@ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ {
+ u8 dscp, newdscp;
+
+- newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
++ newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
+ ~INET_ECN_MASK;
+
+ switch (proto) {
+@@ -73,7 +73,7 @@ static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ struct sk_buff *skb)
+ {
+ ca->stats_cpmark_set++;
+- skb->mark = ct->mark & cp->cpmarkmask;
++ skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask;
+ }
+
+ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -131,7 +131,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+ }
+
+ if (cp->mode & CTINFO_MODE_DSCP)
+- if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask))
++ if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask))
+ tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto);
+
+ if (cp->mode & CTINFO_MODE_CPMARK)
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index e8630707901e3..e8dcdf267c0c3 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
+ u32 self;
+ int err;
+
+- skb_linearize(skb);
++ if (skb_linearize(skb)) {
++ kfree_skb(skb);
++ return;
++ }
+ hdr = buf_msg(skb);
+
+ if (caps & TIPC_NODE_ID128)
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index d92ec92f0b71d..e3b427a703980 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
+ conn_put(con);
+ }
+
+-static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
++static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
+ {
+ struct tipc_conn *con;
+ int ret;
+@@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
+ }
+ con->conid = ret;
+ s->idr_in_use++;
+- spin_unlock_bh(&s->idr_lock);
+
+ set_bit(CF_CONNECTED, &con->flags);
+ con->server = s;
++ con->sock = sock;
++ conn_get(con);
++ spin_unlock_bh(&s->idr_lock);
+
+ return con;
+ }
+@@ -467,7 +469,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+ if (ret < 0)
+ return;
+- con = tipc_conn_alloc(srv);
++ con = tipc_conn_alloc(srv, newsock);
+ if (IS_ERR(con)) {
+ ret = PTR_ERR(con);
+ sock_release(newsock);
+@@ -479,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ newsk->sk_data_ready = tipc_conn_data_ready;
+ newsk->sk_write_space = tipc_conn_write_space;
+ newsk->sk_user_data = con;
+- con->sock = newsock;
+ write_unlock_bh(&newsk->sk_callback_lock);
+
+ /* Wake up receive process in case of 'SYN+' message */
+ newsk->sk_data_ready(newsk);
++ conn_put(con);
+ }
+ }
+
+@@ -577,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+ sub.filter = filter;
+ *(u64 *)&sub.usr_handle = (u64)port;
+
+- con = tipc_conn_alloc(tipc_topsrv(net));
++ con = tipc_conn_alloc(tipc_topsrv(net), NULL);
+ if (IS_ERR(con))
+ return false;
+
+ *conid = con->conid;
+- con->sock = NULL;
+ rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
+- if (rc >= 0)
+- return true;
++ if (rc)
++ conn_put(con);
++
+ conn_put(con);
+- return false;
++ return !rc;
+ }
+
+ void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 775836f6785ab..450d609b512a1 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1555,10 +1555,12 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate)
+ tmp = result;
+ tmp *= SCALE;
+ do_div(tmp, mcs_divisors[rate->mcs]);
+- result = tmp;
+
+ /* and take NSS */
+- result = (result * rate->nss) / 8;
++ tmp *= rate->nss;
++ do_div(tmp, 8);
++
++ result = tmp;
+
+ return result / 10000;
+ }
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 637ca88384368..9af6bf1652e48 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -97,6 +97,18 @@ static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
+ }
+ }
+
++static inline bool xmit_xfrm_check_overflow(struct sk_buff *skb)
++{
++ struct xfrm_offload *xo = xfrm_offload(skb);
++ __u32 seq = xo->seq.low;
++
++ seq += skb_shinfo(skb)->gso_segs;
++ if (unlikely(seq < xo->seq.low))
++ return true;
++
++ return false;
++}
++
+ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
+ {
+ int err;
+@@ -134,7 +146,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ return skb;
+ }
+
+- if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
++ if (skb_is_gso(skb) && (unlikely(x->xso.dev != dev) ||
++ unlikely(xmit_xfrm_check_overflow(skb)))) {
+ struct sk_buff *segs;
+
+ /* Packet got rerouted, fixup features and segment it. */
+diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
+index 9277d81b344cb..49dd788859d8b 100644
+--- a/net/xfrm/xfrm_replay.c
++++ b/net/xfrm/xfrm_replay.c
+@@ -714,7 +714,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
+ oseq += skb_shinfo(skb)->gso_segs;
+ }
+
+- if (unlikely(oseq < replay_esn->oseq)) {
++ if (unlikely(xo->seq.low < replay_esn->oseq)) {
+ XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
+ xo->seq.hi = oseq_hi;
+ replay_esn->oseq_hi = oseq_hi;
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index b9eb3208f2888..ae31bb1275940 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -320,6 +320,11 @@ static const struct config_entry config_table[] = {
+ {}
+ }
+ },
++ {
++ .flags = FLAG_SOF,
++ .device = 0x34c8,
++ .codec_hid = &essx_83x6,
++ },
+ {
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x34c8,
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 6c0f1de10429a..d9715bea965e1 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -206,6 +206,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
++ }
++ },
+ {}
+ };
+
+diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h
+index d0efc5e254ae9..da0ed74758b05 100644
+--- a/sound/soc/codecs/hdac_hda.h
++++ b/sound/soc/codecs/hdac_hda.h
+@@ -14,7 +14,7 @@ enum {
+ HDAC_HDMI_1_DAI_ID,
+ HDAC_HDMI_2_DAI_ID,
+ HDAC_HDMI_3_DAI_ID,
+- HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID,
++ HDAC_DAI_ID_NUM
+ };
+
+ struct hdac_hda_pcm {
+@@ -24,7 +24,7 @@ struct hdac_hda_pcm {
+
+ struct hdac_hda_priv {
+ struct hda_codec codec;
+- struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID];
++ struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM];
+ bool need_display_power;
+ };
+
+diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c
+index 3e04c7f0cce43..ec0905df65d18 100644
+--- a/sound/soc/codecs/max98373-i2c.c
++++ b/sound/soc/codecs/max98373-i2c.c
+@@ -549,6 +549,10 @@ static int max98373_i2c_probe(struct i2c_client *i2c)
+ max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num,
+ sizeof(*max98373->cache),
+ GFP_KERNEL);
++ if (!max98373->cache) {
++ ret = -ENOMEM;
++ return ret;
++ }
+
+ for (i = 0; i < max98373->cache_num; i++)
+ max98373->cache[i].reg = max98373_i2c_cache_reg[i];
+diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
+index 3fafd9fc5cfd6..75a45ad55aa87 100644
+--- a/sound/soc/codecs/sgtl5000.c
++++ b/sound/soc/codecs/sgtl5000.c
+@@ -1794,6 +1794,7 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
+ {
+ struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
+
++ regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT);
+ regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT);
+ regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT);
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 6432b83f616f3..a935c5fd9edbc 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -443,6 +443,13 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
+ | BYT_CHT_ES8316_INTMIC_IN2_MAP
+ | BYT_CHT_ES8316_JD_INVERTED),
+ },
++ { /* Nanote UMPC-01 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++ },
++ .driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP,
++ },
+ { /* Teclast X98 Plus II */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
+index 606cc3242a60f..5c218a39ca201 100644
+--- a/sound/soc/intel/boards/sof_es8336.c
++++ b/sound/soc/intel/boards/sof_es8336.c
+@@ -63,6 +63,7 @@ struct sof_es8336_private {
+ struct snd_soc_jack jack;
+ struct list_head hdmi_pcm_list;
+ bool speaker_en;
++ struct delayed_work pcm_pop_work;
+ };
+
+ struct sof_hdmi_pcm {
+@@ -111,6 +112,46 @@ static void log_quirks(struct device *dev)
+ dev_info(dev, "quirk headset at mic1 port enabled\n");
+ }
+
++static void pcm_pop_work_events(struct work_struct *work)
++{
++ struct sof_es8336_private *priv =
++ container_of(work, struct sof_es8336_private, pcm_pop_work.work);
++
++ gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
++
++ if (quirk & SOF_ES8336_HEADPHONE_GPIO)
++ gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
++
++}
++
++static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct snd_soc_card *card = rtd->card;
++ struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ break;
++
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_STOP:
++ if (priv->speaker_en == false)
++ if (substream->stream == 0) {
++ cancel_delayed_work(&priv->pcm_pop_work);
++ gpiod_set_value_cansleep(priv->gpio_speakers, true);
++ }
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -122,19 +163,7 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+
+ priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
+
+- if (SND_SOC_DAPM_EVENT_ON(event))
+- msleep(70);
+-
+- gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
+-
+- if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
+- return 0;
+-
+- if (SND_SOC_DAPM_EVENT_ON(event))
+- msleep(70);
+-
+- gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
+-
++ queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70));
+ return 0;
+ }
+
+@@ -344,6 +373,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream,
+ /* machine stream operations */
+ static struct snd_soc_ops sof_es8336_ops = {
+ .hw_params = sof_es8336_hw_params,
++ .trigger = sof_8336_trigger,
+ };
+
+ static struct snd_soc_dai_link_component platform_component[] = {
+@@ -722,7 +752,8 @@ static int sof_es8336_probe(struct platform_device *pdev)
+ }
+
+ INIT_LIST_HEAD(&priv->hdmi_pcm_list);
+-
++ INIT_DELAYED_WORK(&priv->pcm_pop_work,
++ pcm_pop_work_events);
+ snd_soc_card_set_drvdata(card, priv);
+
+ if (mach->mach_params.dmic_num > 0) {
+@@ -751,6 +782,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+
++ cancel_delayed_work(&priv->pcm_pop_work);
+ gpiod_put(priv->gpio_speakers);
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
+diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+index b032bc07de8bf..d0062f2cd2566 100644
+--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
++++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+@@ -10,6 +10,11 @@
+ #include <sound/soc-acpi-intel-match.h>
+ #include "../skylake/skl.h"
+
++static const struct snd_soc_acpi_codecs essx_83x6 = {
++ .num_codecs = 3,
++ .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
++};
++
+ static struct skl_machine_pdata icl_pdata = {
+ .use_tplg_pcm = true,
+ };
+@@ -27,6 +32,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
+ .drv_name = "sof_rt5682",
+ .sof_tplg_filename = "sof-icl-rt5682.tplg",
+ },
++ {
++ .comp_ids = &essx_83x6,
++ .drv_name = "sof-essx8336",
++ .sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */
++ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
++ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
++ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
++ },
+ {},
+ };
+ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 4d9b91e7e14f1..f6a996f0f9c74 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -800,11 +800,6 @@ static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd,
+ ret = snd_soc_dai_startup(dai, substream);
+ if (ret < 0)
+ goto err;
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- dai->tx_mask = 0;
+- else
+- dai->rx_mask = 0;
+ }
+
+ /* Dynamic PCM DAI links compat checks use dynamic capabilities */
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index a39b43850f0ed..bf8a46463cec7 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -2242,6 +2242,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
+ struct snd_sof_widget *swidget;
+ struct snd_sof_route *sroute;
++ bool dyn_widgets = false;
+ int ret;
+
+ /*
+@@ -2251,12 +2252,14 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ * topology loading the sound card unavailable to open PCMs.
+ */
+ list_for_each_entry(swidget, &sdev->widget_list, list) {
+- if (swidget->dynamic_pipeline_widget)
++ if (swidget->dynamic_pipeline_widget) {
++ dyn_widgets = true;
+ continue;
++ }
+
+- /* Do not free widgets for static pipelines with FW ABI older than 3.19 */
++ /* Do not free widgets for static pipelines with FW older than SOF2.2 */
+ if (!verify && !swidget->dynamic_pipeline_widget &&
+- v->abi_version < SOF_ABI_VER(3, 19, 0)) {
++ SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
+ swidget->use_count = 0;
+ swidget->complete = 0;
+ continue;
+@@ -2270,9 +2273,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ /*
+ * Tear down all pipelines associated with PCMs that did not get suspended
+ * and unset the prepare flag so that they can be set up again during resume.
+- * Skip this step for older firmware.
++ * Skip this step for older firmware unless topology has any
++ * dynamic pipeline (in which case the step is mandatory).
+ */
+- if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) {
++ if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >=
++ SOF_FW_VER(2, 2, 0))) {
+ ret = sof_tear_down_left_over_pipelines(sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to tear down paused pipelines\n");
+diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
+index 643fc8a170184..837c1848d9bff 100644
+--- a/sound/soc/stm/stm32_adfsdm.c
++++ b/sound/soc/stm/stm32_adfsdm.c
+@@ -304,6 +304,11 @@ static int stm32_adfsdm_dummy_cb(const void *data, void *private)
+ return 0;
+ }
+
++static void stm32_adfsdm_cleanup(void *data)
++{
++ iio_channel_release_all_cb(data);
++}
++
+ static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
+ .open = stm32_adfsdm_pcm_open,
+ .close = stm32_adfsdm_pcm_close,
+@@ -350,6 +355,12 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->iio_cb))
+ return PTR_ERR(priv->iio_cb);
+
++ ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "Unable to add action\n");
++ return ret;
++ }
++
+ component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
+ if (!component)
+ return -ENOMEM;
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index 2420dc994632a..4c9ea13f72d48 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -923,7 +923,8 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n",
+ ep->ep_num, ep->opened);
+
+- if (!--ep->iface_ref->opened)
++ if (!--ep->iface_ref->opened &&
++ !(chip->quirk_flags & QUIRK_FLAG_IFACE_SKIP_CLOSE))
+ endpoint_set_interface(chip, ep, false);
+
+ if (!--ep->opened) {
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 250bda7cda075..4f914dce6bbf9 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2186,6 +2186,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+ DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
+ QUIRK_FLAG_GENERIC_IMPLICIT_FB),
++ DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
++ QUIRK_FLAG_IFACE_SKIP_CLOSE),
+
+ /* Vendor matches */
+ VENDOR_FLG(0x045e, /* MS Lifecam */
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index 2c6575029b1cd..e97141ef730ad 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -170,6 +170,8 @@ extern bool snd_usb_skip_validation;
+ * Apply the generic implicit feedback sync mode (same as implicit_fb=1 option)
+ * QUIRK_FLAG_SKIP_IMPLICIT_FB
+ * Don't apply implicit feedback sync mode
++ * QUIRK_FLAG_IFACE_SKIP_CLOSE
++ * Don't closed interface during setting sample rate
+ */
+
+ #define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0)
+@@ -191,5 +193,6 @@ extern bool snd_usb_skip_validation;
+ #define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16)
+ #define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17)
+ #define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18)
++#define QUIRK_FLAG_IFACE_SKIP_CLOSE (1U << 19)
+
+ #endif /* __USBAUDIO_H */
+diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
+index 2491c54a5e4fb..f8deae4e26a15 100644
+--- a/tools/iio/iio_generic_buffer.c
++++ b/tools/iio/iio_generic_buffer.c
+@@ -715,12 +715,12 @@ int main(int argc, char **argv)
+ continue;
+ }
+
+- toread = buf_len;
+ } else {
+ usleep(timedelay);
+- toread = 64;
+ }
+
++ toread = buf_len;
++
+ read_size = read(buf_fd, data, toread * scan_size);
+ if (read_size < 0) {
+ if (errno == EAGAIN) {
+diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+index 57a83d763ec17..6dc65b2501ed2 100644
+--- a/tools/testing/selftests/bpf/verifier/ref_tracking.c
++++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+@@ -905,3 +905,39 @@
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "unknown func",
+ },
++{
++ "reference tracking: try to leak released ptr reg",
++ .insns = {
++ BPF_MOV64_IMM(BPF_REG_0, 0),
++ BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
++ BPF_LD_MAP_FD(BPF_REG_1, 0),
++ BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
++ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++ BPF_EXIT_INSN(),
++ BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
++
++ BPF_MOV64_IMM(BPF_REG_0, 0),
++ BPF_LD_MAP_FD(BPF_REG_1, 0),
++ BPF_MOV64_IMM(BPF_REG_2, 8),
++ BPF_MOV64_IMM(BPF_REG_3, 0),
++ BPF_EMIT_CALL(BPF_FUNC_ringbuf_reserve),
++ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++ BPF_EXIT_INSN(),
++ BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
++
++ BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
++ BPF_MOV64_IMM(BPF_REG_2, 0),
++ BPF_EMIT_CALL(BPF_FUNC_ringbuf_discard),
++ BPF_MOV64_IMM(BPF_REG_0, 0),
++
++ BPF_STX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0),
++ BPF_EXIT_INSN()
++ },
++ .fixup_map_array_48b = { 4 },
++ .fixup_map_ringbuf = { 11 },
++ .result = ACCEPT,
++ .result_unpriv = REJECT,
++ .errstr_unpriv = "R8 !read_ok"
++},
+diff --git a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+index 32aa6e9dacc26..9ac4456d48fcc 100755
+--- a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
++++ b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+@@ -29,7 +29,7 @@ if [[ "$#" -eq "0" ]]; then
+ for IP in "${IPs[@]}"; do
+ for mode in $(seq 1 3); do
+ $0 "$IP" udp -m "$mode" -t 1 -n 32
+- $0 "$IP" tcp -m "$mode" -t 1 -n 32
++ $0 "$IP" tcp -m "$mode" -t 1 -n 1
+ done
+ done
+
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+index ff83ef426df52..e52b794401239 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -2105,7 +2105,7 @@ remove_tests()
+ pm_nl_set_limits $ns2 1 3
+ pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
+ pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
+- run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
++ run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 speed_10
+ chk_join_nr 3 3 3
+ chk_add_nr 1 1
+ chk_rm_nr 2 2
+@@ -2118,7 +2118,7 @@ remove_tests()
+ pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
+ pm_nl_set_limits $ns2 3 3
+- run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++ run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ chk_join_nr 3 3 3
+ chk_add_nr 3 3
+ chk_rm_nr 3 3 invert
+@@ -2131,7 +2131,7 @@ remove_tests()
+ pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
+ pm_nl_set_limits $ns2 3 3
+- run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++ run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ chk_join_nr 1 1 1
+ chk_add_nr 3 3
+ chk_rm_nr 3 1 invert
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+index 0879da915014f..80d36f7cfee8a 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+@@ -35,8 +35,9 @@ init()
+
+ ns1="ns1-$rndh"
+ ns2="ns2-$rndh"
++ ns_sbox="ns_sbox-$rndh"
+
+- for netns in "$ns1" "$ns2";do
++ for netns in "$ns1" "$ns2" "$ns_sbox";do
+ ip netns add $netns || exit $ksft_skip
+ ip -net $netns link set lo up
+ ip netns exec $netns sysctl -q net.mptcp.enabled=1
+@@ -73,7 +74,7 @@ init()
+
+ cleanup()
+ {
+- for netns in "$ns1" "$ns2"; do
++ for netns in "$ns1" "$ns2" "$ns_sbox"; do
+ ip netns del $netns
+ done
+ rm -f "$cin" "$cout"
+@@ -243,7 +244,7 @@ do_mptcp_sockopt_tests()
+ {
+ local lret=0
+
+- ./mptcp_sockopt
++ ip netns exec "$ns_sbox" ./mptcp_sockopt
+ lret=$?
+
+ if [ $lret -ne 0 ]; then
+@@ -252,7 +253,7 @@ do_mptcp_sockopt_tests()
+ return
+ fi
+
+- ./mptcp_sockopt -6
++ ip netns exec "$ns_sbox" ./mptcp_sockopt -6
+ lret=$?
+
+ if [ $lret -ne 0 ]; then
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index ffa13a957a363..40aeb5a71a2a6 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -247,9 +247,10 @@ run_test()
+ tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
+ tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
+
+- # time is measured in ms, account for transfer size, affegated link speed
++ # time is measured in ms, account for transfer size, aggregated link speed
+ # and header overhead (10%)
+- local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
++ # ms byte -> bit 10% mbit -> kbit -> bit 10%
++ local time=$((1000 * size * 8 * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) ))
+
+ # mptcp_connect will do some sleeps to allow the mp_join handshake
+ # completion (see mptcp_connect): 200ms on each side, add some slack
+diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
+index ebbd0b2824327..6a443ca3cd3a4 100755
+--- a/tools/testing/selftests/net/udpgro.sh
++++ b/tools/testing/selftests/net/udpgro.sh
+@@ -50,7 +50,7 @@ run_one() {
+ echo "failed" &
+
+ # Hack: let bg programs complete the startup
+- sleep 0.1
++ sleep 0.2
+ ./udpgso_bench_tx ${tx_args}
+ ret=$?
+ wait $(jobs -p)
+@@ -117,7 +117,7 @@ run_one_2sock() {
+ echo "failed" &
+
+ # Hack: let bg programs complete the startup
+- sleep 0.1
++ sleep 0.2
+ ./udpgso_bench_tx ${tx_args} -p 12345
+ sleep 0.1
+ # first UDP GSO socket should be closed at this point
+diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh
+index fad2d1a71cac3..8a1109a545dba 100755
+--- a/tools/testing/selftests/net/udpgro_bench.sh
++++ b/tools/testing/selftests/net/udpgro_bench.sh
+@@ -39,7 +39,7 @@ run_one() {
+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
+
+ # Hack: let bg programs complete the startup
+- sleep 0.1
++ sleep 0.2
+ ./udpgso_bench_tx ${tx_args}
+ }
+
+diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh
+index 832c738cc3c29..7fe85ba51075d 100755
+--- a/tools/testing/selftests/net/udpgro_frglist.sh
++++ b/tools/testing/selftests/net/udpgro_frglist.sh
+@@ -44,7 +44,7 @@ run_one() {
+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
+
+ # Hack: let bg programs complete the startup
+- sleep 0.1
++ sleep 0.2
+ ./udpgso_bench_tx ${tx_args}
+ }
+
+diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
+index 346e47f155724..7c248193ca26e 100644
+--- a/virt/kvm/pfncache.c
++++ b/virt/kvm/pfncache.c
+@@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ if (!gpc->valid || old_uhva != gpc->uhva) {
+ ret = hva_to_pfn_retry(kvm, gpc);
+ } else {
+- /* If the HVA→PFN mapping was already valid, don't unmap it. */
++ /*
++ * If the HVA→PFN mapping was already valid, don't unmap it.
++ * But do update gpc->khva because the offset within the page
++ * may have changed.
++ */
++ gpc->khva = old_khva + page_offset;
+ old_pfn = KVM_PFN_ERR_FAULT;
+ old_khva = NULL;
+ ret = 0;
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-06 13:00 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-06 13:00 UTC (permalink / raw
To: gentoo-commits
commit: d88f68a1c45be889061120a9d1a196424496f78d
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 6 13:00:01 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Dec 6 13:00:01 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=d88f68a1
Add the BMQ(BitMap Queue) Scheduler (USE=experiemental)
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 3 +
5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch | 10036 ++++++++++++++++++++++++++
2 files changed, 10039 insertions(+)
diff --git a/0000_README b/0000_README
index 12c46dfc..5f75f686 100644
--- a/0000_README
+++ b/0000_README
@@ -127,3 +127,6 @@ Patch: 5010_enable-cpu-optimizations-universal.patch
From: https://github.com/graysky2/kernel_compiler_patch
Desc: Kernel >= 5.15 patch enables gcc = v11.1+ optimizations for additional CPUs.
+Patch: 5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
+From: https://gitlab.com/alfredchen/projectc
+Desc: BMQ(BitMap Queue) Scheduler. A new CPU scheduler developed from PDS(incld). Inspired by the scheduler in zircon.
diff --git a/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch b/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
new file mode 100644
index 00000000..e0ebdb65
--- /dev/null
+++ b/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
@@ -0,0 +1,10036 @@
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 426fa892d311..43b06e44128c 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -5385,6 +5385,12 @@
+ sa1100ir [NET]
+ See drivers/net/irda/sa1100_ir.c.
+
++ sched_timeslice=
++ [KNL] Time slice in ms for Project C BMQ/PDS scheduler.
++ Format: integer 2, 4
++ Default: 4
++ See Documentation/scheduler/sched-BMQ.txt
++
+ sched_verbose [KNL] Enables verbose scheduler debug messages.
+
+ schedstats= [KNL,X86] Enable or disable scheduled statistics.
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index ee6572b1edad..5d3e6ce49e23 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -1536,3 +1536,13 @@ is 10 seconds.
+
+ The softlockup threshold is (``2 * watchdog_thresh``). Setting this
+ tunable to zero will disable lockup detection altogether.
++
++yield_type:
++===========
++
++BMQ/PDS CPU scheduler only. This determines what type of yield calls
++to sched_yield will perform.
++
++ 0 - No yield.
++ 1 - Deboost and requeue task. (default)
++ 2 - Set run queue skip task.
+diff --git a/Documentation/scheduler/sched-BMQ.txt b/Documentation/scheduler/sched-BMQ.txt
+new file mode 100644
+index 000000000000..05c84eec0f31
+--- /dev/null
++++ b/Documentation/scheduler/sched-BMQ.txt
+@@ -0,0 +1,110 @@
++ BitMap queue CPU Scheduler
++ --------------------------
++
++CONTENT
++========
++
++ Background
++ Design
++ Overview
++ Task policy
++ Priority management
++ BitMap Queue
++ CPU Assignment and Migration
++
++
++Background
++==========
++
++BitMap Queue CPU scheduler, referred to as BMQ from here on, is an evolution
++of previous Priority and Deadline based Skiplist multiple queue scheduler(PDS),
++and inspired by Zircon scheduler. The goal of it is to keep the scheduler code
++simple, while efficiency and scalable for interactive tasks, such as desktop,
++movie playback and gaming etc.
++
++Design
++======
++
++Overview
++--------
++
++BMQ use per CPU run queue design, each CPU(logical) has it's own run queue,
++each CPU is responsible for scheduling the tasks that are putting into it's
++run queue.
++
++The run queue is a set of priority queues. Note that these queues are fifo
++queue for non-rt tasks or priority queue for rt tasks in data structure. See
++BitMap Queue below for details. BMQ is optimized for non-rt tasks in the fact
++that most applications are non-rt tasks. No matter the queue is fifo or
++priority, In each queue is an ordered list of runnable tasks awaiting execution
++and the data structures are the same. When it is time for a new task to run,
++the scheduler simply looks the lowest numbered queueue that contains a task,
++and runs the first task from the head of that queue. And per CPU idle task is
++also in the run queue, so the scheduler can always find a task to run on from
++its run queue.
++
++Each task will assigned the same timeslice(default 4ms) when it is picked to
++start running. Task will be reinserted at the end of the appropriate priority
++queue when it uses its whole timeslice. When the scheduler selects a new task
++from the priority queue it sets the CPU's preemption timer for the remainder of
++the previous timeslice. When that timer fires the scheduler will stop execution
++on that task, select another task and start over again.
++
++If a task blocks waiting for a shared resource then it's taken out of its
++priority queue and is placed in a wait queue for the shared resource. When it
++is unblocked it will be reinserted in the appropriate priority queue of an
++eligible CPU.
++
++Task policy
++-----------
++
++BMQ supports DEADLINE, FIFO, RR, NORMAL, BATCH and IDLE task policy like the
++mainline CFS scheduler. But BMQ is heavy optimized for non-rt task, that's
++NORMAL/BATCH/IDLE policy tasks. Below is the implementation detail of each
++policy.
++
++DEADLINE
++ It is squashed as priority 0 FIFO task.
++
++FIFO/RR
++ All RT tasks share one single priority queue in BMQ run queue designed. The
++complexity of insert operation is O(n). BMQ is not designed for system runs
++with major rt policy tasks.
++
++NORMAL/BATCH/IDLE
++ BATCH and IDLE tasks are treated as the same policy. They compete CPU with
++NORMAL policy tasks, but they just don't boost. To control the priority of
++NORMAL/BATCH/IDLE tasks, simply use nice level.
++
++ISO
++ ISO policy is not supported in BMQ. Please use nice level -20 NORMAL policy
++task instead.
++
++Priority management
++-------------------
++
++RT tasks have priority from 0-99. For non-rt tasks, there are three different
++factors used to determine the effective priority of a task. The effective
++priority being what is used to determine which queue it will be in.
++
++The first factor is simply the task’s static priority. Which is assigned from
++task's nice level, within [-20, 19] in userland's point of view and [0, 39]
++internally.
++
++The second factor is the priority boost. This is a value bounded between
++[-MAX_PRIORITY_ADJ, MAX_PRIORITY_ADJ] used to offset the base priority, it is
++modified by the following cases:
++
++*When a thread has used up its entire timeslice, always deboost its boost by
++increasing by one.
++*When a thread gives up cpu control(voluntary or non-voluntary) to reschedule,
++and its switch-in time(time after last switch and run) below the thredhold
++based on its priority boost, will boost its boost by decreasing by one buti is
++capped at 0 (won’t go negative).
++
++The intent in this system is to ensure that interactive threads are serviced
++quickly. These are usually the threads that interact directly with the user
++and cause user-perceivable latency. These threads usually do little work and
++spend most of their time blocked awaiting another user event. So they get the
++priority boost from unblocking while background threads that do most of the
++processing receive the priority penalty for using their entire timeslice.
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 93f7e3d971e4..8cdeb0d9048c 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -479,7 +479,7 @@ static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
+ seq_puts(m, "0 0 0\n");
+ else
+ seq_printf(m, "%llu %llu %lu\n",
+- (unsigned long long)task->se.sum_exec_runtime,
++ (unsigned long long)tsk_seruntime(task),
+ (unsigned long long)task->sched_info.run_delay,
+ task->sched_info.pcount);
+
+diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h
+index 8874f681b056..59eb72bf7d5f 100644
+--- a/include/asm-generic/resource.h
++++ b/include/asm-generic/resource.h
+@@ -23,7 +23,7 @@
+ [RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \
+ [RLIMIT_SIGPENDING] = { 0, 0 }, \
+ [RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+- [RLIMIT_NICE] = { 0, 0 }, \
++ [RLIMIT_NICE] = { 30, 30 }, \
+ [RLIMIT_RTPRIO] = { 0, 0 }, \
+ [RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY }, \
+ }
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index e7b2f8a5c711..9e3742ad8f32 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -752,8 +752,14 @@ struct task_struct {
+ unsigned int ptrace;
+
+ #ifdef CONFIG_SMP
+- int on_cpu;
+ struct __call_single_node wake_entry;
++#endif
++#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_ALT)
++ int on_cpu;
++#endif
++
++#ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ unsigned int wakee_flips;
+ unsigned long wakee_flip_decay_ts;
+ struct task_struct *last_wakee;
+@@ -767,6 +773,7 @@ struct task_struct {
+ */
+ int recent_used_cpu;
+ int wake_cpu;
++#endif /* !CONFIG_SCHED_ALT */
+ #endif
+ int on_rq;
+
+@@ -775,6 +782,20 @@ struct task_struct {
+ int normal_prio;
+ unsigned int rt_priority;
+
++#ifdef CONFIG_SCHED_ALT
++ u64 last_ran;
++ s64 time_slice;
++ int sq_idx;
++ struct list_head sq_node;
++#ifdef CONFIG_SCHED_BMQ
++ int boost_prio;
++#endif /* CONFIG_SCHED_BMQ */
++#ifdef CONFIG_SCHED_PDS
++ u64 deadline;
++#endif /* CONFIG_SCHED_PDS */
++ /* sched_clock time spent running */
++ u64 sched_time;
++#else /* !CONFIG_SCHED_ALT */
+ struct sched_entity se;
+ struct sched_rt_entity rt;
+ struct sched_dl_entity dl;
+@@ -785,6 +806,7 @@ struct task_struct {
+ unsigned long core_cookie;
+ unsigned int core_occupation;
+ #endif
++#endif /* !CONFIG_SCHED_ALT */
+
+ #ifdef CONFIG_CGROUP_SCHED
+ struct task_group *sched_task_group;
+@@ -1529,6 +1551,15 @@ struct task_struct {
+ */
+ };
+
++#ifdef CONFIG_SCHED_ALT
++#define tsk_seruntime(t) ((t)->sched_time)
++/* replace the uncertian rt_timeout with 0UL */
++#define tsk_rttimeout(t) (0UL)
++#else /* CFS */
++#define tsk_seruntime(t) ((t)->se.sum_exec_runtime)
++#define tsk_rttimeout(t) ((t)->rt.timeout)
++#endif /* !CONFIG_SCHED_ALT */
++
+ static inline struct pid *task_pid(struct task_struct *task)
+ {
+ return task->thread_pid;
+diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
+index 7c83d4d5a971..fa30f98cb2be 100644
+--- a/include/linux/sched/deadline.h
++++ b/include/linux/sched/deadline.h
+@@ -1,5 +1,24 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+
++#ifdef CONFIG_SCHED_ALT
++
++static inline int dl_task(struct task_struct *p)
++{
++ return 0;
++}
++
++#ifdef CONFIG_SCHED_BMQ
++#define __tsk_deadline(p) (0UL)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++#define __tsk_deadline(p) ((((u64) ((p)->prio))<<56) | (p)->deadline)
++#endif
++
++#else
++
++#define __tsk_deadline(p) ((p)->dl.deadline)
++
+ /*
+ * SCHED_DEADLINE tasks has negative priorities, reflecting
+ * the fact that any of them has higher prio than RT and
+@@ -21,6 +40,7 @@ static inline int dl_task(struct task_struct *p)
+ {
+ return dl_prio(p->prio);
+ }
++#endif /* CONFIG_SCHED_ALT */
+
+ static inline bool dl_time_before(u64 a, u64 b)
+ {
+diff --git a/include/linux/sched/prio.h b/include/linux/sched/prio.h
+index ab83d85e1183..6af9ae681116 100644
+--- a/include/linux/sched/prio.h
++++ b/include/linux/sched/prio.h
+@@ -18,6 +18,32 @@
+ #define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
+ #define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
+
++#ifdef CONFIG_SCHED_ALT
++
++/* Undefine MAX_PRIO and DEFAULT_PRIO */
++#undef MAX_PRIO
++#undef DEFAULT_PRIO
++
++/* +/- priority levels from the base priority */
++#ifdef CONFIG_SCHED_BMQ
++#define MAX_PRIORITY_ADJ (7)
++
++#define MIN_NORMAL_PRIO (MAX_RT_PRIO)
++#define MAX_PRIO (MIN_NORMAL_PRIO + NICE_WIDTH)
++#define DEFAULT_PRIO (MIN_NORMAL_PRIO + NICE_WIDTH / 2)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++#define MAX_PRIORITY_ADJ (0)
++
++#define MIN_NORMAL_PRIO (128)
++#define NORMAL_PRIO_NUM (64)
++#define MAX_PRIO (MIN_NORMAL_PRIO + NORMAL_PRIO_NUM)
++#define DEFAULT_PRIO (MAX_PRIO - NICE_WIDTH / 2)
++#endif
++
++#endif /* CONFIG_SCHED_ALT */
++
+ /*
+ * Convert user-nice values [ -20 ... 0 ... 19 ]
+ * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
+diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h
+index 994c25640e15..8c050a59ece1 100644
+--- a/include/linux/sched/rt.h
++++ b/include/linux/sched/rt.h
+@@ -24,8 +24,10 @@ static inline bool task_is_realtime(struct task_struct *tsk)
+
+ if (policy == SCHED_FIFO || policy == SCHED_RR)
+ return true;
++#ifndef CONFIG_SCHED_ALT
+ if (policy == SCHED_DEADLINE)
+ return true;
++#endif
+ return false;
+ }
+
+diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
+index 816df6cc444e..c8da08e18c91 100644
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -234,7 +234,8 @@ static inline bool cpus_share_cache(int this_cpu, int that_cpu)
+
+ #endif /* !CONFIG_SMP */
+
+-#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
++#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) && \
++ !defined(CONFIG_SCHED_ALT)
+ extern void rebuild_sched_domains_energy(void);
+ #else
+ static inline void rebuild_sched_domains_energy(void)
+diff --git a/init/Kconfig b/init/Kconfig
+index 532362fcfe31..2bf9e67b73c9 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -808,6 +808,7 @@ menu "Scheduler features"
+ config UCLAMP_TASK
+ bool "Enable utilization clamping for RT/FAIR tasks"
+ depends on CPU_FREQ_GOV_SCHEDUTIL
++ depends on !SCHED_ALT
+ help
+ This feature enables the scheduler to track the clamped utilization
+ of each CPU based on RUNNABLE tasks scheduled on that CPU.
+@@ -854,6 +855,35 @@ config UCLAMP_BUCKETS_COUNT
+
+ If in doubt, use the default value.
+
++menuconfig SCHED_ALT
++ bool "Alternative CPU Schedulers"
++ default y
++ help
++ This feature enable alternative CPU scheduler"
++
++if SCHED_ALT
++
++choice
++ prompt "Alternative CPU Scheduler"
++ default SCHED_BMQ
++
++config SCHED_BMQ
++ bool "BMQ CPU scheduler"
++ help
++ The BitMap Queue CPU scheduler for excellent interactivity and
++ responsiveness on the desktop and solid scalability on normal
++ hardware and commodity servers.
++
++config SCHED_PDS
++ bool "PDS CPU scheduler"
++ help
++ The Priority and Deadline based Skip list multiple queue CPU
++ Scheduler.
++
++endchoice
++
++endif
++
+ endmenu
+
+ #
+@@ -907,6 +937,7 @@ config NUMA_BALANCING
+ depends on ARCH_SUPPORTS_NUMA_BALANCING
+ depends on !ARCH_WANT_NUMA_VARIABLE_LOCALITY
+ depends on SMP && NUMA && MIGRATION && !PREEMPT_RT
++ depends on !SCHED_ALT
+ help
+ This option adds support for automatic NUMA aware memory/task placement.
+ The mechanism is quite primitive and is based on migrating memory when
+@@ -1009,6 +1040,7 @@ config FAIR_GROUP_SCHED
+ depends on CGROUP_SCHED
+ default CGROUP_SCHED
+
++if !SCHED_ALT
+ config CFS_BANDWIDTH
+ bool "CPU bandwidth provisioning for FAIR_GROUP_SCHED"
+ depends on FAIR_GROUP_SCHED
+@@ -1031,6 +1063,7 @@ config RT_GROUP_SCHED
+ realtime bandwidth for them.
+ See Documentation/scheduler/sched-rt-group.rst for more information.
+
++endif #!SCHED_ALT
+ endif #CGROUP_SCHED
+
+ config UCLAMP_TASK_GROUP
+@@ -1274,6 +1307,7 @@ config CHECKPOINT_RESTORE
+
+ config SCHED_AUTOGROUP
+ bool "Automatic process group scheduling"
++ depends on !SCHED_ALT
+ select CGROUPS
+ select CGROUP_SCHED
+ select FAIR_GROUP_SCHED
+diff --git a/init/init_task.c b/init/init_task.c
+index ff6c4b9bfe6b..19e9c662d1a1 100644
+--- a/init/init_task.c
++++ b/init/init_task.c
+@@ -75,9 +75,15 @@ struct task_struct init_task
+ .stack = init_stack,
+ .usage = REFCOUNT_INIT(2),
+ .flags = PF_KTHREAD,
++#ifdef CONFIG_SCHED_ALT
++ .prio = DEFAULT_PRIO + MAX_PRIORITY_ADJ,
++ .static_prio = DEFAULT_PRIO,
++ .normal_prio = DEFAULT_PRIO + MAX_PRIORITY_ADJ,
++#else
+ .prio = MAX_PRIO - 20,
+ .static_prio = MAX_PRIO - 20,
+ .normal_prio = MAX_PRIO - 20,
++#endif
+ .policy = SCHED_NORMAL,
+ .cpus_ptr = &init_task.cpus_mask,
+ .user_cpus_ptr = NULL,
+@@ -88,6 +94,17 @@ struct task_struct init_task
+ .restart_block = {
+ .fn = do_no_restart_syscall,
+ },
++#ifdef CONFIG_SCHED_ALT
++ .sq_node = LIST_HEAD_INIT(init_task.sq_node),
++#ifdef CONFIG_SCHED_BMQ
++ .boost_prio = 0,
++ .sq_idx = 15,
++#endif
++#ifdef CONFIG_SCHED_PDS
++ .deadline = 0,
++#endif
++ .time_slice = HZ,
++#else
+ .se = {
+ .group_node = LIST_HEAD_INIT(init_task.se.group_node),
+ },
+@@ -95,6 +112,7 @@ struct task_struct init_task
+ .run_list = LIST_HEAD_INIT(init_task.rt.run_list),
+ .time_slice = RR_TIMESLICE,
+ },
++#endif
+ .tasks = LIST_HEAD_INIT(init_task.tasks),
+ #ifdef CONFIG_SMP
+ .pushable_tasks = PLIST_NODE_INIT(init_task.pushable_tasks, MAX_PRIO),
+diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
+index c2f1fd95a821..41654679b1b2 100644
+--- a/kernel/Kconfig.preempt
++++ b/kernel/Kconfig.preempt
+@@ -117,7 +117,7 @@ config PREEMPT_DYNAMIC
+
+ config SCHED_CORE
+ bool "Core Scheduling for SMT"
+- depends on SCHED_SMT
++ depends on SCHED_SMT && !SCHED_ALT
+ help
+ This option permits Core Scheduling, a means of coordinated task
+ selection across SMT siblings. When enabled -- see
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 1f3a55297f39..a7ce153c6f91 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -704,7 +704,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
+ return ret;
+ }
+
+-#ifdef CONFIG_SMP
++#if defined(CONFIG_SMP) && !defined(CONFIG_SCHED_ALT)
+ /*
+ * Helper routine for generate_sched_domains().
+ * Do cpusets a, b have overlapping effective cpus_allowed masks?
+@@ -1100,7 +1100,7 @@ static void rebuild_sched_domains_locked(void)
+ /* Have scheduler rebuild the domains */
+ partition_and_rebuild_sched_domains(ndoms, doms, attr);
+ }
+-#else /* !CONFIG_SMP */
++#else /* !CONFIG_SMP || CONFIG_SCHED_ALT */
+ static void rebuild_sched_domains_locked(void)
+ {
+ }
+diff --git a/kernel/delayacct.c b/kernel/delayacct.c
+index 164ed9ef77a3..c974a84b056f 100644
+--- a/kernel/delayacct.c
++++ b/kernel/delayacct.c
+@@ -150,7 +150,7 @@ int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
+ */
+ t1 = tsk->sched_info.pcount;
+ t2 = tsk->sched_info.run_delay;
+- t3 = tsk->se.sum_exec_runtime;
++ t3 = tsk_seruntime(tsk);
+
+ d->cpu_count += t1;
+
+diff --git a/kernel/exit.c b/kernel/exit.c
+index 84021b24f79e..a9b77bf74eec 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -124,7 +124,7 @@ static void __exit_signal(struct task_struct *tsk)
+ sig->curr_target = next_thread(tsk);
+ }
+
+- add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
++ add_device_randomness((const void*) &tsk_seruntime(tsk),
+ sizeof(unsigned long long));
+
+ /*
+@@ -145,7 +145,7 @@ static void __exit_signal(struct task_struct *tsk)
+ sig->inblock += task_io_get_inblock(tsk);
+ sig->oublock += task_io_get_oublock(tsk);
+ task_io_accounting_add(&sig->ioac, &tsk->ioac);
+- sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
++ sig->sum_sched_runtime += tsk_seruntime(tsk);
+ sig->nr_threads--;
+ __unhash_process(tsk, group_dead);
+ write_sequnlock(&sig->stats_lock);
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 7779ee8abc2a..5b9893cdfb1b 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -300,21 +300,25 @@ static __always_inline void
+ waiter_update_prio(struct rt_mutex_waiter *waiter, struct task_struct *task)
+ {
+ waiter->prio = __waiter_prio(task);
+- waiter->deadline = task->dl.deadline;
++ waiter->deadline = __tsk_deadline(task);
+ }
+
+ /*
+ * Only use with rt_mutex_waiter_{less,equal}()
+ */
+ #define task_to_waiter(p) \
+- &(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline }
++ &(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = __tsk_deadline(p) }
+
+ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,
+ struct rt_mutex_waiter *right)
+ {
++#ifdef CONFIG_SCHED_PDS
++ return (left->deadline < right->deadline);
++#else
+ if (left->prio < right->prio)
+ return 1;
+
++#ifndef CONFIG_SCHED_BMQ
+ /*
+ * If both waiters have dl_prio(), we check the deadlines of the
+ * associated tasks.
+@@ -323,16 +327,22 @@ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,
+ */
+ if (dl_prio(left->prio))
+ return dl_time_before(left->deadline, right->deadline);
++#endif
+
+ return 0;
++#endif
+ }
+
+ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,
+ struct rt_mutex_waiter *right)
+ {
++#ifdef CONFIG_SCHED_PDS
++ return (left->deadline == right->deadline);
++#else
+ if (left->prio != right->prio)
+ return 0;
+
++#ifndef CONFIG_SCHED_BMQ
+ /*
+ * If both waiters have dl_prio(), we check the deadlines of the
+ * associated tasks.
+@@ -341,8 +351,10 @@ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,
+ */
+ if (dl_prio(left->prio))
+ return left->deadline == right->deadline;
++#endif
+
+ return 1;
++#endif
+ }
+
+ static inline bool rt_mutex_steal(struct rt_mutex_waiter *waiter,
+diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
+index 976092b7bd45..31d587c16ec1 100644
+--- a/kernel/sched/Makefile
++++ b/kernel/sched/Makefile
+@@ -28,7 +28,12 @@ endif
+ # These compilation units have roughly the same size and complexity - so their
+ # build parallelizes well and finishes roughly at once:
+ #
++ifdef CONFIG_SCHED_ALT
++obj-y += alt_core.o
++obj-$(CONFIG_SCHED_DEBUG) += alt_debug.o
++else
+ obj-y += core.o
+ obj-y += fair.o
++endif
+ obj-y += build_policy.o
+ obj-y += build_utility.o
+diff --git a/kernel/sched/alt_core.c b/kernel/sched/alt_core.c
+new file mode 100644
+index 000000000000..03e3956194f7
+--- /dev/null
++++ b/kernel/sched/alt_core.c
+@@ -0,0 +1,7887 @@
++/*
++ * kernel/sched/alt_core.c
++ *
++ * Core alternative kernel scheduler code and related syscalls
++ *
++ * Copyright (C) 1991-2002 Linus Torvalds
++ *
++ * 2009-08-13 Brainfuck deadline scheduling policy by Con Kolivas deletes
++ * a whole lot of those previous things.
++ * 2017-09-06 Priority and Deadline based Skip list multiple queue kernel
++ * scheduler by Alfred Chen.
++ * 2019-02-20 BMQ(BitMap Queue) kernel scheduler by Alfred Chen.
++ */
++#include <linux/sched/cputime.h>
++#include <linux/sched/debug.h>
++#include <linux/sched/isolation.h>
++#include <linux/sched/loadavg.h>
++#include <linux/sched/mm.h>
++#include <linux/sched/nohz.h>
++#include <linux/sched/stat.h>
++#include <linux/sched/wake_q.h>
++
++#include <linux/blkdev.h>
++#include <linux/context_tracking.h>
++#include <linux/cpuset.h>
++#include <linux/delayacct.h>
++#include <linux/init_task.h>
++#include <linux/kcov.h>
++#include <linux/kprobes.h>
++#include <linux/profile.h>
++#include <linux/nmi.h>
++#include <linux/scs.h>
++
++#include <uapi/linux/sched/types.h>
++
++#include <asm/switch_to.h>
++
++#define CREATE_TRACE_POINTS
++#include <trace/events/sched.h>
++#undef CREATE_TRACE_POINTS
++
++#include "sched.h"
++
++#include "pelt.h"
++
++#include "../../io_uring/io-wq.h"
++#include "../smpboot.h"
++
++/*
++ * Export tracepoints that act as a bare tracehook (ie: have no trace event
++ * associated with them) to allow external modules to probe them.
++ */
++EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_irq_tp);
++
++#ifdef CONFIG_SCHED_DEBUG
++#define sched_feat(x) (1)
++/*
++ * Print a warning if need_resched is set for the given duration (if
++ * LATENCY_WARN is enabled).
++ *
++ * If sysctl_resched_latency_warn_once is set, only one warning will be shown
++ * per boot.
++ */
++__read_mostly int sysctl_resched_latency_warn_ms = 100;
++__read_mostly int sysctl_resched_latency_warn_once = 1;
++#else
++#define sched_feat(x) (0)
++#endif /* CONFIG_SCHED_DEBUG */
++
++#define ALT_SCHED_VERSION "v6.0-r0"
++
++/* rt_prio(prio) defined in include/linux/sched/rt.h */
++#define rt_task(p) rt_prio((p)->prio)
++#define rt_policy(policy) ((policy) == SCHED_FIFO || (policy) == SCHED_RR)
++#define task_has_rt_policy(p) (rt_policy((p)->policy))
++
++#define STOP_PRIO (MAX_RT_PRIO - 1)
++
++/* Default time slice is 4 in ms, can be set via kernel parameter "sched_timeslice" */
++u64 sched_timeslice_ns __read_mostly = (4 << 20);
++
++static inline void requeue_task(struct task_struct *p, struct rq *rq, int idx);
++
++#ifdef CONFIG_SCHED_BMQ
++#include "bmq.h"
++#endif
++#ifdef CONFIG_SCHED_PDS
++#include "pds.h"
++#endif
++
++static int __init sched_timeslice(char *str)
++{
++ int timeslice_ms;
++
++ get_option(&str, ×lice_ms);
++ if (2 != timeslice_ms)
++ timeslice_ms = 4;
++ sched_timeslice_ns = timeslice_ms << 20;
++ sched_timeslice_imp(timeslice_ms);
++
++ return 0;
++}
++early_param("sched_timeslice", sched_timeslice);
++
++/* Reschedule if less than this many μs left */
++#define RESCHED_NS (100 << 10)
++
++/**
++ * sched_yield_type - Choose what sort of yield sched_yield will perform.
++ * 0: No yield.
++ * 1: Deboost and requeue task. (default)
++ * 2: Set rq skip task.
++ */
++int sched_yield_type __read_mostly = 1;
++
++#ifdef CONFIG_SMP
++static cpumask_t sched_rq_pending_mask ____cacheline_aligned_in_smp;
++
++DEFINE_PER_CPU(cpumask_t [NR_CPU_AFFINITY_LEVELS], sched_cpu_topo_masks);
++DEFINE_PER_CPU(cpumask_t *, sched_cpu_llc_mask);
++DEFINE_PER_CPU(cpumask_t *, sched_cpu_topo_end_mask);
++
++#ifdef CONFIG_SCHED_SMT
++DEFINE_STATIC_KEY_FALSE(sched_smt_present);
++EXPORT_SYMBOL_GPL(sched_smt_present);
++#endif
++
++/*
++ * Keep a unique ID per domain (we use the first CPUs number in the cpumask of
++ * the domain), this allows us to quickly tell if two cpus are in the same cache
++ * domain, see cpus_share_cache().
++ */
++DEFINE_PER_CPU(int, sd_llc_id);
++#endif /* CONFIG_SMP */
++
++static DEFINE_MUTEX(sched_hotcpu_mutex);
++
++DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++
++#ifndef prepare_arch_switch
++# define prepare_arch_switch(next) do { } while (0)
++#endif
++#ifndef finish_arch_post_lock_switch
++# define finish_arch_post_lock_switch() do { } while (0)
++#endif
++
++#ifdef CONFIG_SCHED_SMT
++static cpumask_t sched_sg_idle_mask ____cacheline_aligned_in_smp;
++#endif
++static cpumask_t sched_rq_watermark[SCHED_QUEUE_BITS] ____cacheline_aligned_in_smp;
++
++/* sched_queue related functions */
++static inline void sched_queue_init(struct sched_queue *q)
++{
++ int i;
++
++ bitmap_zero(q->bitmap, SCHED_QUEUE_BITS);
++ for(i = 0; i < SCHED_BITS; i++)
++ INIT_LIST_HEAD(&q->heads[i]);
++}
++
++/*
++ * Init idle task and put into queue structure of rq
++ * IMPORTANT: may be called multiple times for a single cpu
++ */
++static inline void sched_queue_init_idle(struct sched_queue *q,
++ struct task_struct *idle)
++{
++ idle->sq_idx = IDLE_TASK_SCHED_PRIO;
++ INIT_LIST_HEAD(&q->heads[idle->sq_idx]);
++ list_add(&idle->sq_node, &q->heads[idle->sq_idx]);
++}
++
++/* water mark related functions */
++static inline void update_sched_rq_watermark(struct rq *rq)
++{
++ unsigned long watermark = find_first_bit(rq->queue.bitmap, SCHED_QUEUE_BITS);
++ unsigned long last_wm = rq->watermark;
++ unsigned long i;
++ int cpu;
++
++ if (watermark == last_wm)
++ return;
++
++ rq->watermark = watermark;
++ cpu = cpu_of(rq);
++ if (watermark < last_wm) {
++ for (i = last_wm; i > watermark; i--)
++ cpumask_clear_cpu(cpu, sched_rq_watermark + SCHED_QUEUE_BITS - i);
++#ifdef CONFIG_SCHED_SMT
++ if (static_branch_likely(&sched_smt_present) &&
++ IDLE_TASK_SCHED_PRIO == last_wm)
++ cpumask_andnot(&sched_sg_idle_mask,
++ &sched_sg_idle_mask, cpu_smt_mask(cpu));
++#endif
++ return;
++ }
++ /* last_wm < watermark */
++ for (i = watermark; i > last_wm; i--)
++ cpumask_set_cpu(cpu, sched_rq_watermark + SCHED_QUEUE_BITS - i);
++#ifdef CONFIG_SCHED_SMT
++ if (static_branch_likely(&sched_smt_present) &&
++ IDLE_TASK_SCHED_PRIO == watermark) {
++ cpumask_t tmp;
++
++ cpumask_and(&tmp, cpu_smt_mask(cpu), sched_rq_watermark);
++ if (cpumask_equal(&tmp, cpu_smt_mask(cpu)))
++ cpumask_or(&sched_sg_idle_mask,
++ &sched_sg_idle_mask, cpu_smt_mask(cpu));
++ }
++#endif
++}
++
++/*
++ * This routine assume that the idle task always in queue
++ */
++static inline struct task_struct *sched_rq_first_task(struct rq *rq)
++{
++ unsigned long idx = find_first_bit(rq->queue.bitmap, SCHED_QUEUE_BITS);
++ const struct list_head *head = &rq->queue.heads[sched_prio2idx(idx, rq)];
++
++ return list_first_entry(head, struct task_struct, sq_node);
++}
++
++static inline struct task_struct *
++sched_rq_next_task(struct task_struct *p, struct rq *rq)
++{
++ unsigned long idx = p->sq_idx;
++ struct list_head *head = &rq->queue.heads[idx];
++
++ if (list_is_last(&p->sq_node, head)) {
++ idx = find_next_bit(rq->queue.bitmap, SCHED_QUEUE_BITS,
++ sched_idx2prio(idx, rq) + 1);
++ head = &rq->queue.heads[sched_prio2idx(idx, rq)];
++
++ return list_first_entry(head, struct task_struct, sq_node);
++ }
++
++ return list_next_entry(p, sq_node);
++}
++
++static inline struct task_struct *rq_runnable_task(struct rq *rq)
++{
++ struct task_struct *next = sched_rq_first_task(rq);
++
++ if (unlikely(next == rq->skip))
++ next = sched_rq_next_task(next, rq);
++
++ return next;
++}
++
++/*
++ * Serialization rules:
++ *
++ * Lock order:
++ *
++ * p->pi_lock
++ * rq->lock
++ * hrtimer_cpu_base->lock (hrtimer_start() for bandwidth controls)
++ *
++ * rq1->lock
++ * rq2->lock where: rq1 < rq2
++ *
++ * Regular state:
++ *
++ * Normal scheduling state is serialized by rq->lock. __schedule() takes the
++ * local CPU's rq->lock, it optionally removes the task from the runqueue and
++ * always looks at the local rq data structures to find the most eligible task
++ * to run next.
++ *
++ * Task enqueue is also under rq->lock, possibly taken from another CPU.
++ * Wakeups from another LLC domain might use an IPI to transfer the enqueue to
++ * the local CPU to avoid bouncing the runqueue state around [ see
++ * ttwu_queue_wakelist() ]
++ *
++ * Task wakeup, specifically wakeups that involve migration, are horribly
++ * complicated to avoid having to take two rq->locks.
++ *
++ * Special state:
++ *
++ * System-calls and anything external will use task_rq_lock() which acquires
++ * both p->pi_lock and rq->lock. As a consequence the state they change is
++ * stable while holding either lock:
++ *
++ * - sched_setaffinity()/
++ * set_cpus_allowed_ptr(): p->cpus_ptr, p->nr_cpus_allowed
++ * - set_user_nice(): p->se.load, p->*prio
++ * - __sched_setscheduler(): p->sched_class, p->policy, p->*prio,
++ * p->se.load, p->rt_priority,
++ * p->dl.dl_{runtime, deadline, period, flags, bw, density}
++ * - sched_setnuma(): p->numa_preferred_nid
++ * - sched_move_task()/
++ * cpu_cgroup_fork(): p->sched_task_group
++ * - uclamp_update_active() p->uclamp*
++ *
++ * p->state <- TASK_*:
++ *
++ * is changed locklessly using set_current_state(), __set_current_state() or
++ * set_special_state(), see their respective comments, or by
++ * try_to_wake_up(). This latter uses p->pi_lock to serialize against
++ * concurrent self.
++ *
++ * p->on_rq <- { 0, 1 = TASK_ON_RQ_QUEUED, 2 = TASK_ON_RQ_MIGRATING }:
++ *
++ * is set by activate_task() and cleared by deactivate_task(), under
++ * rq->lock. Non-zero indicates the task is runnable, the special
++ * ON_RQ_MIGRATING state is used for migration without holding both
++ * rq->locks. It indicates task_cpu() is not stable, see task_rq_lock().
++ *
++ * p->on_cpu <- { 0, 1 }:
++ *
++ * is set by prepare_task() and cleared by finish_task() such that it will be
++ * set before p is scheduled-in and cleared after p is scheduled-out, both
++ * under rq->lock. Non-zero indicates the task is running on its CPU.
++ *
++ * [ The astute reader will observe that it is possible for two tasks on one
++ * CPU to have ->on_cpu = 1 at the same time. ]
++ *
++ * task_cpu(p): is changed by set_task_cpu(), the rules are:
++ *
++ * - Don't call set_task_cpu() on a blocked task:
++ *
++ * We don't care what CPU we're not running on, this simplifies hotplug,
++ * the CPU assignment of blocked tasks isn't required to be valid.
++ *
++ * - for try_to_wake_up(), called under p->pi_lock:
++ *
++ * This allows try_to_wake_up() to only take one rq->lock, see its comment.
++ *
++ * - for migration called under rq->lock:
++ * [ see task_on_rq_migrating() in task_rq_lock() ]
++ *
++ * o move_queued_task()
++ * o detach_task()
++ *
++ * - for migration called under double_rq_lock():
++ *
++ * o __migrate_swap_task()
++ * o push_rt_task() / pull_rt_task()
++ * o push_dl_task() / pull_dl_task()
++ * o dl_task_offline_migration()
++ *
++ */
++
++/*
++ * Context: p->pi_lock
++ */
++static inline struct rq
++*__task_access_lock(struct task_struct *p, raw_spinlock_t **plock)
++{
++ struct rq *rq;
++ for (;;) {
++ rq = task_rq(p);
++ if (p->on_cpu || task_on_rq_queued(p)) {
++ raw_spin_lock(&rq->lock);
++ if (likely((p->on_cpu || task_on_rq_queued(p))
++ && rq == task_rq(p))) {
++ *plock = &rq->lock;
++ return rq;
++ }
++ raw_spin_unlock(&rq->lock);
++ } else if (task_on_rq_migrating(p)) {
++ do {
++ cpu_relax();
++ } while (unlikely(task_on_rq_migrating(p)));
++ } else {
++ *plock = NULL;
++ return rq;
++ }
++ }
++}
++
++static inline void
++__task_access_unlock(struct task_struct *p, raw_spinlock_t *lock)
++{
++ if (NULL != lock)
++ raw_spin_unlock(lock);
++}
++
++static inline struct rq
++*task_access_lock_irqsave(struct task_struct *p, raw_spinlock_t **plock,
++ unsigned long *flags)
++{
++ struct rq *rq;
++ for (;;) {
++ rq = task_rq(p);
++ if (p->on_cpu || task_on_rq_queued(p)) {
++ raw_spin_lock_irqsave(&rq->lock, *flags);
++ if (likely((p->on_cpu || task_on_rq_queued(p))
++ && rq == task_rq(p))) {
++ *plock = &rq->lock;
++ return rq;
++ }
++ raw_spin_unlock_irqrestore(&rq->lock, *flags);
++ } else if (task_on_rq_migrating(p)) {
++ do {
++ cpu_relax();
++ } while (unlikely(task_on_rq_migrating(p)));
++ } else {
++ raw_spin_lock_irqsave(&p->pi_lock, *flags);
++ if (likely(!p->on_cpu && !p->on_rq &&
++ rq == task_rq(p))) {
++ *plock = &p->pi_lock;
++ return rq;
++ }
++ raw_spin_unlock_irqrestore(&p->pi_lock, *flags);
++ }
++ }
++}
++
++static inline void
++task_access_unlock_irqrestore(struct task_struct *p, raw_spinlock_t *lock,
++ unsigned long *flags)
++{
++ raw_spin_unlock_irqrestore(lock, *flags);
++}
++
++/*
++ * __task_rq_lock - lock the rq @p resides on.
++ */
++struct rq *__task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++ __acquires(rq->lock)
++{
++ struct rq *rq;
++
++ lockdep_assert_held(&p->pi_lock);
++
++ for (;;) {
++ rq = task_rq(p);
++ raw_spin_lock(&rq->lock);
++ if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
++ return rq;
++ raw_spin_unlock(&rq->lock);
++
++ while (unlikely(task_on_rq_migrating(p)))
++ cpu_relax();
++ }
++}
++
++/*
++ * task_rq_lock - lock p->pi_lock and lock the rq @p resides on.
++ */
++struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++ __acquires(p->pi_lock)
++ __acquires(rq->lock)
++{
++ struct rq *rq;
++
++ for (;;) {
++ raw_spin_lock_irqsave(&p->pi_lock, rf->flags);
++ rq = task_rq(p);
++ raw_spin_lock(&rq->lock);
++ /*
++ * move_queued_task() task_rq_lock()
++ *
++ * ACQUIRE (rq->lock)
++ * [S] ->on_rq = MIGRATING [L] rq = task_rq()
++ * WMB (__set_task_cpu()) ACQUIRE (rq->lock);
++ * [S] ->cpu = new_cpu [L] task_rq()
++ * [L] ->on_rq
++ * RELEASE (rq->lock)
++ *
++ * If we observe the old CPU in task_rq_lock(), the acquire of
++ * the old rq->lock will fully serialize against the stores.
++ *
++ * If we observe the new CPU in task_rq_lock(), the address
++ * dependency headed by '[L] rq = task_rq()' and the acquire
++ * will pair with the WMB to ensure we then also see migrating.
++ */
++ if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) {
++ return rq;
++ }
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, rf->flags);
++
++ while (unlikely(task_on_rq_migrating(p)))
++ cpu_relax();
++ }
++}
++
++static inline void
++rq_lock_irqsave(struct rq *rq, struct rq_flags *rf)
++ __acquires(rq->lock)
++{
++ raw_spin_lock_irqsave(&rq->lock, rf->flags);
++}
++
++static inline void
++rq_unlock_irqrestore(struct rq *rq, struct rq_flags *rf)
++ __releases(rq->lock)
++{
++ raw_spin_unlock_irqrestore(&rq->lock, rf->flags);
++}
++
++void raw_spin_rq_lock_nested(struct rq *rq, int subclass)
++{
++ raw_spinlock_t *lock;
++
++ /* Matches synchronize_rcu() in __sched_core_enable() */
++ preempt_disable();
++
++ for (;;) {
++ lock = __rq_lockp(rq);
++ raw_spin_lock_nested(lock, subclass);
++ if (likely(lock == __rq_lockp(rq))) {
++ /* preempt_count *MUST* be > 1 */
++ preempt_enable_no_resched();
++ return;
++ }
++ raw_spin_unlock(lock);
++ }
++}
++
++void raw_spin_rq_unlock(struct rq *rq)
++{
++ raw_spin_unlock(rq_lockp(rq));
++}
++
++/*
++ * RQ-clock updating methods:
++ */
++
++static void update_rq_clock_task(struct rq *rq, s64 delta)
++{
++/*
++ * In theory, the compile should just see 0 here, and optimize out the call
++ * to sched_rt_avg_update. But I don't trust it...
++ */
++ s64 __maybe_unused steal = 0, irq_delta = 0;
++
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++ irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
++
++ /*
++ * Since irq_time is only updated on {soft,}irq_exit, we might run into
++ * this case when a previous update_rq_clock() happened inside a
++ * {soft,}irq region.
++ *
++ * When this happens, we stop ->clock_task and only update the
++ * prev_irq_time stamp to account for the part that fit, so that a next
++ * update will consume the rest. This ensures ->clock_task is
++ * monotonic.
++ *
++ * It does however cause some slight miss-attribution of {soft,}irq
++ * time, a more accurate solution would be to update the irq_time using
++ * the current rq->clock timestamp, except that would require using
++ * atomic ops.
++ */
++ if (irq_delta > delta)
++ irq_delta = delta;
++
++ rq->prev_irq_time += irq_delta;
++ delta -= irq_delta;
++#endif
++#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
++ if (static_key_false((¶virt_steal_rq_enabled))) {
++ steal = paravirt_steal_clock(cpu_of(rq));
++ steal -= rq->prev_steal_time_rq;
++
++ if (unlikely(steal > delta))
++ steal = delta;
++
++ rq->prev_steal_time_rq += steal;
++ delta -= steal;
++ }
++#endif
++
++ rq->clock_task += delta;
++
++#ifdef CONFIG_HAVE_SCHED_AVG_IRQ
++ if ((irq_delta + steal))
++ update_irq_load_avg(rq, irq_delta + steal);
++#endif
++}
++
++static inline void update_rq_clock(struct rq *rq)
++{
++ s64 delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
++
++ if (unlikely(delta <= 0))
++ return;
++ rq->clock += delta;
++ update_rq_time_edge(rq);
++ update_rq_clock_task(rq, delta);
++}
++
++/*
++ * RQ Load update routine
++ */
++#define RQ_LOAD_HISTORY_BITS (sizeof(s32) * 8ULL)
++#define RQ_UTIL_SHIFT (8)
++#define RQ_LOAD_HISTORY_TO_UTIL(l) (((l) >> (RQ_LOAD_HISTORY_BITS - 1 - RQ_UTIL_SHIFT)) & 0xff)
++
++#define LOAD_BLOCK(t) ((t) >> 17)
++#define LOAD_HALF_BLOCK(t) ((t) >> 16)
++#define BLOCK_MASK(t) ((t) & ((0x01 << 18) - 1))
++#define LOAD_BLOCK_BIT(b) (1UL << (RQ_LOAD_HISTORY_BITS - 1 - (b)))
++#define CURRENT_LOAD_BIT LOAD_BLOCK_BIT(0)
++
++static inline void rq_load_update(struct rq *rq)
++{
++ u64 time = rq->clock;
++ u64 delta = min(LOAD_BLOCK(time) - LOAD_BLOCK(rq->load_stamp),
++ RQ_LOAD_HISTORY_BITS - 1);
++ u64 prev = !!(rq->load_history & CURRENT_LOAD_BIT);
++ u64 curr = !!rq->nr_running;
++
++ if (delta) {
++ rq->load_history = rq->load_history >> delta;
++
++ if (delta < RQ_UTIL_SHIFT) {
++ rq->load_block += (~BLOCK_MASK(rq->load_stamp)) * prev;
++ if (!!LOAD_HALF_BLOCK(rq->load_block) ^ curr)
++ rq->load_history ^= LOAD_BLOCK_BIT(delta);
++ }
++
++ rq->load_block = BLOCK_MASK(time) * prev;
++ } else {
++ rq->load_block += (time - rq->load_stamp) * prev;
++ }
++ if (prev ^ curr)
++ rq->load_history ^= CURRENT_LOAD_BIT;
++ rq->load_stamp = time;
++}
++
++unsigned long rq_load_util(int cpu)
++{
++ struct rq *rq;
++ unsigned long max;
++
++ rq = cpu_rq(cpu);
++ max = arch_scale_cpu_capacity(cpu);
++
++ return RQ_LOAD_HISTORY_TO_UTIL(rq->load_history) * (max >> RQ_UTIL_SHIFT);
++}
++
++#ifdef CONFIG_SMP
++unsigned long sched_cpu_util(int cpu)
++{
++ return rq_load_util(cpu);
++}
++#endif /* CONFIG_SMP */
++
++#ifdef CONFIG_CPU_FREQ
++/**
++ * cpufreq_update_util - Take a note about CPU utilization changes.
++ * @rq: Runqueue to carry out the update for.
++ * @flags: Update reason flags.
++ *
++ * This function is called by the scheduler on the CPU whose utilization is
++ * being updated.
++ *
++ * It can only be called from RCU-sched read-side critical sections.
++ *
++ * The way cpufreq is currently arranged requires it to evaluate the CPU
++ * performance state (frequency/voltage) on a regular basis to prevent it from
++ * being stuck in a completely inadequate performance level for too long.
++ * That is not guaranteed to happen if the updates are only triggered from CFS
++ * and DL, though, because they may not be coming in if only RT tasks are
++ * active all the time (or there are RT tasks only).
++ *
++ * As a workaround for that issue, this function is called periodically by the
++ * RT sched class to trigger extra cpufreq updates to prevent it from stalling,
++ * but that really is a band-aid. Going forward it should be replaced with
++ * solutions targeted more specifically at RT tasks.
++ */
++static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
++{
++ struct update_util_data *data;
++
++#ifdef CONFIG_SMP
++ rq_load_update(rq);
++#endif
++ data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
++ cpu_of(rq)));
++ if (data)
++ data->func(data, rq_clock(rq), flags);
++}
++#else
++static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
++{
++#ifdef CONFIG_SMP
++ rq_load_update(rq);
++#endif
++}
++#endif /* CONFIG_CPU_FREQ */
++
++#ifdef CONFIG_NO_HZ_FULL
++/*
++ * Tick may be needed by tasks in the runqueue depending on their policy and
++ * requirements. If tick is needed, lets send the target an IPI to kick it out
++ * of nohz mode if necessary.
++ */
++static inline void sched_update_tick_dependency(struct rq *rq)
++{
++ int cpu = cpu_of(rq);
++
++ if (!tick_nohz_full_cpu(cpu))
++ return;
++
++ if (rq->nr_running < 2)
++ tick_nohz_dep_clear_cpu(cpu, TICK_DEP_BIT_SCHED);
++ else
++ tick_nohz_dep_set_cpu(cpu, TICK_DEP_BIT_SCHED);
++}
++#else /* !CONFIG_NO_HZ_FULL */
++static inline void sched_update_tick_dependency(struct rq *rq) { }
++#endif
++
++bool sched_task_on_rq(struct task_struct *p)
++{
++ return task_on_rq_queued(p);
++}
++
++unsigned long get_wchan(struct task_struct *p)
++{
++ unsigned long ip = 0;
++ unsigned int state;
++
++ if (!p || p == current)
++ return 0;
++
++ /* Only get wchan if task is blocked and we can keep it that way. */
++ raw_spin_lock_irq(&p->pi_lock);
++ state = READ_ONCE(p->__state);
++ smp_rmb(); /* see try_to_wake_up() */
++ if (state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq)
++ ip = __get_wchan(p);
++ raw_spin_unlock_irq(&p->pi_lock);
++
++ return ip;
++}
++
++/*
++ * Add/Remove/Requeue task to/from the runqueue routines
++ * Context: rq->lock
++ */
++#define __SCHED_DEQUEUE_TASK(p, rq, flags) \
++ psi_dequeue(p, flags & DEQUEUE_SLEEP); \
++ sched_info_dequeue(rq, p); \
++ \
++ list_del(&p->sq_node); \
++ if (list_empty(&rq->queue.heads[p->sq_idx])) \
++ clear_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++
++#define __SCHED_ENQUEUE_TASK(p, rq, flags) \
++ sched_info_enqueue(rq, p); \
++ psi_enqueue(p, flags); \
++ \
++ p->sq_idx = task_sched_prio_idx(p, rq); \
++ list_add_tail(&p->sq_node, &rq->queue.heads[p->sq_idx]); \
++ set_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++
++static inline void dequeue_task(struct task_struct *p, struct rq *rq, int flags)
++{
++ lockdep_assert_held(&rq->lock);
++
++ /*printk(KERN_INFO "sched: dequeue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++ WARN_ONCE(task_rq(p) != rq, "sched: dequeue task reside on cpu%d from cpu%d\n",
++ task_cpu(p), cpu_of(rq));
++
++ __SCHED_DEQUEUE_TASK(p, rq, flags);
++ --rq->nr_running;
++#ifdef CONFIG_SMP
++ if (1 == rq->nr_running)
++ cpumask_clear_cpu(cpu_of(rq), &sched_rq_pending_mask);
++#endif
++
++ sched_update_tick_dependency(rq);
++}
++
++static inline void enqueue_task(struct task_struct *p, struct rq *rq, int flags)
++{
++ lockdep_assert_held(&rq->lock);
++
++ /*printk(KERN_INFO "sched: enqueue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++ WARN_ONCE(task_rq(p) != rq, "sched: enqueue task reside on cpu%d to cpu%d\n",
++ task_cpu(p), cpu_of(rq));
++
++ __SCHED_ENQUEUE_TASK(p, rq, flags);
++ update_sched_rq_watermark(rq);
++ ++rq->nr_running;
++#ifdef CONFIG_SMP
++ if (2 == rq->nr_running)
++ cpumask_set_cpu(cpu_of(rq), &sched_rq_pending_mask);
++#endif
++
++ sched_update_tick_dependency(rq);
++}
++
++static inline void requeue_task(struct task_struct *p, struct rq *rq, int idx)
++{
++ lockdep_assert_held(&rq->lock);
++ /*printk(KERN_INFO "sched: requeue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++ WARN_ONCE(task_rq(p) != rq, "sched: cpu[%d] requeue task reside on cpu%d\n",
++ cpu_of(rq), task_cpu(p));
++
++ list_del(&p->sq_node);
++ list_add_tail(&p->sq_node, &rq->queue.heads[idx]);
++ if (idx != p->sq_idx) {
++ if (list_empty(&rq->queue.heads[p->sq_idx]))
++ clear_bit(sched_idx2prio(p->sq_idx, rq),
++ rq->queue.bitmap);
++ p->sq_idx = idx;
++ set_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++ update_sched_rq_watermark(rq);
++ }
++}
++
++/*
++ * cmpxchg based fetch_or, macro so it works for different integer types
++ */
++#define fetch_or(ptr, mask) \
++ ({ \
++ typeof(ptr) _ptr = (ptr); \
++ typeof(mask) _mask = (mask); \
++ typeof(*_ptr) _old, _val = *_ptr; \
++ \
++ for (;;) { \
++ _old = cmpxchg(_ptr, _val, _val | _mask); \
++ if (_old == _val) \
++ break; \
++ _val = _old; \
++ } \
++ _old; \
++})
++
++#if defined(CONFIG_SMP) && defined(TIF_POLLING_NRFLAG)
++/*
++ * Atomically set TIF_NEED_RESCHED and test for TIF_POLLING_NRFLAG,
++ * this avoids any races wrt polling state changes and thereby avoids
++ * spurious IPIs.
++ */
++static bool set_nr_and_not_polling(struct task_struct *p)
++{
++ struct thread_info *ti = task_thread_info(p);
++ return !(fetch_or(&ti->flags, _TIF_NEED_RESCHED) & _TIF_POLLING_NRFLAG);
++}
++
++/*
++ * Atomically set TIF_NEED_RESCHED if TIF_POLLING_NRFLAG is set.
++ *
++ * If this returns true, then the idle task promises to call
++ * sched_ttwu_pending() and reschedule soon.
++ */
++static bool set_nr_if_polling(struct task_struct *p)
++{
++ struct thread_info *ti = task_thread_info(p);
++ typeof(ti->flags) old, val = READ_ONCE(ti->flags);
++
++ for (;;) {
++ if (!(val & _TIF_POLLING_NRFLAG))
++ return false;
++ if (val & _TIF_NEED_RESCHED)
++ return true;
++ old = cmpxchg(&ti->flags, val, val | _TIF_NEED_RESCHED);
++ if (old == val)
++ break;
++ val = old;
++ }
++ return true;
++}
++
++#else
++static bool set_nr_and_not_polling(struct task_struct *p)
++{
++ set_tsk_need_resched(p);
++ return true;
++}
++
++#ifdef CONFIG_SMP
++static bool set_nr_if_polling(struct task_struct *p)
++{
++ return false;
++}
++#endif
++#endif
++
++static bool __wake_q_add(struct wake_q_head *head, struct task_struct *task)
++{
++ struct wake_q_node *node = &task->wake_q;
++
++ /*
++ * Atomically grab the task, if ->wake_q is !nil already it means
++ * it's already queued (either by us or someone else) and will get the
++ * wakeup due to that.
++ *
++ * In order to ensure that a pending wakeup will observe our pending
++ * state, even in the failed case, an explicit smp_mb() must be used.
++ */
++ smp_mb__before_atomic();
++ if (unlikely(cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL)))
++ return false;
++
++ /*
++ * The head is context local, there can be no concurrency.
++ */
++ *head->lastp = node;
++ head->lastp = &node->next;
++ return true;
++}
++
++/**
++ * wake_q_add() - queue a wakeup for 'later' waking.
++ * @head: the wake_q_head to add @task to
++ * @task: the task to queue for 'later' wakeup
++ *
++ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
++ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
++ * instantly.
++ *
++ * This function must be used as-if it were wake_up_process(); IOW the task
++ * must be ready to be woken at this location.
++ */
++void wake_q_add(struct wake_q_head *head, struct task_struct *task)
++{
++ if (__wake_q_add(head, task))
++ get_task_struct(task);
++}
++
++/**
++ * wake_q_add_safe() - safely queue a wakeup for 'later' waking.
++ * @head: the wake_q_head to add @task to
++ * @task: the task to queue for 'later' wakeup
++ *
++ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
++ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
++ * instantly.
++ *
++ * This function must be used as-if it were wake_up_process(); IOW the task
++ * must be ready to be woken at this location.
++ *
++ * This function is essentially a task-safe equivalent to wake_q_add(). Callers
++ * that already hold reference to @task can call the 'safe' version and trust
++ * wake_q to do the right thing depending whether or not the @task is already
++ * queued for wakeup.
++ */
++void wake_q_add_safe(struct wake_q_head *head, struct task_struct *task)
++{
++ if (!__wake_q_add(head, task))
++ put_task_struct(task);
++}
++
++void wake_up_q(struct wake_q_head *head)
++{
++ struct wake_q_node *node = head->first;
++
++ while (node != WAKE_Q_TAIL) {
++ struct task_struct *task;
++
++ task = container_of(node, struct task_struct, wake_q);
++ /* task can safely be re-inserted now: */
++ node = node->next;
++ task->wake_q.next = NULL;
++
++ /*
++ * wake_up_process() executes a full barrier, which pairs with
++ * the queueing in wake_q_add() so as not to miss wakeups.
++ */
++ wake_up_process(task);
++ put_task_struct(task);
++ }
++}
++
++/*
++ * resched_curr - mark rq's current task 'to be rescheduled now'.
++ *
++ * On UP this means the setting of the need_resched flag, on SMP it
++ * might also involve a cross-CPU call to trigger the scheduler on
++ * the target CPU.
++ */
++void resched_curr(struct rq *rq)
++{
++ struct task_struct *curr = rq->curr;
++ int cpu;
++
++ lockdep_assert_held(&rq->lock);
++
++ if (test_tsk_need_resched(curr))
++ return;
++
++ cpu = cpu_of(rq);
++ if (cpu == smp_processor_id()) {
++ set_tsk_need_resched(curr);
++ set_preempt_need_resched();
++ return;
++ }
++
++ if (set_nr_and_not_polling(curr))
++ smp_send_reschedule(cpu);
++ else
++ trace_sched_wake_idle_without_ipi(cpu);
++}
++
++void resched_cpu(int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ if (cpu_online(cpu) || cpu == smp_processor_id())
++ resched_curr(cpu_rq(cpu));
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++}
++
++#ifdef CONFIG_SMP
++#ifdef CONFIG_NO_HZ_COMMON
++void nohz_balance_enter_idle(int cpu) {}
++
++void select_nohz_load_balancer(int stop_tick) {}
++
++void set_cpu_sd_state_idle(void) {}
++
++/*
++ * In the semi idle case, use the nearest busy CPU for migrating timers
++ * from an idle CPU. This is good for power-savings.
++ *
++ * We don't do similar optimization for completely idle system, as
++ * selecting an idle CPU will add more delays to the timers than intended
++ * (as that CPU's timer base may not be uptodate wrt jiffies etc).
++ */
++int get_nohz_timer_target(void)
++{
++ int i, cpu = smp_processor_id(), default_cpu = -1;
++ struct cpumask *mask;
++ const struct cpumask *hk_mask;
++
++ if (housekeeping_cpu(cpu, HK_TYPE_TIMER)) {
++ if (!idle_cpu(cpu))
++ return cpu;
++ default_cpu = cpu;
++ }
++
++ hk_mask = housekeeping_cpumask(HK_TYPE_TIMER);
++
++ for (mask = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++ mask < per_cpu(sched_cpu_topo_end_mask, cpu); mask++)
++ for_each_cpu_and(i, mask, hk_mask)
++ if (!idle_cpu(i))
++ return i;
++
++ if (default_cpu == -1)
++ default_cpu = housekeeping_any_cpu(HK_TYPE_TIMER);
++ cpu = default_cpu;
++
++ return cpu;
++}
++
++/*
++ * When add_timer_on() enqueues a timer into the timer wheel of an
++ * idle CPU then this timer might expire before the next timer event
++ * which is scheduled to wake up that CPU. In case of a completely
++ * idle system the next event might even be infinite time into the
++ * future. wake_up_idle_cpu() ensures that the CPU is woken up and
++ * leaves the inner idle loop so the newly added timer is taken into
++ * account when the CPU goes back to idle and evaluates the timer
++ * wheel for the next timer event.
++ */
++static inline void wake_up_idle_cpu(int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ if (cpu == smp_processor_id())
++ return;
++
++ if (set_nr_and_not_polling(rq->idle))
++ smp_send_reschedule(cpu);
++ else
++ trace_sched_wake_idle_without_ipi(cpu);
++}
++
++static inline bool wake_up_full_nohz_cpu(int cpu)
++{
++ /*
++ * We just need the target to call irq_exit() and re-evaluate
++ * the next tick. The nohz full kick at least implies that.
++ * If needed we can still optimize that later with an
++ * empty IRQ.
++ */
++ if (cpu_is_offline(cpu))
++ return true; /* Don't try to wake offline CPUs. */
++ if (tick_nohz_full_cpu(cpu)) {
++ if (cpu != smp_processor_id() ||
++ tick_nohz_tick_stopped())
++ tick_nohz_full_kick_cpu(cpu);
++ return true;
++ }
++
++ return false;
++}
++
++void wake_up_nohz_cpu(int cpu)
++{
++ if (!wake_up_full_nohz_cpu(cpu))
++ wake_up_idle_cpu(cpu);
++}
++
++static void nohz_csd_func(void *info)
++{
++ struct rq *rq = info;
++ int cpu = cpu_of(rq);
++ unsigned int flags;
++
++ /*
++ * Release the rq::nohz_csd.
++ */
++ flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(cpu));
++ WARN_ON(!(flags & NOHZ_KICK_MASK));
++
++ rq->idle_balance = idle_cpu(cpu);
++ if (rq->idle_balance && !need_resched()) {
++ rq->nohz_idle_balance = flags;
++ raise_softirq_irqoff(SCHED_SOFTIRQ);
++ }
++}
++
++#endif /* CONFIG_NO_HZ_COMMON */
++#endif /* CONFIG_SMP */
++
++static inline void check_preempt_curr(struct rq *rq)
++{
++ if (sched_rq_first_task(rq) != rq->curr)
++ resched_curr(rq);
++}
++
++#ifdef CONFIG_SCHED_HRTICK
++/*
++ * Use HR-timers to deliver accurate preemption points.
++ */
++
++static void hrtick_clear(struct rq *rq)
++{
++ if (hrtimer_active(&rq->hrtick_timer))
++ hrtimer_cancel(&rq->hrtick_timer);
++}
++
++/*
++ * High-resolution timer tick.
++ * Runs from hardirq context with interrupts disabled.
++ */
++static enum hrtimer_restart hrtick(struct hrtimer *timer)
++{
++ struct rq *rq = container_of(timer, struct rq, hrtick_timer);
++
++ WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
++
++ raw_spin_lock(&rq->lock);
++ resched_curr(rq);
++ raw_spin_unlock(&rq->lock);
++
++ return HRTIMER_NORESTART;
++}
++
++/*
++ * Use hrtick when:
++ * - enabled by features
++ * - hrtimer is actually high res
++ */
++static inline int hrtick_enabled(struct rq *rq)
++{
++ /**
++ * Alt schedule FW doesn't support sched_feat yet
++ if (!sched_feat(HRTICK))
++ return 0;
++ */
++ if (!cpu_active(cpu_of(rq)))
++ return 0;
++ return hrtimer_is_hres_active(&rq->hrtick_timer);
++}
++
++#ifdef CONFIG_SMP
++
++static void __hrtick_restart(struct rq *rq)
++{
++ struct hrtimer *timer = &rq->hrtick_timer;
++ ktime_t time = rq->hrtick_time;
++
++ hrtimer_start(timer, time, HRTIMER_MODE_ABS_PINNED_HARD);
++}
++
++/*
++ * called from hardirq (IPI) context
++ */
++static void __hrtick_start(void *arg)
++{
++ struct rq *rq = arg;
++
++ raw_spin_lock(&rq->lock);
++ __hrtick_restart(rq);
++ raw_spin_unlock(&rq->lock);
++}
++
++/*
++ * Called to set the hrtick timer state.
++ *
++ * called with rq->lock held and irqs disabled
++ */
++void hrtick_start(struct rq *rq, u64 delay)
++{
++ struct hrtimer *timer = &rq->hrtick_timer;
++ s64 delta;
++
++ /*
++ * Don't schedule slices shorter than 10000ns, that just
++ * doesn't make sense and can cause timer DoS.
++ */
++ delta = max_t(s64, delay, 10000LL);
++
++ rq->hrtick_time = ktime_add_ns(timer->base->get_time(), delta);
++
++ if (rq == this_rq())
++ __hrtick_restart(rq);
++ else
++ smp_call_function_single_async(cpu_of(rq), &rq->hrtick_csd);
++}
++
++#else
++/*
++ * Called to set the hrtick timer state.
++ *
++ * called with rq->lock held and irqs disabled
++ */
++void hrtick_start(struct rq *rq, u64 delay)
++{
++ /*
++ * Don't schedule slices shorter than 10000ns, that just
++ * doesn't make sense. Rely on vruntime for fairness.
++ */
++ delay = max_t(u64, delay, 10000LL);
++ hrtimer_start(&rq->hrtick_timer, ns_to_ktime(delay),
++ HRTIMER_MODE_REL_PINNED_HARD);
++}
++#endif /* CONFIG_SMP */
++
++static void hrtick_rq_init(struct rq *rq)
++{
++#ifdef CONFIG_SMP
++ INIT_CSD(&rq->hrtick_csd, __hrtick_start, rq);
++#endif
++
++ hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
++ rq->hrtick_timer.function = hrtick;
++}
++#else /* CONFIG_SCHED_HRTICK */
++static inline int hrtick_enabled(struct rq *rq)
++{
++ return 0;
++}
++
++static inline void hrtick_clear(struct rq *rq)
++{
++}
++
++static inline void hrtick_rq_init(struct rq *rq)
++{
++}
++#endif /* CONFIG_SCHED_HRTICK */
++
++static inline int __normal_prio(int policy, int rt_prio, int static_prio)
++{
++ return rt_policy(policy) ? (MAX_RT_PRIO - 1 - rt_prio) :
++ static_prio + MAX_PRIORITY_ADJ;
++}
++
++/*
++ * Calculate the expected normal priority: i.e. priority
++ * without taking RT-inheritance into account. Might be
++ * boosted by interactivity modifiers. Changes upon fork,
++ * setprio syscalls, and whenever the interactivity
++ * estimator recalculates.
++ */
++static inline int normal_prio(struct task_struct *p)
++{
++ return __normal_prio(p->policy, p->rt_priority, p->static_prio);
++}
++
++/*
++ * Calculate the current priority, i.e. the priority
++ * taken into account by the scheduler. This value might
++ * be boosted by RT tasks as it will be RT if the task got
++ * RT-boosted. If not then it returns p->normal_prio.
++ */
++static int effective_prio(struct task_struct *p)
++{
++ p->normal_prio = normal_prio(p);
++ /*
++ * If we are RT tasks or we were boosted to RT priority,
++ * keep the priority unchanged. Otherwise, update priority
++ * to the normal priority:
++ */
++ if (!rt_prio(p->prio))
++ return p->normal_prio;
++ return p->prio;
++}
++
++/*
++ * activate_task - move a task to the runqueue.
++ *
++ * Context: rq->lock
++ */
++static void activate_task(struct task_struct *p, struct rq *rq)
++{
++ enqueue_task(p, rq, ENQUEUE_WAKEUP);
++ p->on_rq = TASK_ON_RQ_QUEUED;
++
++ /*
++ * If in_iowait is set, the code below may not trigger any cpufreq
++ * utilization updates, so do it here explicitly with the IOWAIT flag
++ * passed.
++ */
++ cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT * p->in_iowait);
++}
++
++/*
++ * deactivate_task - remove a task from the runqueue.
++ *
++ * Context: rq->lock
++ */
++static inline void deactivate_task(struct task_struct *p, struct rq *rq)
++{
++ dequeue_task(p, rq, DEQUEUE_SLEEP);
++ p->on_rq = 0;
++ cpufreq_update_util(rq, 0);
++}
++
++static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
++{
++#ifdef CONFIG_SMP
++ /*
++ * After ->cpu is set up to a new value, task_access_lock(p, ...) can be
++ * successfully executed on another CPU. We must ensure that updates of
++ * per-task data have been completed by this moment.
++ */
++ smp_wmb();
++
++ WRITE_ONCE(task_thread_info(p)->cpu, cpu);
++#endif
++}
++
++static inline bool is_migration_disabled(struct task_struct *p)
++{
++#ifdef CONFIG_SMP
++ return p->migration_disabled;
++#else
++ return false;
++#endif
++}
++
++#define SCA_CHECK 0x01
++#define SCA_USER 0x08
++
++#ifdef CONFIG_SMP
++
++void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
++{
++#ifdef CONFIG_SCHED_DEBUG
++ unsigned int state = READ_ONCE(p->__state);
++
++ /*
++ * We should never call set_task_cpu() on a blocked task,
++ * ttwu() will sort out the placement.
++ */
++ WARN_ON_ONCE(state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq);
++
++#ifdef CONFIG_LOCKDEP
++ /*
++ * The caller should hold either p->pi_lock or rq->lock, when changing
++ * a task's CPU. ->pi_lock for waking tasks, rq->lock for runnable tasks.
++ *
++ * sched_move_task() holds both and thus holding either pins the cgroup,
++ * see task_group().
++ */
++ WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&p->pi_lock) ||
++ lockdep_is_held(&task_rq(p)->lock)));
++#endif
++ /*
++ * Clearly, migrating tasks to offline CPUs is a fairly daft thing.
++ */
++ WARN_ON_ONCE(!cpu_online(new_cpu));
++
++ WARN_ON_ONCE(is_migration_disabled(p));
++#endif
++ if (task_cpu(p) == new_cpu)
++ return;
++ trace_sched_migrate_task(p, new_cpu);
++ rseq_migrate(p);
++ perf_event_task_migrate(p);
++
++ __set_task_cpu(p, new_cpu);
++}
++
++#define MDF_FORCE_ENABLED 0x80
++
++static void
++__do_set_cpus_ptr(struct task_struct *p, const struct cpumask *new_mask)
++{
++ /*
++ * This here violates the locking rules for affinity, since we're only
++ * supposed to change these variables while holding both rq->lock and
++ * p->pi_lock.
++ *
++ * HOWEVER, it magically works, because ttwu() is the only code that
++ * accesses these variables under p->pi_lock and only does so after
++ * smp_cond_load_acquire(&p->on_cpu, !VAL), and we're in __schedule()
++ * before finish_task().
++ *
++ * XXX do further audits, this smells like something putrid.
++ */
++ SCHED_WARN_ON(!p->on_cpu);
++ p->cpus_ptr = new_mask;
++}
++
++void migrate_disable(void)
++{
++ struct task_struct *p = current;
++ int cpu;
++
++ if (p->migration_disabled) {
++ p->migration_disabled++;
++ return;
++ }
++
++ preempt_disable();
++ cpu = smp_processor_id();
++ if (cpumask_test_cpu(cpu, &p->cpus_mask)) {
++ cpu_rq(cpu)->nr_pinned++;
++ p->migration_disabled = 1;
++ p->migration_flags &= ~MDF_FORCE_ENABLED;
++
++ /*
++ * Violates locking rules! see comment in __do_set_cpus_ptr().
++ */
++ if (p->cpus_ptr == &p->cpus_mask)
++ __do_set_cpus_ptr(p, cpumask_of(cpu));
++ }
++ preempt_enable();
++}
++EXPORT_SYMBOL_GPL(migrate_disable);
++
++void migrate_enable(void)
++{
++ struct task_struct *p = current;
++
++ if (0 == p->migration_disabled)
++ return;
++
++ if (p->migration_disabled > 1) {
++ p->migration_disabled--;
++ return;
++ }
++
++ if (WARN_ON_ONCE(!p->migration_disabled))
++ return;
++
++ /*
++ * Ensure stop_task runs either before or after this, and that
++ * __set_cpus_allowed_ptr(SCA_MIGRATE_ENABLE) doesn't schedule().
++ */
++ preempt_disable();
++ /*
++ * Assumption: current should be running on allowed cpu
++ */
++ WARN_ON_ONCE(!cpumask_test_cpu(smp_processor_id(), &p->cpus_mask));
++ if (p->cpus_ptr != &p->cpus_mask)
++ __do_set_cpus_ptr(p, &p->cpus_mask);
++ /*
++ * Mustn't clear migration_disabled() until cpus_ptr points back at the
++ * regular cpus_mask, otherwise things that race (eg.
++ * select_fallback_rq) get confused.
++ */
++ barrier();
++ p->migration_disabled = 0;
++ this_rq()->nr_pinned--;
++ preempt_enable();
++}
++EXPORT_SYMBOL_GPL(migrate_enable);
++
++static inline bool rq_has_pinned_tasks(struct rq *rq)
++{
++ return rq->nr_pinned;
++}
++
++/*
++ * Per-CPU kthreads are allowed to run on !active && online CPUs, see
++ * __set_cpus_allowed_ptr() and select_fallback_rq().
++ */
++static inline bool is_cpu_allowed(struct task_struct *p, int cpu)
++{
++ /* When not in the task's cpumask, no point in looking further. */
++ if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++ return false;
++
++ /* migrate_disabled() must be allowed to finish. */
++ if (is_migration_disabled(p))
++ return cpu_online(cpu);
++
++ /* Non kernel threads are not allowed during either online or offline. */
++ if (!(p->flags & PF_KTHREAD))
++ return cpu_active(cpu) && task_cpu_possible(cpu, p);
++
++ /* KTHREAD_IS_PER_CPU is always allowed. */
++ if (kthread_is_per_cpu(p))
++ return cpu_online(cpu);
++
++ /* Regular kernel threads don't get to stay during offline. */
++ if (cpu_dying(cpu))
++ return false;
++
++ /* But are allowed during online. */
++ return cpu_online(cpu);
++}
++
++/*
++ * This is how migration works:
++ *
++ * 1) we invoke migration_cpu_stop() on the target CPU using
++ * stop_one_cpu().
++ * 2) stopper starts to run (implicitly forcing the migrated thread
++ * off the CPU)
++ * 3) it checks whether the migrated task is still in the wrong runqueue.
++ * 4) if it's in the wrong runqueue then the migration thread removes
++ * it and puts it into the right queue.
++ * 5) stopper completes and stop_one_cpu() returns and the migration
++ * is done.
++ */
++
++/*
++ * move_queued_task - move a queued task to new rq.
++ *
++ * Returns (locked) new rq. Old rq's lock is released.
++ */
++static struct rq *move_queued_task(struct rq *rq, struct task_struct *p, int
++ new_cpu)
++{
++ lockdep_assert_held(&rq->lock);
++
++ WRITE_ONCE(p->on_rq, TASK_ON_RQ_MIGRATING);
++ dequeue_task(p, rq, 0);
++ update_sched_rq_watermark(rq);
++ set_task_cpu(p, new_cpu);
++ raw_spin_unlock(&rq->lock);
++
++ rq = cpu_rq(new_cpu);
++
++ raw_spin_lock(&rq->lock);
++ BUG_ON(task_cpu(p) != new_cpu);
++ sched_task_sanity_check(p, rq);
++ enqueue_task(p, rq, 0);
++ p->on_rq = TASK_ON_RQ_QUEUED;
++ check_preempt_curr(rq);
++
++ return rq;
++}
++
++struct migration_arg {
++ struct task_struct *task;
++ int dest_cpu;
++};
++
++/*
++ * Move (not current) task off this CPU, onto the destination CPU. We're doing
++ * this because either it can't run here any more (set_cpus_allowed()
++ * away from this CPU, or CPU going down), or because we're
++ * attempting to rebalance this task on exec (sched_exec).
++ *
++ * So we race with normal scheduler movements, but that's OK, as long
++ * as the task is no longer on this CPU.
++ */
++static struct rq *__migrate_task(struct rq *rq, struct task_struct *p, int
++ dest_cpu)
++{
++ /* Affinity changed (again). */
++ if (!is_cpu_allowed(p, dest_cpu))
++ return rq;
++
++ update_rq_clock(rq);
++ return move_queued_task(rq, p, dest_cpu);
++}
++
++/*
++ * migration_cpu_stop - this will be executed by a highprio stopper thread
++ * and performs thread migration by bumping thread off CPU then
++ * 'pushing' onto another runqueue.
++ */
++static int migration_cpu_stop(void *data)
++{
++ struct migration_arg *arg = data;
++ struct task_struct *p = arg->task;
++ struct rq *rq = this_rq();
++ unsigned long flags;
++
++ /*
++ * The original target CPU might have gone down and we might
++ * be on another CPU but it doesn't matter.
++ */
++ local_irq_save(flags);
++ /*
++ * We need to explicitly wake pending tasks before running
++ * __migrate_task() such that we will not miss enforcing cpus_ptr
++ * during wakeups, see set_cpus_allowed_ptr()'s TASK_WAKING test.
++ */
++ flush_smp_call_function_queue();
++
++ raw_spin_lock(&p->pi_lock);
++ raw_spin_lock(&rq->lock);
++ /*
++ * If task_rq(p) != rq, it cannot be migrated here, because we're
++ * holding rq->lock, if p->on_rq == 0 it cannot get enqueued because
++ * we're holding p->pi_lock.
++ */
++ if (task_rq(p) == rq && task_on_rq_queued(p))
++ rq = __migrate_task(rq, p, arg->dest_cpu);
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++ return 0;
++}
++
++static inline void
++set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask)
++{
++ cpumask_copy(&p->cpus_mask, new_mask);
++ p->nr_cpus_allowed = cpumask_weight(new_mask);
++}
++
++static void
++__do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
++{
++ lockdep_assert_held(&p->pi_lock);
++ set_cpus_allowed_common(p, new_mask);
++}
++
++void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
++{
++ __do_set_cpus_allowed(p, new_mask);
++}
++
++int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src,
++ int node)
++{
++ if (!src->user_cpus_ptr)
++ return 0;
++
++ dst->user_cpus_ptr = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
++ if (!dst->user_cpus_ptr)
++ return -ENOMEM;
++
++ cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
++ return 0;
++}
++
++static inline struct cpumask *clear_user_cpus_ptr(struct task_struct *p)
++{
++ struct cpumask *user_mask = NULL;
++
++ swap(p->user_cpus_ptr, user_mask);
++
++ return user_mask;
++}
++
++void release_user_cpus_ptr(struct task_struct *p)
++{
++ kfree(clear_user_cpus_ptr(p));
++}
++
++#endif
++
++/**
++ * task_curr - is this task currently executing on a CPU?
++ * @p: the task in question.
++ *
++ * Return: 1 if the task is currently executing. 0 otherwise.
++ */
++inline int task_curr(const struct task_struct *p)
++{
++ return cpu_curr(task_cpu(p)) == p;
++}
++
++#ifdef CONFIG_SMP
++/*
++ * wait_task_inactive - wait for a thread to unschedule.
++ *
++ * If @match_state is nonzero, it's the @p->state value just checked and
++ * not expected to change. If it changes, i.e. @p might have woken up,
++ * then return zero. When we succeed in waiting for @p to be off its CPU,
++ * we return a positive number (its total switch count). If a second call
++ * a short while later returns the same number, the caller can be sure that
++ * @p has remained unscheduled the whole time.
++ *
++ * The caller must ensure that the task *will* unschedule sometime soon,
++ * else this function might spin for a *long* time. This function can't
++ * be called with interrupts off, or it may introduce deadlock with
++ * smp_call_function() if an IPI is sent by the same process we are
++ * waiting to become inactive.
++ */
++unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state)
++{
++ unsigned long flags;
++ bool running, on_rq;
++ unsigned long ncsw;
++ struct rq *rq;
++ raw_spinlock_t *lock;
++
++ for (;;) {
++ rq = task_rq(p);
++
++ /*
++ * If the task is actively running on another CPU
++ * still, just relax and busy-wait without holding
++ * any locks.
++ *
++ * NOTE! Since we don't hold any locks, it's not
++ * even sure that "rq" stays as the right runqueue!
++ * But we don't care, since this will return false
++ * if the runqueue has changed and p is actually now
++ * running somewhere else!
++ */
++ while (task_running(p) && p == rq->curr) {
++ if (match_state && unlikely(READ_ONCE(p->__state) != match_state))
++ return 0;
++ cpu_relax();
++ }
++
++ /*
++ * Ok, time to look more closely! We need the rq
++ * lock now, to be *sure*. If we're wrong, we'll
++ * just go back and repeat.
++ */
++ task_access_lock_irqsave(p, &lock, &flags);
++ trace_sched_wait_task(p);
++ running = task_running(p);
++ on_rq = p->on_rq;
++ ncsw = 0;
++ if (!match_state || READ_ONCE(p->__state) == match_state)
++ ncsw = p->nvcsw | LONG_MIN; /* sets MSB */
++ task_access_unlock_irqrestore(p, lock, &flags);
++
++ /*
++ * If it changed from the expected state, bail out now.
++ */
++ if (unlikely(!ncsw))
++ break;
++
++ /*
++ * Was it really running after all now that we
++ * checked with the proper locks actually held?
++ *
++ * Oops. Go back and try again..
++ */
++ if (unlikely(running)) {
++ cpu_relax();
++ continue;
++ }
++
++ /*
++ * It's not enough that it's not actively running,
++ * it must be off the runqueue _entirely_, and not
++ * preempted!
++ *
++ * So if it was still runnable (but just not actively
++ * running right now), it's preempted, and we should
++ * yield - it could be a while.
++ */
++ if (unlikely(on_rq)) {
++ ktime_t to = NSEC_PER_SEC / HZ;
++
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_hrtimeout(&to, HRTIMER_MODE_REL_HARD);
++ continue;
++ }
++
++ /*
++ * Ahh, all good. It wasn't running, and it wasn't
++ * runnable, which means that it will never become
++ * running in the future either. We're all done!
++ */
++ break;
++ }
++
++ return ncsw;
++}
++
++/***
++ * kick_process - kick a running thread to enter/exit the kernel
++ * @p: the to-be-kicked thread
++ *
++ * Cause a process which is running on another CPU to enter
++ * kernel-mode, without any delay. (to get signals handled.)
++ *
++ * NOTE: this function doesn't have to take the runqueue lock,
++ * because all it wants to ensure is that the remote task enters
++ * the kernel. If the IPI races and the task has been migrated
++ * to another CPU then no harm is done and the purpose has been
++ * achieved as well.
++ */
++void kick_process(struct task_struct *p)
++{
++ int cpu;
++
++ preempt_disable();
++ cpu = task_cpu(p);
++ if ((cpu != smp_processor_id()) && task_curr(p))
++ smp_send_reschedule(cpu);
++ preempt_enable();
++}
++EXPORT_SYMBOL_GPL(kick_process);
++
++/*
++ * ->cpus_ptr is protected by both rq->lock and p->pi_lock
++ *
++ * A few notes on cpu_active vs cpu_online:
++ *
++ * - cpu_active must be a subset of cpu_online
++ *
++ * - on CPU-up we allow per-CPU kthreads on the online && !active CPU,
++ * see __set_cpus_allowed_ptr(). At this point the newly online
++ * CPU isn't yet part of the sched domains, and balancing will not
++ * see it.
++ *
++ * - on cpu-down we clear cpu_active() to mask the sched domains and
++ * avoid the load balancer to place new tasks on the to be removed
++ * CPU. Existing tasks will remain running there and will be taken
++ * off.
++ *
++ * This means that fallback selection must not select !active CPUs.
++ * And can assume that any active CPU must be online. Conversely
++ * select_task_rq() below may allow selection of !active CPUs in order
++ * to satisfy the above rules.
++ */
++static int select_fallback_rq(int cpu, struct task_struct *p)
++{
++ int nid = cpu_to_node(cpu);
++ const struct cpumask *nodemask = NULL;
++ enum { cpuset, possible, fail } state = cpuset;
++ int dest_cpu;
++
++ /*
++ * If the node that the CPU is on has been offlined, cpu_to_node()
++ * will return -1. There is no CPU on the node, and we should
++ * select the CPU on the other node.
++ */
++ if (nid != -1) {
++ nodemask = cpumask_of_node(nid);
++
++ /* Look for allowed, online CPU in same node. */
++ for_each_cpu(dest_cpu, nodemask) {
++ if (is_cpu_allowed(p, dest_cpu))
++ return dest_cpu;
++ }
++ }
++
++ for (;;) {
++ /* Any allowed, online CPU? */
++ for_each_cpu(dest_cpu, p->cpus_ptr) {
++ if (!is_cpu_allowed(p, dest_cpu))
++ continue;
++ goto out;
++ }
++
++ /* No more Mr. Nice Guy. */
++ switch (state) {
++ case cpuset:
++ if (cpuset_cpus_allowed_fallback(p)) {
++ state = possible;
++ break;
++ }
++ fallthrough;
++ case possible:
++ /*
++ * XXX When called from select_task_rq() we only
++ * hold p->pi_lock and again violate locking order.
++ *
++ * More yuck to audit.
++ */
++ do_set_cpus_allowed(p, task_cpu_possible_mask(p));
++ state = fail;
++ break;
++
++ case fail:
++ BUG();
++ break;
++ }
++ }
++
++out:
++ if (state != cpuset) {
++ /*
++ * Don't tell them about moving exiting tasks or
++ * kernel threads (both mm NULL), since they never
++ * leave kernel.
++ */
++ if (p->mm && printk_ratelimit()) {
++ printk_deferred("process %d (%s) no longer affine to cpu%d\n",
++ task_pid_nr(p), p->comm, cpu);
++ }
++ }
++
++ return dest_cpu;
++}
++
++static inline int select_task_rq(struct task_struct *p)
++{
++ cpumask_t chk_mask, tmp;
++
++ if (unlikely(!cpumask_and(&chk_mask, p->cpus_ptr, cpu_active_mask)))
++ return select_fallback_rq(task_cpu(p), p);
++
++ if (
++#ifdef CONFIG_SCHED_SMT
++ cpumask_and(&tmp, &chk_mask, &sched_sg_idle_mask) ||
++#endif
++ cpumask_and(&tmp, &chk_mask, sched_rq_watermark) ||
++ cpumask_and(&tmp, &chk_mask,
++ sched_rq_watermark + SCHED_QUEUE_BITS - 1 - task_sched_prio(p)))
++ return best_mask_cpu(task_cpu(p), &tmp);
++
++ return best_mask_cpu(task_cpu(p), &chk_mask);
++}
++
++void sched_set_stop_task(int cpu, struct task_struct *stop)
++{
++ static struct lock_class_key stop_pi_lock;
++ struct sched_param stop_param = { .sched_priority = STOP_PRIO };
++ struct sched_param start_param = { .sched_priority = 0 };
++ struct task_struct *old_stop = cpu_rq(cpu)->stop;
++
++ if (stop) {
++ /*
++ * Make it appear like a SCHED_FIFO task, its something
++ * userspace knows about and won't get confused about.
++ *
++ * Also, it will make PI more or less work without too
++ * much confusion -- but then, stop work should not
++ * rely on PI working anyway.
++ */
++ sched_setscheduler_nocheck(stop, SCHED_FIFO, &stop_param);
++
++ /*
++ * The PI code calls rt_mutex_setprio() with ->pi_lock held to
++ * adjust the effective priority of a task. As a result,
++ * rt_mutex_setprio() can trigger (RT) balancing operations,
++ * which can then trigger wakeups of the stop thread to push
++ * around the current task.
++ *
++ * The stop task itself will never be part of the PI-chain, it
++ * never blocks, therefore that ->pi_lock recursion is safe.
++ * Tell lockdep about this by placing the stop->pi_lock in its
++ * own class.
++ */
++ lockdep_set_class(&stop->pi_lock, &stop_pi_lock);
++ }
++
++ cpu_rq(cpu)->stop = stop;
++
++ if (old_stop) {
++ /*
++ * Reset it back to a normal scheduling policy so that
++ * it can die in pieces.
++ */
++ sched_setscheduler_nocheck(old_stop, SCHED_NORMAL, &start_param);
++ }
++}
++
++static int affine_move_task(struct rq *rq, struct task_struct *p, int dest_cpu,
++ raw_spinlock_t *lock, unsigned long irq_flags)
++{
++ /* Can the task run on the task's current CPU? If so, we're done */
++ if (!cpumask_test_cpu(task_cpu(p), &p->cpus_mask)) {
++ if (p->migration_disabled) {
++ if (likely(p->cpus_ptr != &p->cpus_mask))
++ __do_set_cpus_ptr(p, &p->cpus_mask);
++ p->migration_disabled = 0;
++ p->migration_flags |= MDF_FORCE_ENABLED;
++ /* When p is migrate_disabled, rq->lock should be held */
++ rq->nr_pinned--;
++ }
++
++ if (task_running(p) || READ_ONCE(p->__state) == TASK_WAKING) {
++ struct migration_arg arg = { p, dest_cpu };
++
++ /* Need help from migration thread: drop lock and wait. */
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++ stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
++ return 0;
++ }
++ if (task_on_rq_queued(p)) {
++ /*
++ * OK, since we're going to drop the lock immediately
++ * afterwards anyway.
++ */
++ update_rq_clock(rq);
++ rq = move_queued_task(rq, p, dest_cpu);
++ lock = &rq->lock;
++ }
++ }
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++ return 0;
++}
++
++static int __set_cpus_allowed_ptr_locked(struct task_struct *p,
++ const struct cpumask *new_mask,
++ u32 flags,
++ struct rq *rq,
++ raw_spinlock_t *lock,
++ unsigned long irq_flags)
++{
++ const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
++ const struct cpumask *cpu_valid_mask = cpu_active_mask;
++ bool kthread = p->flags & PF_KTHREAD;
++ struct cpumask *user_mask = NULL;
++ int dest_cpu;
++ int ret = 0;
++
++ if (kthread || is_migration_disabled(p)) {
++ /*
++ * Kernel threads are allowed on online && !active CPUs,
++ * however, during cpu-hot-unplug, even these might get pushed
++ * away if not KTHREAD_IS_PER_CPU.
++ *
++ * Specifically, migration_disabled() tasks must not fail the
++ * cpumask_any_and_distribute() pick below, esp. so on
++ * SCA_MIGRATE_ENABLE, otherwise we'll not call
++ * set_cpus_allowed_common() and actually reset p->cpus_ptr.
++ */
++ cpu_valid_mask = cpu_online_mask;
++ }
++
++ if (!kthread && !cpumask_subset(new_mask, cpu_allowed_mask)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /*
++ * Must re-check here, to close a race against __kthread_bind(),
++ * sched_setaffinity() is not guaranteed to observe the flag.
++ */
++ if ((flags & SCA_CHECK) && (p->flags & PF_NO_SETAFFINITY)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (cpumask_equal(&p->cpus_mask, new_mask))
++ goto out;
++
++ dest_cpu = cpumask_any_and(cpu_valid_mask, new_mask);
++ if (dest_cpu >= nr_cpu_ids) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ __do_set_cpus_allowed(p, new_mask);
++
++ if (flags & SCA_USER)
++ user_mask = clear_user_cpus_ptr(p);
++
++ ret = affine_move_task(rq, p, dest_cpu, lock, irq_flags);
++
++ kfree(user_mask);
++
++ return ret;
++
++out:
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++
++ return ret;
++}
++
++/*
++ * Change a given task's CPU affinity. Migrate the thread to a
++ * proper CPU and schedule it away if the CPU it's executing on
++ * is removed from the allowed bitmask.
++ *
++ * NOTE: the caller must have a valid reference to the task, the
++ * task must not exit() & deallocate itself prematurely. The
++ * call is not atomic; no spinlocks may be held.
++ */
++static int __set_cpus_allowed_ptr(struct task_struct *p,
++ const struct cpumask *new_mask, u32 flags)
++{
++ unsigned long irq_flags;
++ struct rq *rq;
++ raw_spinlock_t *lock;
++
++ raw_spin_lock_irqsave(&p->pi_lock, irq_flags);
++ rq = __task_access_lock(p, &lock);
++
++ return __set_cpus_allowed_ptr_locked(p, new_mask, flags, rq, lock, irq_flags);
++}
++
++int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
++{
++ return __set_cpus_allowed_ptr(p, new_mask, 0);
++}
++EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
++
++/*
++ * Change a given task's CPU affinity to the intersection of its current
++ * affinity mask and @subset_mask, writing the resulting mask to @new_mask
++ * and pointing @p->user_cpus_ptr to a copy of the old mask.
++ * If the resulting mask is empty, leave the affinity unchanged and return
++ * -EINVAL.
++ */
++static int restrict_cpus_allowed_ptr(struct task_struct *p,
++ struct cpumask *new_mask,
++ const struct cpumask *subset_mask)
++{
++ struct cpumask *user_mask = NULL;
++ unsigned long irq_flags;
++ raw_spinlock_t *lock;
++ struct rq *rq;
++ int err;
++
++ if (!p->user_cpus_ptr) {
++ user_mask = kmalloc(cpumask_size(), GFP_KERNEL);
++ if (!user_mask)
++ return -ENOMEM;
++ }
++
++ raw_spin_lock_irqsave(&p->pi_lock, irq_flags);
++ rq = __task_access_lock(p, &lock);
++
++ if (!cpumask_and(new_mask, &p->cpus_mask, subset_mask)) {
++ err = -EINVAL;
++ goto err_unlock;
++ }
++
++ /*
++ * We're about to butcher the task affinity, so keep track of what
++ * the user asked for in case we're able to restore it later on.
++ */
++ if (user_mask) {
++ cpumask_copy(user_mask, p->cpus_ptr);
++ p->user_cpus_ptr = user_mask;
++ }
++
++ /*return __set_cpus_allowed_ptr_locked(p, new_mask, 0, rq, &rf);*/
++ return __set_cpus_allowed_ptr_locked(p, new_mask, 0, rq, lock, irq_flags);
++
++err_unlock:
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++ kfree(user_mask);
++ return err;
++}
++
++/*
++ * Restrict the CPU affinity of task @p so that it is a subset of
++ * task_cpu_possible_mask() and point @p->user_cpu_ptr to a copy of the
++ * old affinity mask. If the resulting mask is empty, we warn and walk
++ * up the cpuset hierarchy until we find a suitable mask.
++ */
++void force_compatible_cpus_allowed_ptr(struct task_struct *p)
++{
++ cpumask_var_t new_mask;
++ const struct cpumask *override_mask = task_cpu_possible_mask(p);
++
++ alloc_cpumask_var(&new_mask, GFP_KERNEL);
++
++ /*
++ * __migrate_task() can fail silently in the face of concurrent
++ * offlining of the chosen destination CPU, so take the hotplug
++ * lock to ensure that the migration succeeds.
++ */
++ cpus_read_lock();
++ if (!cpumask_available(new_mask))
++ goto out_set_mask;
++
++ if (!restrict_cpus_allowed_ptr(p, new_mask, override_mask))
++ goto out_free_mask;
++
++ /*
++ * We failed to find a valid subset of the affinity mask for the
++ * task, so override it based on its cpuset hierarchy.
++ */
++ cpuset_cpus_allowed(p, new_mask);
++ override_mask = new_mask;
++
++out_set_mask:
++ if (printk_ratelimit()) {
++ printk_deferred("Overriding affinity for process %d (%s) to CPUs %*pbl\n",
++ task_pid_nr(p), p->comm,
++ cpumask_pr_args(override_mask));
++ }
++
++ WARN_ON(set_cpus_allowed_ptr(p, override_mask));
++out_free_mask:
++ cpus_read_unlock();
++ free_cpumask_var(new_mask);
++}
++
++static int
++__sched_setaffinity(struct task_struct *p, const struct cpumask *mask);
++
++/*
++ * Restore the affinity of a task @p which was previously restricted by a
++ * call to force_compatible_cpus_allowed_ptr(). This will clear (and free)
++ * @p->user_cpus_ptr.
++ *
++ * It is the caller's responsibility to serialise this with any calls to
++ * force_compatible_cpus_allowed_ptr(@p).
++ */
++void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
++{
++ struct cpumask *user_mask = p->user_cpus_ptr;
++ unsigned long flags;
++
++ /*
++ * Try to restore the old affinity mask. If this fails, then
++ * we free the mask explicitly to avoid it being inherited across
++ * a subsequent fork().
++ */
++ if (!user_mask || !__sched_setaffinity(p, user_mask))
++ return;
++
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++ user_mask = clear_user_cpus_ptr(p);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++ kfree(user_mask);
++}
++
++#else /* CONFIG_SMP */
++
++static inline int select_task_rq(struct task_struct *p)
++{
++ return 0;
++}
++
++static inline int
++__set_cpus_allowed_ptr(struct task_struct *p,
++ const struct cpumask *new_mask, u32 flags)
++{
++ return set_cpus_allowed_ptr(p, new_mask);
++}
++
++static inline bool rq_has_pinned_tasks(struct rq *rq)
++{
++ return false;
++}
++
++#endif /* !CONFIG_SMP */
++
++static void
++ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
++{
++ struct rq *rq;
++
++ if (!schedstat_enabled())
++ return;
++
++ rq = this_rq();
++
++#ifdef CONFIG_SMP
++ if (cpu == rq->cpu) {
++ __schedstat_inc(rq->ttwu_local);
++ __schedstat_inc(p->stats.nr_wakeups_local);
++ } else {
++ /** Alt schedule FW ToDo:
++ * How to do ttwu_wake_remote
++ */
++ }
++#endif /* CONFIG_SMP */
++
++ __schedstat_inc(rq->ttwu_count);
++ __schedstat_inc(p->stats.nr_wakeups);
++}
++
++/*
++ * Mark the task runnable and perform wakeup-preemption.
++ */
++static inline void
++ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
++{
++ check_preempt_curr(rq);
++ WRITE_ONCE(p->__state, TASK_RUNNING);
++ trace_sched_wakeup(p);
++}
++
++static inline void
++ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags)
++{
++ if (p->sched_contributes_to_load)
++ rq->nr_uninterruptible--;
++
++ if (
++#ifdef CONFIG_SMP
++ !(wake_flags & WF_MIGRATED) &&
++#endif
++ p->in_iowait) {
++ delayacct_blkio_end(p);
++ atomic_dec(&task_rq(p)->nr_iowait);
++ }
++
++ activate_task(p, rq);
++ ttwu_do_wakeup(rq, p, 0);
++}
++
++/*
++ * Consider @p being inside a wait loop:
++ *
++ * for (;;) {
++ * set_current_state(TASK_UNINTERRUPTIBLE);
++ *
++ * if (CONDITION)
++ * break;
++ *
++ * schedule();
++ * }
++ * __set_current_state(TASK_RUNNING);
++ *
++ * between set_current_state() and schedule(). In this case @p is still
++ * runnable, so all that needs doing is change p->state back to TASK_RUNNING in
++ * an atomic manner.
++ *
++ * By taking task_rq(p)->lock we serialize against schedule(), if @p->on_rq
++ * then schedule() must still happen and p->state can be changed to
++ * TASK_RUNNING. Otherwise we lost the race, schedule() has happened, and we
++ * need to do a full wakeup with enqueue.
++ *
++ * Returns: %true when the wakeup is done,
++ * %false otherwise.
++ */
++static int ttwu_runnable(struct task_struct *p, int wake_flags)
++{
++ struct rq *rq;
++ raw_spinlock_t *lock;
++ int ret = 0;
++
++ rq = __task_access_lock(p, &lock);
++ if (task_on_rq_queued(p)) {
++ /* check_preempt_curr() may use rq clock */
++ update_rq_clock(rq);
++ ttwu_do_wakeup(rq, p, wake_flags);
++ ret = 1;
++ }
++ __task_access_unlock(p, lock);
++
++ return ret;
++}
++
++#ifdef CONFIG_SMP
++void sched_ttwu_pending(void *arg)
++{
++ struct llist_node *llist = arg;
++ struct rq *rq = this_rq();
++ struct task_struct *p, *t;
++ struct rq_flags rf;
++
++ if (!llist)
++ return;
++
++ /*
++ * rq::ttwu_pending racy indication of out-standing wakeups.
++ * Races such that false-negatives are possible, since they
++ * are shorter lived that false-positives would be.
++ */
++ WRITE_ONCE(rq->ttwu_pending, 0);
++
++ rq_lock_irqsave(rq, &rf);
++ update_rq_clock(rq);
++
++ llist_for_each_entry_safe(p, t, llist, wake_entry.llist) {
++ if (WARN_ON_ONCE(p->on_cpu))
++ smp_cond_load_acquire(&p->on_cpu, !VAL);
++
++ if (WARN_ON_ONCE(task_cpu(p) != cpu_of(rq)))
++ set_task_cpu(p, cpu_of(rq));
++
++ ttwu_do_activate(rq, p, p->sched_remote_wakeup ? WF_MIGRATED : 0);
++ }
++
++ rq_unlock_irqrestore(rq, &rf);
++}
++
++void send_call_function_single_ipi(int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ if (!set_nr_if_polling(rq->idle))
++ arch_send_call_function_single_ipi(cpu);
++ else
++ trace_sched_wake_idle_without_ipi(cpu);
++}
++
++/*
++ * Queue a task on the target CPUs wake_list and wake the CPU via IPI if
++ * necessary. The wakee CPU on receipt of the IPI will queue the task
++ * via sched_ttwu_wakeup() for activation so the wakee incurs the cost
++ * of the wakeup instead of the waker.
++ */
++static void __ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ p->sched_remote_wakeup = !!(wake_flags & WF_MIGRATED);
++
++ WRITE_ONCE(rq->ttwu_pending, 1);
++ __smp_call_single_queue(cpu, &p->wake_entry.llist);
++}
++
++static inline bool ttwu_queue_cond(struct task_struct *p, int cpu)
++{
++ /*
++ * Do not complicate things with the async wake_list while the CPU is
++ * in hotplug state.
++ */
++ if (!cpu_active(cpu))
++ return false;
++
++ /* Ensure the task will still be allowed to run on the CPU. */
++ if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++ return false;
++
++ /*
++ * If the CPU does not share cache, then queue the task on the
++ * remote rqs wakelist to avoid accessing remote data.
++ */
++ if (!cpus_share_cache(smp_processor_id(), cpu))
++ return true;
++
++ if (cpu == smp_processor_id())
++ return false;
++
++ /*
++ * If the wakee cpu is idle, or the task is descheduling and the
++ * only running task on the CPU, then use the wakelist to offload
++ * the task activation to the idle (or soon-to-be-idle) CPU as
++ * the current CPU is likely busy. nr_running is checked to
++ * avoid unnecessary task stacking.
++ *
++ * Note that we can only get here with (wakee) p->on_rq=0,
++ * p->on_cpu can be whatever, we've done the dequeue, so
++ * the wakee has been accounted out of ->nr_running.
++ */
++ if (!cpu_rq(cpu)->nr_running)
++ return true;
++
++ return false;
++}
++
++static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++ if (__is_defined(ALT_SCHED_TTWU_QUEUE) && ttwu_queue_cond(p, cpu)) {
++ sched_clock_cpu(cpu); /* Sync clocks across CPUs */
++ __ttwu_queue_wakelist(p, cpu, wake_flags);
++ return true;
++ }
++
++ return false;
++}
++
++void wake_up_if_idle(int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++
++ rcu_read_lock();
++
++ if (!is_idle_task(rcu_dereference(rq->curr)))
++ goto out;
++
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ if (is_idle_task(rq->curr))
++ resched_curr(rq);
++ /* Else CPU is not idle, do nothing here */
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++out:
++ rcu_read_unlock();
++}
++
++bool cpus_share_cache(int this_cpu, int that_cpu)
++{
++ if (this_cpu == that_cpu)
++ return true;
++
++ return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
++}
++#else /* !CONFIG_SMP */
++
++static inline bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++ return false;
++}
++
++#endif /* CONFIG_SMP */
++
++static inline void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ if (ttwu_queue_wakelist(p, cpu, wake_flags))
++ return;
++
++ raw_spin_lock(&rq->lock);
++ update_rq_clock(rq);
++ ttwu_do_activate(rq, p, wake_flags);
++ raw_spin_unlock(&rq->lock);
++}
++
++/*
++ * Invoked from try_to_wake_up() to check whether the task can be woken up.
++ *
++ * The caller holds p::pi_lock if p != current or has preemption
++ * disabled when p == current.
++ *
++ * The rules of PREEMPT_RT saved_state:
++ *
++ * The related locking code always holds p::pi_lock when updating
++ * p::saved_state, which means the code is fully serialized in both cases.
++ *
++ * The lock wait and lock wakeups happen via TASK_RTLOCK_WAIT. No other
++ * bits set. This allows to distinguish all wakeup scenarios.
++ */
++static __always_inline
++bool ttwu_state_match(struct task_struct *p, unsigned int state, int *success)
++{
++ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) {
++ WARN_ON_ONCE((state & TASK_RTLOCK_WAIT) &&
++ state != TASK_RTLOCK_WAIT);
++ }
++
++ if (READ_ONCE(p->__state) & state) {
++ *success = 1;
++ return true;
++ }
++
++#ifdef CONFIG_PREEMPT_RT
++ /*
++ * Saved state preserves the task state across blocking on
++ * an RT lock. If the state matches, set p::saved_state to
++ * TASK_RUNNING, but do not wake the task because it waits
++ * for a lock wakeup. Also indicate success because from
++ * the regular waker's point of view this has succeeded.
++ *
++ * After acquiring the lock the task will restore p::__state
++ * from p::saved_state which ensures that the regular
++ * wakeup is not lost. The restore will also set
++ * p::saved_state to TASK_RUNNING so any further tests will
++ * not result in false positives vs. @success
++ */
++ if (p->saved_state & state) {
++ p->saved_state = TASK_RUNNING;
++ *success = 1;
++ }
++#endif
++ return false;
++}
++
++/*
++ * Notes on Program-Order guarantees on SMP systems.
++ *
++ * MIGRATION
++ *
++ * The basic program-order guarantee on SMP systems is that when a task [t]
++ * migrates, all its activity on its old CPU [c0] happens-before any subsequent
++ * execution on its new CPU [c1].
++ *
++ * For migration (of runnable tasks) this is provided by the following means:
++ *
++ * A) UNLOCK of the rq(c0)->lock scheduling out task t
++ * B) migration for t is required to synchronize *both* rq(c0)->lock and
++ * rq(c1)->lock (if not at the same time, then in that order).
++ * C) LOCK of the rq(c1)->lock scheduling in task
++ *
++ * Transitivity guarantees that B happens after A and C after B.
++ * Note: we only require RCpc transitivity.
++ * Note: the CPU doing B need not be c0 or c1
++ *
++ * Example:
++ *
++ * CPU0 CPU1 CPU2
++ *
++ * LOCK rq(0)->lock
++ * sched-out X
++ * sched-in Y
++ * UNLOCK rq(0)->lock
++ *
++ * LOCK rq(0)->lock // orders against CPU0
++ * dequeue X
++ * UNLOCK rq(0)->lock
++ *
++ * LOCK rq(1)->lock
++ * enqueue X
++ * UNLOCK rq(1)->lock
++ *
++ * LOCK rq(1)->lock // orders against CPU2
++ * sched-out Z
++ * sched-in X
++ * UNLOCK rq(1)->lock
++ *
++ *
++ * BLOCKING -- aka. SLEEP + WAKEUP
++ *
++ * For blocking we (obviously) need to provide the same guarantee as for
++ * migration. However the means are completely different as there is no lock
++ * chain to provide order. Instead we do:
++ *
++ * 1) smp_store_release(X->on_cpu, 0) -- finish_task()
++ * 2) smp_cond_load_acquire(!X->on_cpu) -- try_to_wake_up()
++ *
++ * Example:
++ *
++ * CPU0 (schedule) CPU1 (try_to_wake_up) CPU2 (schedule)
++ *
++ * LOCK rq(0)->lock LOCK X->pi_lock
++ * dequeue X
++ * sched-out X
++ * smp_store_release(X->on_cpu, 0);
++ *
++ * smp_cond_load_acquire(&X->on_cpu, !VAL);
++ * X->state = WAKING
++ * set_task_cpu(X,2)
++ *
++ * LOCK rq(2)->lock
++ * enqueue X
++ * X->state = RUNNING
++ * UNLOCK rq(2)->lock
++ *
++ * LOCK rq(2)->lock // orders against CPU1
++ * sched-out Z
++ * sched-in X
++ * UNLOCK rq(2)->lock
++ *
++ * UNLOCK X->pi_lock
++ * UNLOCK rq(0)->lock
++ *
++ *
++ * However; for wakeups there is a second guarantee we must provide, namely we
++ * must observe the state that lead to our wakeup. That is, not only must our
++ * task observe its own prior state, it must also observe the stores prior to
++ * its wakeup.
++ *
++ * This means that any means of doing remote wakeups must order the CPU doing
++ * the wakeup against the CPU the task is going to end up running on. This,
++ * however, is already required for the regular Program-Order guarantee above,
++ * since the waking CPU is the one issueing the ACQUIRE (smp_cond_load_acquire).
++ *
++ */
++
++/**
++ * try_to_wake_up - wake up a thread
++ * @p: the thread to be awakened
++ * @state: the mask of task states that can be woken
++ * @wake_flags: wake modifier flags (WF_*)
++ *
++ * Conceptually does:
++ *
++ * If (@state & @p->state) @p->state = TASK_RUNNING.
++ *
++ * If the task was not queued/runnable, also place it back on a runqueue.
++ *
++ * This function is atomic against schedule() which would dequeue the task.
++ *
++ * It issues a full memory barrier before accessing @p->state, see the comment
++ * with set_current_state().
++ *
++ * Uses p->pi_lock to serialize against concurrent wake-ups.
++ *
++ * Relies on p->pi_lock stabilizing:
++ * - p->sched_class
++ * - p->cpus_ptr
++ * - p->sched_task_group
++ * in order to do migration, see its use of select_task_rq()/set_task_cpu().
++ *
++ * Tries really hard to only take one task_rq(p)->lock for performance.
++ * Takes rq->lock in:
++ * - ttwu_runnable() -- old rq, unavoidable, see comment there;
++ * - ttwu_queue() -- new rq, for enqueue of the task;
++ * - psi_ttwu_dequeue() -- much sadness :-( accounting will kill us.
++ *
++ * As a consequence we race really badly with just about everything. See the
++ * many memory barriers and their comments for details.
++ *
++ * Return: %true if @p->state changes (an actual wakeup was done),
++ * %false otherwise.
++ */
++static int try_to_wake_up(struct task_struct *p, unsigned int state,
++ int wake_flags)
++{
++ unsigned long flags;
++ int cpu, success = 0;
++
++ preempt_disable();
++ if (p == current) {
++ /*
++ * We're waking current, this means 'p->on_rq' and 'task_cpu(p)
++ * == smp_processor_id()'. Together this means we can special
++ * case the whole 'p->on_rq && ttwu_runnable()' case below
++ * without taking any locks.
++ *
++ * In particular:
++ * - we rely on Program-Order guarantees for all the ordering,
++ * - we're serialized against set_special_state() by virtue of
++ * it disabling IRQs (this allows not taking ->pi_lock).
++ */
++ if (!ttwu_state_match(p, state, &success))
++ goto out;
++
++ trace_sched_waking(p);
++ WRITE_ONCE(p->__state, TASK_RUNNING);
++ trace_sched_wakeup(p);
++ goto out;
++ }
++
++ /*
++ * If we are going to wake up a thread waiting for CONDITION we
++ * need to ensure that CONDITION=1 done by the caller can not be
++ * reordered with p->state check below. This pairs with smp_store_mb()
++ * in set_current_state() that the waiting thread does.
++ */
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++ smp_mb__after_spinlock();
++ if (!ttwu_state_match(p, state, &success))
++ goto unlock;
++
++ trace_sched_waking(p);
++
++ /*
++ * Ensure we load p->on_rq _after_ p->state, otherwise it would
++ * be possible to, falsely, observe p->on_rq == 0 and get stuck
++ * in smp_cond_load_acquire() below.
++ *
++ * sched_ttwu_pending() try_to_wake_up()
++ * STORE p->on_rq = 1 LOAD p->state
++ * UNLOCK rq->lock
++ *
++ * __schedule() (switch to task 'p')
++ * LOCK rq->lock smp_rmb();
++ * smp_mb__after_spinlock();
++ * UNLOCK rq->lock
++ *
++ * [task p]
++ * STORE p->state = UNINTERRUPTIBLE LOAD p->on_rq
++ *
++ * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
++ * __schedule(). See the comment for smp_mb__after_spinlock().
++ *
++ * A similar smb_rmb() lives in try_invoke_on_locked_down_task().
++ */
++ smp_rmb();
++ if (READ_ONCE(p->on_rq) && ttwu_runnable(p, wake_flags))
++ goto unlock;
++
++#ifdef CONFIG_SMP
++ /*
++ * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
++ * possible to, falsely, observe p->on_cpu == 0.
++ *
++ * One must be running (->on_cpu == 1) in order to remove oneself
++ * from the runqueue.
++ *
++ * __schedule() (switch to task 'p') try_to_wake_up()
++ * STORE p->on_cpu = 1 LOAD p->on_rq
++ * UNLOCK rq->lock
++ *
++ * __schedule() (put 'p' to sleep)
++ * LOCK rq->lock smp_rmb();
++ * smp_mb__after_spinlock();
++ * STORE p->on_rq = 0 LOAD p->on_cpu
++ *
++ * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
++ * __schedule(). See the comment for smp_mb__after_spinlock().
++ *
++ * Form a control-dep-acquire with p->on_rq == 0 above, to ensure
++ * schedule()'s deactivate_task() has 'happened' and p will no longer
++ * care about it's own p->state. See the comment in __schedule().
++ */
++ smp_acquire__after_ctrl_dep();
++
++ /*
++ * We're doing the wakeup (@success == 1), they did a dequeue (p->on_rq
++ * == 0), which means we need to do an enqueue, change p->state to
++ * TASK_WAKING such that we can unlock p->pi_lock before doing the
++ * enqueue, such as ttwu_queue_wakelist().
++ */
++ WRITE_ONCE(p->__state, TASK_WAKING);
++
++ /*
++ * If the owning (remote) CPU is still in the middle of schedule() with
++ * this task as prev, considering queueing p on the remote CPUs wake_list
++ * which potentially sends an IPI instead of spinning on p->on_cpu to
++ * let the waker make forward progress. This is safe because IRQs are
++ * disabled and the IPI will deliver after on_cpu is cleared.
++ *
++ * Ensure we load task_cpu(p) after p->on_cpu:
++ *
++ * set_task_cpu(p, cpu);
++ * STORE p->cpu = @cpu
++ * __schedule() (switch to task 'p')
++ * LOCK rq->lock
++ * smp_mb__after_spin_lock() smp_cond_load_acquire(&p->on_cpu)
++ * STORE p->on_cpu = 1 LOAD p->cpu
++ *
++ * to ensure we observe the correct CPU on which the task is currently
++ * scheduling.
++ */
++ if (smp_load_acquire(&p->on_cpu) &&
++ ttwu_queue_wakelist(p, task_cpu(p), wake_flags))
++ goto unlock;
++
++ /*
++ * If the owning (remote) CPU is still in the middle of schedule() with
++ * this task as prev, wait until it's done referencing the task.
++ *
++ * Pairs with the smp_store_release() in finish_task().
++ *
++ * This ensures that tasks getting woken will be fully ordered against
++ * their previous state and preserve Program Order.
++ */
++ smp_cond_load_acquire(&p->on_cpu, !VAL);
++
++ sched_task_ttwu(p);
++
++ cpu = select_task_rq(p);
++
++ if (cpu != task_cpu(p)) {
++ if (p->in_iowait) {
++ delayacct_blkio_end(p);
++ atomic_dec(&task_rq(p)->nr_iowait);
++ }
++
++ wake_flags |= WF_MIGRATED;
++ psi_ttwu_dequeue(p);
++ set_task_cpu(p, cpu);
++ }
++#else
++ cpu = task_cpu(p);
++#endif /* CONFIG_SMP */
++
++ ttwu_queue(p, cpu, wake_flags);
++unlock:
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++out:
++ if (success)
++ ttwu_stat(p, task_cpu(p), wake_flags);
++ preempt_enable();
++
++ return success;
++}
++
++/**
++ * task_call_func - Invoke a function on task in fixed state
++ * @p: Process for which the function is to be invoked, can be @current.
++ * @func: Function to invoke.
++ * @arg: Argument to function.
++ *
++ * Fix the task in it's current state by avoiding wakeups and or rq operations
++ * and call @func(@arg) on it. This function can use ->on_rq and task_curr()
++ * to work out what the state is, if required. Given that @func can be invoked
++ * with a runqueue lock held, it had better be quite lightweight.
++ *
++ * Returns:
++ * Whatever @func returns
++ */
++int task_call_func(struct task_struct *p, task_call_f func, void *arg)
++{
++ struct rq *rq = NULL;
++ unsigned int state;
++ struct rq_flags rf;
++ int ret;
++
++ raw_spin_lock_irqsave(&p->pi_lock, rf.flags);
++
++ state = READ_ONCE(p->__state);
++
++ /*
++ * Ensure we load p->on_rq after p->__state, otherwise it would be
++ * possible to, falsely, observe p->on_rq == 0.
++ *
++ * See try_to_wake_up() for a longer comment.
++ */
++ smp_rmb();
++
++ /*
++ * Since pi->lock blocks try_to_wake_up(), we don't need rq->lock when
++ * the task is blocked. Make sure to check @state since ttwu() can drop
++ * locks at the end, see ttwu_queue_wakelist().
++ */
++ if (state == TASK_RUNNING || state == TASK_WAKING || p->on_rq)
++ rq = __task_rq_lock(p, &rf);
++
++ /*
++ * At this point the task is pinned; either:
++ * - blocked and we're holding off wakeups (pi->lock)
++ * - woken, and we're holding off enqueue (rq->lock)
++ * - queued, and we're holding off schedule (rq->lock)
++ * - running, and we're holding off de-schedule (rq->lock)
++ *
++ * The called function (@func) can use: task_curr(), p->on_rq and
++ * p->__state to differentiate between these states.
++ */
++ ret = func(p, arg);
++
++ if (rq)
++ __task_rq_unlock(rq, &rf);
++
++ raw_spin_unlock_irqrestore(&p->pi_lock, rf.flags);
++ return ret;
++}
++
++/**
++ * cpu_curr_snapshot - Return a snapshot of the currently running task
++ * @cpu: The CPU on which to snapshot the task.
++ *
++ * Returns the task_struct pointer of the task "currently" running on
++ * the specified CPU. If the same task is running on that CPU throughout,
++ * the return value will be a pointer to that task's task_struct structure.
++ * If the CPU did any context switches even vaguely concurrently with the
++ * execution of this function, the return value will be a pointer to the
++ * task_struct structure of a randomly chosen task that was running on
++ * that CPU somewhere around the time that this function was executing.
++ *
++ * If the specified CPU was offline, the return value is whatever it
++ * is, perhaps a pointer to the task_struct structure of that CPU's idle
++ * task, but there is no guarantee. Callers wishing a useful return
++ * value must take some action to ensure that the specified CPU remains
++ * online throughout.
++ *
++ * This function executes full memory barriers before and after fetching
++ * the pointer, which permits the caller to confine this function's fetch
++ * with respect to the caller's accesses to other shared variables.
++ */
++struct task_struct *cpu_curr_snapshot(int cpu)
++{
++ struct task_struct *t;
++
++ smp_mb(); /* Pairing determined by caller's synchronization design. */
++ t = rcu_dereference(cpu_curr(cpu));
++ smp_mb(); /* Pairing determined by caller's synchronization design. */
++ return t;
++}
++
++/**
++ * wake_up_process - Wake up a specific process
++ * @p: The process to be woken up.
++ *
++ * Attempt to wake up the nominated process and move it to the set of runnable
++ * processes.
++ *
++ * Return: 1 if the process was woken up, 0 if it was already running.
++ *
++ * This function executes a full memory barrier before accessing the task state.
++ */
++int wake_up_process(struct task_struct *p)
++{
++ return try_to_wake_up(p, TASK_NORMAL, 0);
++}
++EXPORT_SYMBOL(wake_up_process);
++
++int wake_up_state(struct task_struct *p, unsigned int state)
++{
++ return try_to_wake_up(p, state, 0);
++}
++
++/*
++ * Perform scheduler related setup for a newly forked process p.
++ * p is forked by current.
++ *
++ * __sched_fork() is basic setup used by init_idle() too:
++ */
++static inline void __sched_fork(unsigned long clone_flags, struct task_struct *p)
++{
++ p->on_rq = 0;
++ p->on_cpu = 0;
++ p->utime = 0;
++ p->stime = 0;
++ p->sched_time = 0;
++
++#ifdef CONFIG_SCHEDSTATS
++ /* Even if schedstat is disabled, there should not be garbage */
++ memset(&p->stats, 0, sizeof(p->stats));
++#endif
++
++#ifdef CONFIG_PREEMPT_NOTIFIERS
++ INIT_HLIST_HEAD(&p->preempt_notifiers);
++#endif
++
++#ifdef CONFIG_COMPACTION
++ p->capture_control = NULL;
++#endif
++#ifdef CONFIG_SMP
++ p->wake_entry.u_flags = CSD_TYPE_TTWU;
++#endif
++}
++
++/*
++ * fork()/clone()-time setup:
++ */
++int sched_fork(unsigned long clone_flags, struct task_struct *p)
++{
++ __sched_fork(clone_flags, p);
++ /*
++ * We mark the process as NEW here. This guarantees that
++ * nobody will actually run it, and a signal or other external
++ * event cannot wake it up and insert it on the runqueue either.
++ */
++ p->__state = TASK_NEW;
++
++ /*
++ * Make sure we do not leak PI boosting priority to the child.
++ */
++ p->prio = current->normal_prio;
++
++ /*
++ * Revert to default priority/policy on fork if requested.
++ */
++ if (unlikely(p->sched_reset_on_fork)) {
++ if (task_has_rt_policy(p)) {
++ p->policy = SCHED_NORMAL;
++ p->static_prio = NICE_TO_PRIO(0);
++ p->rt_priority = 0;
++ } else if (PRIO_TO_NICE(p->static_prio) < 0)
++ p->static_prio = NICE_TO_PRIO(0);
++
++ p->prio = p->normal_prio = p->static_prio;
++
++ /*
++ * We don't need the reset flag anymore after the fork. It has
++ * fulfilled its duty:
++ */
++ p->sched_reset_on_fork = 0;
++ }
++
++#ifdef CONFIG_SCHED_INFO
++ if (unlikely(sched_info_on()))
++ memset(&p->sched_info, 0, sizeof(p->sched_info));
++#endif
++ init_task_preempt_count(p);
++
++ return 0;
++}
++
++void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
++{
++ unsigned long flags;
++ struct rq *rq;
++
++ /*
++ * Because we're not yet on the pid-hash, p->pi_lock isn't strictly
++ * required yet, but lockdep gets upset if rules are violated.
++ */
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++ /*
++ * Share the timeslice between parent and child, thus the
++ * total amount of pending timeslices in the system doesn't change,
++ * resulting in more scheduling fairness.
++ */
++ rq = this_rq();
++ raw_spin_lock(&rq->lock);
++
++ rq->curr->time_slice /= 2;
++ p->time_slice = rq->curr->time_slice;
++#ifdef CONFIG_SCHED_HRTICK
++ hrtick_start(rq, rq->curr->time_slice);
++#endif
++
++ if (p->time_slice < RESCHED_NS) {
++ p->time_slice = sched_timeslice_ns;
++ resched_curr(rq);
++ }
++ sched_task_fork(p, rq);
++ raw_spin_unlock(&rq->lock);
++
++ rseq_migrate(p);
++ /*
++ * We're setting the CPU for the first time, we don't migrate,
++ * so use __set_task_cpu().
++ */
++ __set_task_cpu(p, smp_processor_id());
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++
++void sched_post_fork(struct task_struct *p)
++{
++}
++
++#ifdef CONFIG_SCHEDSTATS
++
++DEFINE_STATIC_KEY_FALSE(sched_schedstats);
++
++static void set_schedstats(bool enabled)
++{
++ if (enabled)
++ static_branch_enable(&sched_schedstats);
++ else
++ static_branch_disable(&sched_schedstats);
++}
++
++void force_schedstat_enabled(void)
++{
++ if (!schedstat_enabled()) {
++ pr_info("kernel profiling enabled schedstats, disable via kernel.sched_schedstats.\n");
++ static_branch_enable(&sched_schedstats);
++ }
++}
++
++static int __init setup_schedstats(char *str)
++{
++ int ret = 0;
++ if (!str)
++ goto out;
++
++ if (!strcmp(str, "enable")) {
++ set_schedstats(true);
++ ret = 1;
++ } else if (!strcmp(str, "disable")) {
++ set_schedstats(false);
++ ret = 1;
++ }
++out:
++ if (!ret)
++ pr_warn("Unable to parse schedstats=\n");
++
++ return ret;
++}
++__setup("schedstats=", setup_schedstats);
++
++#ifdef CONFIG_PROC_SYSCTL
++static int sysctl_schedstats(struct ctl_table *table, int write, void *buffer,
++ size_t *lenp, loff_t *ppos)
++{
++ struct ctl_table t;
++ int err;
++ int state = static_branch_likely(&sched_schedstats);
++
++ if (write && !capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ t = *table;
++ t.data = &state;
++ err = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
++ if (err < 0)
++ return err;
++ if (write)
++ set_schedstats(state);
++ return err;
++}
++
++static struct ctl_table sched_core_sysctls[] = {
++ {
++ .procname = "sched_schedstats",
++ .data = NULL,
++ .maxlen = sizeof(unsigned int),
++ .mode = 0644,
++ .proc_handler = sysctl_schedstats,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
++ {}
++};
++static int __init sched_core_sysctl_init(void)
++{
++ register_sysctl_init("kernel", sched_core_sysctls);
++ return 0;
++}
++late_initcall(sched_core_sysctl_init);
++#endif /* CONFIG_PROC_SYSCTL */
++#endif /* CONFIG_SCHEDSTATS */
++
++/*
++ * wake_up_new_task - wake up a newly created task for the first time.
++ *
++ * This function will do some initial scheduler statistics housekeeping
++ * that must be done for every newly created context, then puts the task
++ * on the runqueue and wakes it.
++ */
++void wake_up_new_task(struct task_struct *p)
++{
++ unsigned long flags;
++ struct rq *rq;
++
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++ WRITE_ONCE(p->__state, TASK_RUNNING);
++ rq = cpu_rq(select_task_rq(p));
++#ifdef CONFIG_SMP
++ rseq_migrate(p);
++ /*
++ * Fork balancing, do it here and not earlier because:
++ * - cpus_ptr can change in the fork path
++ * - any previously selected CPU might disappear through hotplug
++ *
++ * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq,
++ * as we're not fully set-up yet.
++ */
++ __set_task_cpu(p, cpu_of(rq));
++#endif
++
++ raw_spin_lock(&rq->lock);
++ update_rq_clock(rq);
++
++ activate_task(p, rq);
++ trace_sched_wakeup_new(p);
++ check_preempt_curr(rq);
++
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++
++#ifdef CONFIG_PREEMPT_NOTIFIERS
++
++static DEFINE_STATIC_KEY_FALSE(preempt_notifier_key);
++
++void preempt_notifier_inc(void)
++{
++ static_branch_inc(&preempt_notifier_key);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_inc);
++
++void preempt_notifier_dec(void)
++{
++ static_branch_dec(&preempt_notifier_key);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_dec);
++
++/**
++ * preempt_notifier_register - tell me when current is being preempted & rescheduled
++ * @notifier: notifier struct to register
++ */
++void preempt_notifier_register(struct preempt_notifier *notifier)
++{
++ if (!static_branch_unlikely(&preempt_notifier_key))
++ WARN(1, "registering preempt_notifier while notifiers disabled\n");
++
++ hlist_add_head(¬ifier->link, ¤t->preempt_notifiers);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_register);
++
++/**
++ * preempt_notifier_unregister - no longer interested in preemption notifications
++ * @notifier: notifier struct to unregister
++ *
++ * This is *not* safe to call from within a preemption notifier.
++ */
++void preempt_notifier_unregister(struct preempt_notifier *notifier)
++{
++ hlist_del(¬ifier->link);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_unregister);
++
++static void __fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++ struct preempt_notifier *notifier;
++
++ hlist_for_each_entry(notifier, &curr->preempt_notifiers, link)
++ notifier->ops->sched_in(notifier, raw_smp_processor_id());
++}
++
++static __always_inline void fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++ if (static_branch_unlikely(&preempt_notifier_key))
++ __fire_sched_in_preempt_notifiers(curr);
++}
++
++static void
++__fire_sched_out_preempt_notifiers(struct task_struct *curr,
++ struct task_struct *next)
++{
++ struct preempt_notifier *notifier;
++
++ hlist_for_each_entry(notifier, &curr->preempt_notifiers, link)
++ notifier->ops->sched_out(notifier, next);
++}
++
++static __always_inline void
++fire_sched_out_preempt_notifiers(struct task_struct *curr,
++ struct task_struct *next)
++{
++ if (static_branch_unlikely(&preempt_notifier_key))
++ __fire_sched_out_preempt_notifiers(curr, next);
++}
++
++#else /* !CONFIG_PREEMPT_NOTIFIERS */
++
++static inline void fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++}
++
++static inline void
++fire_sched_out_preempt_notifiers(struct task_struct *curr,
++ struct task_struct *next)
++{
++}
++
++#endif /* CONFIG_PREEMPT_NOTIFIERS */
++
++static inline void prepare_task(struct task_struct *next)
++{
++ /*
++ * Claim the task as running, we do this before switching to it
++ * such that any running task will have this set.
++ *
++ * See the smp_load_acquire(&p->on_cpu) case in ttwu() and
++ * its ordering comment.
++ */
++ WRITE_ONCE(next->on_cpu, 1);
++}
++
++static inline void finish_task(struct task_struct *prev)
++{
++#ifdef CONFIG_SMP
++ /*
++ * This must be the very last reference to @prev from this CPU. After
++ * p->on_cpu is cleared, the task can be moved to a different CPU. We
++ * must ensure this doesn't happen until the switch is completely
++ * finished.
++ *
++ * In particular, the load of prev->state in finish_task_switch() must
++ * happen before this.
++ *
++ * Pairs with the smp_cond_load_acquire() in try_to_wake_up().
++ */
++ smp_store_release(&prev->on_cpu, 0);
++#else
++ prev->on_cpu = 0;
++#endif
++}
++
++#ifdef CONFIG_SMP
++
++static void do_balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++ void (*func)(struct rq *rq);
++ struct callback_head *next;
++
++ lockdep_assert_held(&rq->lock);
++
++ while (head) {
++ func = (void (*)(struct rq *))head->func;
++ next = head->next;
++ head->next = NULL;
++ head = next;
++
++ func(rq);
++ }
++}
++
++static void balance_push(struct rq *rq);
++
++/*
++ * balance_push_callback is a right abuse of the callback interface and plays
++ * by significantly different rules.
++ *
++ * Where the normal balance_callback's purpose is to be ran in the same context
++ * that queued it (only later, when it's safe to drop rq->lock again),
++ * balance_push_callback is specifically targeted at __schedule().
++ *
++ * This abuse is tolerated because it places all the unlikely/odd cases behind
++ * a single test, namely: rq->balance_callback == NULL.
++ */
++struct callback_head balance_push_callback = {
++ .next = NULL,
++ .func = (void (*)(struct callback_head *))balance_push,
++};
++
++static inline struct callback_head *
++__splice_balance_callbacks(struct rq *rq, bool split)
++{
++ struct callback_head *head = rq->balance_callback;
++
++ if (likely(!head))
++ return NULL;
++
++ lockdep_assert_rq_held(rq);
++ /*
++ * Must not take balance_push_callback off the list when
++ * splice_balance_callbacks() and balance_callbacks() are not
++ * in the same rq->lock section.
++ *
++ * In that case it would be possible for __schedule() to interleave
++ * and observe the list empty.
++ */
++ if (split && head == &balance_push_callback)
++ head = NULL;
++ else
++ rq->balance_callback = NULL;
++
++ return head;
++}
++
++static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
++{
++ return __splice_balance_callbacks(rq, true);
++}
++
++static void __balance_callbacks(struct rq *rq)
++{
++ do_balance_callbacks(rq, __splice_balance_callbacks(rq, false));
++}
++
++static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++ unsigned long flags;
++
++ if (unlikely(head)) {
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ do_balance_callbacks(rq, head);
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++ }
++}
++
++#else
++
++static inline void __balance_callbacks(struct rq *rq)
++{
++}
++
++static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
++{
++ return NULL;
++}
++
++static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++}
++
++#endif
++
++static inline void
++prepare_lock_switch(struct rq *rq, struct task_struct *next)
++{
++ /*
++ * Since the runqueue lock will be released by the next
++ * task (which is an invalid locking op but in the case
++ * of the scheduler it's an obvious special-case), so we
++ * do an early lockdep release here:
++ */
++ spin_release(&rq->lock.dep_map, _THIS_IP_);
++#ifdef CONFIG_DEBUG_SPINLOCK
++ /* this is a valid case when another task releases the spinlock */
++ rq->lock.owner = next;
++#endif
++}
++
++static inline void finish_lock_switch(struct rq *rq)
++{
++ /*
++ * If we are tracking spinlock dependencies then we have to
++ * fix up the runqueue lock - which gets 'carried over' from
++ * prev into current:
++ */
++ spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);
++ __balance_callbacks(rq);
++ raw_spin_unlock_irq(&rq->lock);
++}
++
++/*
++ * NOP if the arch has not defined these:
++ */
++
++#ifndef prepare_arch_switch
++# define prepare_arch_switch(next) do { } while (0)
++#endif
++
++#ifndef finish_arch_post_lock_switch
++# define finish_arch_post_lock_switch() do { } while (0)
++#endif
++
++static inline void kmap_local_sched_out(void)
++{
++#ifdef CONFIG_KMAP_LOCAL
++ if (unlikely(current->kmap_ctrl.idx))
++ __kmap_local_sched_out();
++#endif
++}
++
++static inline void kmap_local_sched_in(void)
++{
++#ifdef CONFIG_KMAP_LOCAL
++ if (unlikely(current->kmap_ctrl.idx))
++ __kmap_local_sched_in();
++#endif
++}
++
++/**
++ * prepare_task_switch - prepare to switch tasks
++ * @rq: the runqueue preparing to switch
++ * @next: the task we are going to switch to.
++ *
++ * This is called with the rq lock held and interrupts off. It must
++ * be paired with a subsequent finish_task_switch after the context
++ * switch.
++ *
++ * prepare_task_switch sets up locking and calls architecture specific
++ * hooks.
++ */
++static inline void
++prepare_task_switch(struct rq *rq, struct task_struct *prev,
++ struct task_struct *next)
++{
++ kcov_prepare_switch(prev);
++ sched_info_switch(rq, prev, next);
++ perf_event_task_sched_out(prev, next);
++ rseq_preempt(prev);
++ fire_sched_out_preempt_notifiers(prev, next);
++ kmap_local_sched_out();
++ prepare_task(next);
++ prepare_arch_switch(next);
++}
++
++/**
++ * finish_task_switch - clean up after a task-switch
++ * @rq: runqueue associated with task-switch
++ * @prev: the thread we just switched away from.
++ *
++ * finish_task_switch must be called after the context switch, paired
++ * with a prepare_task_switch call before the context switch.
++ * finish_task_switch will reconcile locking set up by prepare_task_switch,
++ * and do any other architecture-specific cleanup actions.
++ *
++ * Note that we may have delayed dropping an mm in context_switch(). If
++ * so, we finish that here outside of the runqueue lock. (Doing it
++ * with the lock held can cause deadlocks; see schedule() for
++ * details.)
++ *
++ * The context switch have flipped the stack from under us and restored the
++ * local variables which were saved when this task called schedule() in the
++ * past. prev == current is still correct but we need to recalculate this_rq
++ * because prev may have moved to another CPU.
++ */
++static struct rq *finish_task_switch(struct task_struct *prev)
++ __releases(rq->lock)
++{
++ struct rq *rq = this_rq();
++ struct mm_struct *mm = rq->prev_mm;
++ unsigned int prev_state;
++
++ /*
++ * The previous task will have left us with a preempt_count of 2
++ * because it left us after:
++ *
++ * schedule()
++ * preempt_disable(); // 1
++ * __schedule()
++ * raw_spin_lock_irq(&rq->lock) // 2
++ *
++ * Also, see FORK_PREEMPT_COUNT.
++ */
++ if (WARN_ONCE(preempt_count() != 2*PREEMPT_DISABLE_OFFSET,
++ "corrupted preempt_count: %s/%d/0x%x\n",
++ current->comm, current->pid, preempt_count()))
++ preempt_count_set(FORK_PREEMPT_COUNT);
++
++ rq->prev_mm = NULL;
++
++ /*
++ * A task struct has one reference for the use as "current".
++ * If a task dies, then it sets TASK_DEAD in tsk->state and calls
++ * schedule one last time. The schedule call will never return, and
++ * the scheduled task must drop that reference.
++ *
++ * We must observe prev->state before clearing prev->on_cpu (in
++ * finish_task), otherwise a concurrent wakeup can get prev
++ * running on another CPU and we could rave with its RUNNING -> DEAD
++ * transition, resulting in a double drop.
++ */
++ prev_state = READ_ONCE(prev->__state);
++ vtime_task_switch(prev);
++ perf_event_task_sched_in(prev, current);
++ finish_task(prev);
++ tick_nohz_task_switch();
++ finish_lock_switch(rq);
++ finish_arch_post_lock_switch();
++ kcov_finish_switch(current);
++ /*
++ * kmap_local_sched_out() is invoked with rq::lock held and
++ * interrupts disabled. There is no requirement for that, but the
++ * sched out code does not have an interrupt enabled section.
++ * Restoring the maps on sched in does not require interrupts being
++ * disabled either.
++ */
++ kmap_local_sched_in();
++
++ fire_sched_in_preempt_notifiers(current);
++ /*
++ * When switching through a kernel thread, the loop in
++ * membarrier_{private,global}_expedited() may have observed that
++ * kernel thread and not issued an IPI. It is therefore possible to
++ * schedule between user->kernel->user threads without passing though
++ * switch_mm(). Membarrier requires a barrier after storing to
++ * rq->curr, before returning to userspace, so provide them here:
++ *
++ * - a full memory barrier for {PRIVATE,GLOBAL}_EXPEDITED, implicitly
++ * provided by mmdrop(),
++ * - a sync_core for SYNC_CORE.
++ */
++ if (mm) {
++ membarrier_mm_sync_core_before_usermode(mm);
++ mmdrop_sched(mm);
++ }
++ if (unlikely(prev_state == TASK_DEAD)) {
++ /* Task is done with its stack. */
++ put_task_stack(prev);
++
++ put_task_struct_rcu_user(prev);
++ }
++
++ return rq;
++}
++
++/**
++ * schedule_tail - first thing a freshly forked thread must call.
++ * @prev: the thread we just switched away from.
++ */
++asmlinkage __visible void schedule_tail(struct task_struct *prev)
++ __releases(rq->lock)
++{
++ /*
++ * New tasks start with FORK_PREEMPT_COUNT, see there and
++ * finish_task_switch() for details.
++ *
++ * finish_task_switch() will drop rq->lock() and lower preempt_count
++ * and the preempt_enable() will end up enabling preemption (on
++ * PREEMPT_COUNT kernels).
++ */
++
++ finish_task_switch(prev);
++ preempt_enable();
++
++ if (current->set_child_tid)
++ put_user(task_pid_vnr(current), current->set_child_tid);
++
++ calculate_sigpending();
++}
++
++/*
++ * context_switch - switch to the new MM and the new thread's register state.
++ */
++static __always_inline struct rq *
++context_switch(struct rq *rq, struct task_struct *prev,
++ struct task_struct *next)
++{
++ prepare_task_switch(rq, prev, next);
++
++ /*
++ * For paravirt, this is coupled with an exit in switch_to to
++ * combine the page table reload and the switch backend into
++ * one hypercall.
++ */
++ arch_start_context_switch(prev);
++
++ /*
++ * kernel -> kernel lazy + transfer active
++ * user -> kernel lazy + mmgrab() active
++ *
++ * kernel -> user switch + mmdrop() active
++ * user -> user switch
++ */
++ if (!next->mm) { // to kernel
++ enter_lazy_tlb(prev->active_mm, next);
++
++ next->active_mm = prev->active_mm;
++ if (prev->mm) // from user
++ mmgrab(prev->active_mm);
++ else
++ prev->active_mm = NULL;
++ } else { // to user
++ membarrier_switch_mm(rq, prev->active_mm, next->mm);
++ /*
++ * sys_membarrier() requires an smp_mb() between setting
++ * rq->curr / membarrier_switch_mm() and returning to userspace.
++ *
++ * The below provides this either through switch_mm(), or in
++ * case 'prev->active_mm == next->mm' through
++ * finish_task_switch()'s mmdrop().
++ */
++ switch_mm_irqs_off(prev->active_mm, next->mm, next);
++
++ if (!prev->mm) { // from kernel
++ /* will mmdrop() in finish_task_switch(). */
++ rq->prev_mm = prev->active_mm;
++ prev->active_mm = NULL;
++ }
++ }
++
++ prepare_lock_switch(rq, next);
++
++ /* Here we just switch the register state and the stack. */
++ switch_to(prev, next, prev);
++ barrier();
++
++ return finish_task_switch(prev);
++}
++
++/*
++ * nr_running, nr_uninterruptible and nr_context_switches:
++ *
++ * externally visible scheduler statistics: current number of runnable
++ * threads, total number of context switches performed since bootup.
++ */
++unsigned int nr_running(void)
++{
++ unsigned int i, sum = 0;
++
++ for_each_online_cpu(i)
++ sum += cpu_rq(i)->nr_running;
++
++ return sum;
++}
++
++/*
++ * Check if only the current task is running on the CPU.
++ *
++ * Caution: this function does not check that the caller has disabled
++ * preemption, thus the result might have a time-of-check-to-time-of-use
++ * race. The caller is responsible to use it correctly, for example:
++ *
++ * - from a non-preemptible section (of course)
++ *
++ * - from a thread that is bound to a single CPU
++ *
++ * - in a loop with very short iterations (e.g. a polling loop)
++ */
++bool single_task_running(void)
++{
++ return raw_rq()->nr_running == 1;
++}
++EXPORT_SYMBOL(single_task_running);
++
++unsigned long long nr_context_switches(void)
++{
++ int i;
++ unsigned long long sum = 0;
++
++ for_each_possible_cpu(i)
++ sum += cpu_rq(i)->nr_switches;
++
++ return sum;
++}
++
++/*
++ * Consumers of these two interfaces, like for example the cpuidle menu
++ * governor, are using nonsensical data. Preferring shallow idle state selection
++ * for a CPU that has IO-wait which might not even end up running the task when
++ * it does become runnable.
++ */
++
++unsigned int nr_iowait_cpu(int cpu)
++{
++ return atomic_read(&cpu_rq(cpu)->nr_iowait);
++}
++
++/*
++ * IO-wait accounting, and how it's mostly bollocks (on SMP).
++ *
++ * The idea behind IO-wait account is to account the idle time that we could
++ * have spend running if it were not for IO. That is, if we were to improve the
++ * storage performance, we'd have a proportional reduction in IO-wait time.
++ *
++ * This all works nicely on UP, where, when a task blocks on IO, we account
++ * idle time as IO-wait, because if the storage were faster, it could've been
++ * running and we'd not be idle.
++ *
++ * This has been extended to SMP, by doing the same for each CPU. This however
++ * is broken.
++ *
++ * Imagine for instance the case where two tasks block on one CPU, only the one
++ * CPU will have IO-wait accounted, while the other has regular idle. Even
++ * though, if the storage were faster, both could've ran at the same time,
++ * utilising both CPUs.
++ *
++ * This means, that when looking globally, the current IO-wait accounting on
++ * SMP is a lower bound, by reason of under accounting.
++ *
++ * Worse, since the numbers are provided per CPU, they are sometimes
++ * interpreted per CPU, and that is nonsensical. A blocked task isn't strictly
++ * associated with any one particular CPU, it can wake to another CPU than it
++ * blocked on. This means the per CPU IO-wait number is meaningless.
++ *
++ * Task CPU affinities can make all that even more 'interesting'.
++ */
++
++unsigned int nr_iowait(void)
++{
++ unsigned int i, sum = 0;
++
++ for_each_possible_cpu(i)
++ sum += nr_iowait_cpu(i);
++
++ return sum;
++}
++
++#ifdef CONFIG_SMP
++
++/*
++ * sched_exec - execve() is a valuable balancing opportunity, because at
++ * this point the task has the smallest effective memory and cache
++ * footprint.
++ */
++void sched_exec(void)
++{
++}
++
++#endif
++
++DEFINE_PER_CPU(struct kernel_stat, kstat);
++DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat);
++
++EXPORT_PER_CPU_SYMBOL(kstat);
++EXPORT_PER_CPU_SYMBOL(kernel_cpustat);
++
++static inline void update_curr(struct rq *rq, struct task_struct *p)
++{
++ s64 ns = rq->clock_task - p->last_ran;
++
++ p->sched_time += ns;
++ cgroup_account_cputime(p, ns);
++ account_group_exec_runtime(p, ns);
++
++ p->time_slice -= ns;
++ p->last_ran = rq->clock_task;
++}
++
++/*
++ * Return accounted runtime for the task.
++ * Return separately the current's pending runtime that have not been
++ * accounted yet.
++ */
++unsigned long long task_sched_runtime(struct task_struct *p)
++{
++ unsigned long flags;
++ struct rq *rq;
++ raw_spinlock_t *lock;
++ u64 ns;
++
++#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
++ /*
++ * 64-bit doesn't need locks to atomically read a 64-bit value.
++ * So we have a optimization chance when the task's delta_exec is 0.
++ * Reading ->on_cpu is racy, but this is ok.
++ *
++ * If we race with it leaving CPU, we'll take a lock. So we're correct.
++ * If we race with it entering CPU, unaccounted time is 0. This is
++ * indistinguishable from the read occurring a few cycles earlier.
++ * If we see ->on_cpu without ->on_rq, the task is leaving, and has
++ * been accounted, so we're correct here as well.
++ */
++ if (!p->on_cpu || !task_on_rq_queued(p))
++ return tsk_seruntime(p);
++#endif
++
++ rq = task_access_lock_irqsave(p, &lock, &flags);
++ /*
++ * Must be ->curr _and_ ->on_rq. If dequeued, we would
++ * project cycles that may never be accounted to this
++ * thread, breaking clock_gettime().
++ */
++ if (p == rq->curr && task_on_rq_queued(p)) {
++ update_rq_clock(rq);
++ update_curr(rq, p);
++ }
++ ns = tsk_seruntime(p);
++ task_access_unlock_irqrestore(p, lock, &flags);
++
++ return ns;
++}
++
++/* This manages tasks that have run out of timeslice during a scheduler_tick */
++static inline void scheduler_task_tick(struct rq *rq)
++{
++ struct task_struct *p = rq->curr;
++
++ if (is_idle_task(p))
++ return;
++
++ update_curr(rq, p);
++ cpufreq_update_util(rq, 0);
++
++ /*
++ * Tasks have less than RESCHED_NS of time slice left they will be
++ * rescheduled.
++ */
++ if (p->time_slice >= RESCHED_NS)
++ return;
++ set_tsk_need_resched(p);
++ set_preempt_need_resched();
++}
++
++#ifdef CONFIG_SCHED_DEBUG
++static u64 cpu_resched_latency(struct rq *rq)
++{
++ int latency_warn_ms = READ_ONCE(sysctl_resched_latency_warn_ms);
++ u64 resched_latency, now = rq_clock(rq);
++ static bool warned_once;
++
++ if (sysctl_resched_latency_warn_once && warned_once)
++ return 0;
++
++ if (!need_resched() || !latency_warn_ms)
++ return 0;
++
++ if (system_state == SYSTEM_BOOTING)
++ return 0;
++
++ if (!rq->last_seen_need_resched_ns) {
++ rq->last_seen_need_resched_ns = now;
++ rq->ticks_without_resched = 0;
++ return 0;
++ }
++
++ rq->ticks_without_resched++;
++ resched_latency = now - rq->last_seen_need_resched_ns;
++ if (resched_latency <= latency_warn_ms * NSEC_PER_MSEC)
++ return 0;
++
++ warned_once = true;
++
++ return resched_latency;
++}
++
++static int __init setup_resched_latency_warn_ms(char *str)
++{
++ long val;
++
++ if ((kstrtol(str, 0, &val))) {
++ pr_warn("Unable to set resched_latency_warn_ms\n");
++ return 1;
++ }
++
++ sysctl_resched_latency_warn_ms = val;
++ return 1;
++}
++__setup("resched_latency_warn_ms=", setup_resched_latency_warn_ms);
++#else
++static inline u64 cpu_resched_latency(struct rq *rq) { return 0; }
++#endif /* CONFIG_SCHED_DEBUG */
++
++/*
++ * This function gets called by the timer code, with HZ frequency.
++ * We call it with interrupts disabled.
++ */
++void scheduler_tick(void)
++{
++ int cpu __maybe_unused = smp_processor_id();
++ struct rq *rq = cpu_rq(cpu);
++ u64 resched_latency;
++
++ arch_scale_freq_tick();
++ sched_clock_tick();
++
++ raw_spin_lock(&rq->lock);
++ update_rq_clock(rq);
++
++ scheduler_task_tick(rq);
++ if (sched_feat(LATENCY_WARN))
++ resched_latency = cpu_resched_latency(rq);
++ calc_global_load_tick(rq);
++
++ rq->last_tick = rq->clock;
++ raw_spin_unlock(&rq->lock);
++
++ if (sched_feat(LATENCY_WARN) && resched_latency)
++ resched_latency_warn(cpu, resched_latency);
++
++ perf_event_task_tick();
++}
++
++#ifdef CONFIG_SCHED_SMT
++static inline int sg_balance_cpu_stop(void *data)
++{
++ struct rq *rq = this_rq();
++ struct task_struct *p = data;
++ cpumask_t tmp;
++ unsigned long flags;
++
++ local_irq_save(flags);
++
++ raw_spin_lock(&p->pi_lock);
++ raw_spin_lock(&rq->lock);
++
++ rq->active_balance = 0;
++ /* _something_ may have changed the task, double check again */
++ if (task_on_rq_queued(p) && task_rq(p) == rq &&
++ cpumask_and(&tmp, p->cpus_ptr, &sched_sg_idle_mask) &&
++ !is_migration_disabled(p)) {
++ int cpu = cpu_of(rq);
++ int dcpu = __best_mask_cpu(&tmp, per_cpu(sched_cpu_llc_mask, cpu));
++ rq = move_queued_task(rq, p, dcpu);
++ }
++
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock(&p->pi_lock);
++
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++/* sg_balance_trigger - trigger slibing group balance for @cpu */
++static inline int sg_balance_trigger(const int cpu)
++{
++ struct rq *rq= cpu_rq(cpu);
++ unsigned long flags;
++ struct task_struct *curr;
++ int res;
++
++ if (!raw_spin_trylock_irqsave(&rq->lock, flags))
++ return 0;
++ curr = rq->curr;
++ res = (!is_idle_task(curr)) && (1 == rq->nr_running) &&\
++ cpumask_intersects(curr->cpus_ptr, &sched_sg_idle_mask) &&\
++ !is_migration_disabled(curr) && (!rq->active_balance);
++
++ if (res)
++ rq->active_balance = 1;
++
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++ if (res)
++ stop_one_cpu_nowait(cpu, sg_balance_cpu_stop, curr,
++ &rq->active_balance_work);
++ return res;
++}
++
++/*
++ * sg_balance - slibing group balance check for run queue @rq
++ */
++static inline void sg_balance(struct rq *rq)
++{
++ cpumask_t chk;
++ int cpu = cpu_of(rq);
++
++ /* exit when cpu is offline */
++ if (unlikely(!rq->online))
++ return;
++
++ /*
++ * Only cpu in slibing idle group will do the checking and then
++ * find potential cpus which can migrate the current running task
++ */
++ if (cpumask_test_cpu(cpu, &sched_sg_idle_mask) &&
++ cpumask_andnot(&chk, cpu_online_mask, sched_rq_watermark) &&
++ cpumask_andnot(&chk, &chk, &sched_rq_pending_mask)) {
++ int i;
++
++ for_each_cpu_wrap(i, &chk, cpu) {
++ if (cpumask_subset(cpu_smt_mask(i), &chk) &&
++ sg_balance_trigger(i))
++ return;
++ }
++ }
++}
++#endif /* CONFIG_SCHED_SMT */
++
++#ifdef CONFIG_NO_HZ_FULL
++
++struct tick_work {
++ int cpu;
++ atomic_t state;
++ struct delayed_work work;
++};
++/* Values for ->state, see diagram below. */
++#define TICK_SCHED_REMOTE_OFFLINE 0
++#define TICK_SCHED_REMOTE_OFFLINING 1
++#define TICK_SCHED_REMOTE_RUNNING 2
++
++/*
++ * State diagram for ->state:
++ *
++ *
++ * TICK_SCHED_REMOTE_OFFLINE
++ * | ^
++ * | |
++ * | | sched_tick_remote()
++ * | |
++ * | |
++ * +--TICK_SCHED_REMOTE_OFFLINING
++ * | ^
++ * | |
++ * sched_tick_start() | | sched_tick_stop()
++ * | |
++ * V |
++ * TICK_SCHED_REMOTE_RUNNING
++ *
++ *
++ * Other transitions get WARN_ON_ONCE(), except that sched_tick_remote()
++ * and sched_tick_start() are happy to leave the state in RUNNING.
++ */
++
++static struct tick_work __percpu *tick_work_cpu;
++
++static void sched_tick_remote(struct work_struct *work)
++{
++ struct delayed_work *dwork = to_delayed_work(work);
++ struct tick_work *twork = container_of(dwork, struct tick_work, work);
++ int cpu = twork->cpu;
++ struct rq *rq = cpu_rq(cpu);
++ struct task_struct *curr;
++ unsigned long flags;
++ u64 delta;
++ int os;
++
++ /*
++ * Handle the tick only if it appears the remote CPU is running in full
++ * dynticks mode. The check is racy by nature, but missing a tick or
++ * having one too much is no big deal because the scheduler tick updates
++ * statistics and checks timeslices in a time-independent way, regardless
++ * of when exactly it is running.
++ */
++ if (!tick_nohz_tick_stopped_cpu(cpu))
++ goto out_requeue;
++
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ curr = rq->curr;
++ if (cpu_is_offline(cpu))
++ goto out_unlock;
++
++ update_rq_clock(rq);
++ if (!is_idle_task(curr)) {
++ /*
++ * Make sure the next tick runs within a reasonable
++ * amount of time.
++ */
++ delta = rq_clock_task(rq) - curr->last_ran;
++ WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3);
++ }
++ scheduler_task_tick(rq);
++
++ calc_load_nohz_remote(rq);
++out_unlock:
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++out_requeue:
++ /*
++ * Run the remote tick once per second (1Hz). This arbitrary
++ * frequency is large enough to avoid overload but short enough
++ * to keep scheduler internal stats reasonably up to date. But
++ * first update state to reflect hotplug activity if required.
++ */
++ os = atomic_fetch_add_unless(&twork->state, -1, TICK_SCHED_REMOTE_RUNNING);
++ WARN_ON_ONCE(os == TICK_SCHED_REMOTE_OFFLINE);
++ if (os == TICK_SCHED_REMOTE_RUNNING)
++ queue_delayed_work(system_unbound_wq, dwork, HZ);
++}
++
++static void sched_tick_start(int cpu)
++{
++ int os;
++ struct tick_work *twork;
++
++ if (housekeeping_cpu(cpu, HK_TYPE_TICK))
++ return;
++
++ WARN_ON_ONCE(!tick_work_cpu);
++
++ twork = per_cpu_ptr(tick_work_cpu, cpu);
++ os = atomic_xchg(&twork->state, TICK_SCHED_REMOTE_RUNNING);
++ WARN_ON_ONCE(os == TICK_SCHED_REMOTE_RUNNING);
++ if (os == TICK_SCHED_REMOTE_OFFLINE) {
++ twork->cpu = cpu;
++ INIT_DELAYED_WORK(&twork->work, sched_tick_remote);
++ queue_delayed_work(system_unbound_wq, &twork->work, HZ);
++ }
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static void sched_tick_stop(int cpu)
++{
++ struct tick_work *twork;
++
++ if (housekeeping_cpu(cpu, HK_TYPE_TICK))
++ return;
++
++ WARN_ON_ONCE(!tick_work_cpu);
++
++ twork = per_cpu_ptr(tick_work_cpu, cpu);
++ cancel_delayed_work_sync(&twork->work);
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++int __init sched_tick_offload_init(void)
++{
++ tick_work_cpu = alloc_percpu(struct tick_work);
++ BUG_ON(!tick_work_cpu);
++ return 0;
++}
++
++#else /* !CONFIG_NO_HZ_FULL */
++static inline void sched_tick_start(int cpu) { }
++static inline void sched_tick_stop(int cpu) { }
++#endif
++
++#if defined(CONFIG_PREEMPTION) && (defined(CONFIG_DEBUG_PREEMPT) || \
++ defined(CONFIG_PREEMPT_TRACER))
++/*
++ * If the value passed in is equal to the current preempt count
++ * then we just disabled preemption. Start timing the latency.
++ */
++static inline void preempt_latency_start(int val)
++{
++ if (preempt_count() == val) {
++ unsigned long ip = get_lock_parent_ip();
++#ifdef CONFIG_DEBUG_PREEMPT
++ current->preempt_disable_ip = ip;
++#endif
++ trace_preempt_off(CALLER_ADDR0, ip);
++ }
++}
++
++void preempt_count_add(int val)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++ /*
++ * Underflow?
++ */
++ if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
++ return;
++#endif
++ __preempt_count_add(val);
++#ifdef CONFIG_DEBUG_PREEMPT
++ /*
++ * Spinlock count overflowing soon?
++ */
++ DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >=
++ PREEMPT_MASK - 10);
++#endif
++ preempt_latency_start(val);
++}
++EXPORT_SYMBOL(preempt_count_add);
++NOKPROBE_SYMBOL(preempt_count_add);
++
++/*
++ * If the value passed in equals to the current preempt count
++ * then we just enabled preemption. Stop timing the latency.
++ */
++static inline void preempt_latency_stop(int val)
++{
++ if (preempt_count() == val)
++ trace_preempt_on(CALLER_ADDR0, get_lock_parent_ip());
++}
++
++void preempt_count_sub(int val)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++ /*
++ * Underflow?
++ */
++ if (DEBUG_LOCKS_WARN_ON(val > preempt_count()))
++ return;
++ /*
++ * Is the spinlock portion underflowing?
++ */
++ if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
++ !(preempt_count() & PREEMPT_MASK)))
++ return;
++#endif
++
++ preempt_latency_stop(val);
++ __preempt_count_sub(val);
++}
++EXPORT_SYMBOL(preempt_count_sub);
++NOKPROBE_SYMBOL(preempt_count_sub);
++
++#else
++static inline void preempt_latency_start(int val) { }
++static inline void preempt_latency_stop(int val) { }
++#endif
++
++static inline unsigned long get_preempt_disable_ip(struct task_struct *p)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++ return p->preempt_disable_ip;
++#else
++ return 0;
++#endif
++}
++
++/*
++ * Print scheduling while atomic bug:
++ */
++static noinline void __schedule_bug(struct task_struct *prev)
++{
++ /* Save this before calling printk(), since that will clobber it */
++ unsigned long preempt_disable_ip = get_preempt_disable_ip(current);
++
++ if (oops_in_progress)
++ return;
++
++ printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n",
++ prev->comm, prev->pid, preempt_count());
++
++ debug_show_held_locks(prev);
++ print_modules();
++ if (irqs_disabled())
++ print_irqtrace_events(prev);
++ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)
++ && in_atomic_preempt_off()) {
++ pr_err("Preemption disabled at:");
++ print_ip_sym(KERN_ERR, preempt_disable_ip);
++ }
++ if (panic_on_warn)
++ panic("scheduling while atomic\n");
++
++ dump_stack();
++ add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++
++/*
++ * Various schedule()-time debugging checks and statistics:
++ */
++static inline void schedule_debug(struct task_struct *prev, bool preempt)
++{
++#ifdef CONFIG_SCHED_STACK_END_CHECK
++ if (task_stack_end_corrupted(prev))
++ panic("corrupted stack end detected inside scheduler\n");
++
++ if (task_scs_end_corrupted(prev))
++ panic("corrupted shadow stack detected inside scheduler\n");
++#endif
++
++#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
++ if (!preempt && READ_ONCE(prev->__state) && prev->non_block_count) {
++ printk(KERN_ERR "BUG: scheduling in a non-blocking section: %s/%d/%i\n",
++ prev->comm, prev->pid, prev->non_block_count);
++ dump_stack();
++ add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++ }
++#endif
++
++ if (unlikely(in_atomic_preempt_off())) {
++ __schedule_bug(prev);
++ preempt_count_set(PREEMPT_DISABLED);
++ }
++ rcu_sleep_check();
++ SCHED_WARN_ON(ct_state() == CONTEXT_USER);
++
++ profile_hit(SCHED_PROFILING, __builtin_return_address(0));
++
++ schedstat_inc(this_rq()->sched_count);
++}
++
++/*
++ * Compile time debug macro
++ * #define ALT_SCHED_DEBUG
++ */
++
++#ifdef ALT_SCHED_DEBUG
++void alt_sched_debug(void)
++{
++ printk(KERN_INFO "sched: pending: 0x%04lx, idle: 0x%04lx, sg_idle: 0x%04lx\n",
++ sched_rq_pending_mask.bits[0],
++ sched_rq_watermark[0].bits[0],
++ sched_sg_idle_mask.bits[0]);
++}
++#else
++inline void alt_sched_debug(void) {}
++#endif
++
++#ifdef CONFIG_SMP
++
++#define SCHED_RQ_NR_MIGRATION (32U)
++/*
++ * Migrate pending tasks in @rq to @dest_cpu
++ * Will try to migrate mininal of half of @rq nr_running tasks and
++ * SCHED_RQ_NR_MIGRATION to @dest_cpu
++ */
++static inline int
++migrate_pending_tasks(struct rq *rq, struct rq *dest_rq, const int dest_cpu)
++{
++ struct task_struct *p, *skip = rq->curr;
++ int nr_migrated = 0;
++ int nr_tries = min(rq->nr_running / 2, SCHED_RQ_NR_MIGRATION);
++
++ while (skip != rq->idle && nr_tries &&
++ (p = sched_rq_next_task(skip, rq)) != rq->idle) {
++ skip = sched_rq_next_task(p, rq);
++ if (cpumask_test_cpu(dest_cpu, p->cpus_ptr)) {
++ __SCHED_DEQUEUE_TASK(p, rq, 0);
++ set_task_cpu(p, dest_cpu);
++ sched_task_sanity_check(p, dest_rq);
++ __SCHED_ENQUEUE_TASK(p, dest_rq, 0);
++ nr_migrated++;
++ }
++ nr_tries--;
++ }
++
++ return nr_migrated;
++}
++
++static inline int take_other_rq_tasks(struct rq *rq, int cpu)
++{
++ struct cpumask *topo_mask, *end_mask;
++
++ if (unlikely(!rq->online))
++ return 0;
++
++ if (cpumask_empty(&sched_rq_pending_mask))
++ return 0;
++
++ topo_mask = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++ end_mask = per_cpu(sched_cpu_topo_end_mask, cpu);
++ do {
++ int i;
++ for_each_cpu_and(i, &sched_rq_pending_mask, topo_mask) {
++ int nr_migrated;
++ struct rq *src_rq;
++
++ src_rq = cpu_rq(i);
++ if (!do_raw_spin_trylock(&src_rq->lock))
++ continue;
++ spin_acquire(&src_rq->lock.dep_map,
++ SINGLE_DEPTH_NESTING, 1, _RET_IP_);
++
++ if ((nr_migrated = migrate_pending_tasks(src_rq, rq, cpu))) {
++ src_rq->nr_running -= nr_migrated;
++ if (src_rq->nr_running < 2)
++ cpumask_clear_cpu(i, &sched_rq_pending_mask);
++
++ rq->nr_running += nr_migrated;
++ if (rq->nr_running > 1)
++ cpumask_set_cpu(cpu, &sched_rq_pending_mask);
++
++ cpufreq_update_util(rq, 0);
++
++ spin_release(&src_rq->lock.dep_map, _RET_IP_);
++ do_raw_spin_unlock(&src_rq->lock);
++
++ return 1;
++ }
++
++ spin_release(&src_rq->lock.dep_map, _RET_IP_);
++ do_raw_spin_unlock(&src_rq->lock);
++ }
++ } while (++topo_mask < end_mask);
++
++ return 0;
++}
++#endif
++
++/*
++ * Timeslices below RESCHED_NS are considered as good as expired as there's no
++ * point rescheduling when there's so little time left.
++ */
++static inline void check_curr(struct task_struct *p, struct rq *rq)
++{
++ if (unlikely(rq->idle == p))
++ return;
++
++ update_curr(rq, p);
++
++ if (p->time_slice < RESCHED_NS)
++ time_slice_expired(p, rq);
++}
++
++static inline struct task_struct *
++choose_next_task(struct rq *rq, int cpu, struct task_struct *prev)
++{
++ struct task_struct *next;
++
++ if (unlikely(rq->skip)) {
++ next = rq_runnable_task(rq);
++ if (next == rq->idle) {
++#ifdef CONFIG_SMP
++ if (!take_other_rq_tasks(rq, cpu)) {
++#endif
++ rq->skip = NULL;
++ schedstat_inc(rq->sched_goidle);
++ return next;
++#ifdef CONFIG_SMP
++ }
++ next = rq_runnable_task(rq);
++#endif
++ }
++ rq->skip = NULL;
++#ifdef CONFIG_HIGH_RES_TIMERS
++ hrtick_start(rq, next->time_slice);
++#endif
++ return next;
++ }
++
++ next = sched_rq_first_task(rq);
++ if (next == rq->idle) {
++#ifdef CONFIG_SMP
++ if (!take_other_rq_tasks(rq, cpu)) {
++#endif
++ schedstat_inc(rq->sched_goidle);
++ /*printk(KERN_INFO "sched: choose_next_task(%d) idle %px\n", cpu, next);*/
++ return next;
++#ifdef CONFIG_SMP
++ }
++ next = sched_rq_first_task(rq);
++#endif
++ }
++#ifdef CONFIG_HIGH_RES_TIMERS
++ hrtick_start(rq, next->time_slice);
++#endif
++ /*printk(KERN_INFO "sched: choose_next_task(%d) next %px\n", cpu,
++ * next);*/
++ return next;
++}
++
++/*
++ * Constants for the sched_mode argument of __schedule().
++ *
++ * The mode argument allows RT enabled kernels to differentiate a
++ * preemption from blocking on an 'sleeping' spin/rwlock. Note that
++ * SM_MASK_PREEMPT for !RT has all bits set, which allows the compiler to
++ * optimize the AND operation out and just check for zero.
++ */
++#define SM_NONE 0x0
++#define SM_PREEMPT 0x1
++#define SM_RTLOCK_WAIT 0x2
++
++#ifndef CONFIG_PREEMPT_RT
++# define SM_MASK_PREEMPT (~0U)
++#else
++# define SM_MASK_PREEMPT SM_PREEMPT
++#endif
++
++/*
++ * schedule() is the main scheduler function.
++ *
++ * The main means of driving the scheduler and thus entering this function are:
++ *
++ * 1. Explicit blocking: mutex, semaphore, waitqueue, etc.
++ *
++ * 2. TIF_NEED_RESCHED flag is checked on interrupt and userspace return
++ * paths. For example, see arch/x86/entry_64.S.
++ *
++ * To drive preemption between tasks, the scheduler sets the flag in timer
++ * interrupt handler scheduler_tick().
++ *
++ * 3. Wakeups don't really cause entry into schedule(). They add a
++ * task to the run-queue and that's it.
++ *
++ * Now, if the new task added to the run-queue preempts the current
++ * task, then the wakeup sets TIF_NEED_RESCHED and schedule() gets
++ * called on the nearest possible occasion:
++ *
++ * - If the kernel is preemptible (CONFIG_PREEMPTION=y):
++ *
++ * - in syscall or exception context, at the next outmost
++ * preempt_enable(). (this might be as soon as the wake_up()'s
++ * spin_unlock()!)
++ *
++ * - in IRQ context, return from interrupt-handler to
++ * preemptible context
++ *
++ * - If the kernel is not preemptible (CONFIG_PREEMPTION is not set)
++ * then at the next:
++ *
++ * - cond_resched() call
++ * - explicit schedule() call
++ * - return from syscall or exception to user-space
++ * - return from interrupt-handler to user-space
++ *
++ * WARNING: must be called with preemption disabled!
++ */
++static void __sched notrace __schedule(unsigned int sched_mode)
++{
++ struct task_struct *prev, *next;
++ unsigned long *switch_count;
++ unsigned long prev_state;
++ struct rq *rq;
++ int cpu;
++ int deactivated = 0;
++
++ cpu = smp_processor_id();
++ rq = cpu_rq(cpu);
++ prev = rq->curr;
++
++ schedule_debug(prev, !!sched_mode);
++
++ /* by passing sched_feat(HRTICK) checking which Alt schedule FW doesn't support */
++ hrtick_clear(rq);
++
++ local_irq_disable();
++ rcu_note_context_switch(!!sched_mode);
++
++ /*
++ * Make sure that signal_pending_state()->signal_pending() below
++ * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)
++ * done by the caller to avoid the race with signal_wake_up():
++ *
++ * __set_current_state(@state) signal_wake_up()
++ * schedule() set_tsk_thread_flag(p, TIF_SIGPENDING)
++ * wake_up_state(p, state)
++ * LOCK rq->lock LOCK p->pi_state
++ * smp_mb__after_spinlock() smp_mb__after_spinlock()
++ * if (signal_pending_state()) if (p->state & @state)
++ *
++ * Also, the membarrier system call requires a full memory barrier
++ * after coming from user-space, before storing to rq->curr.
++ */
++ raw_spin_lock(&rq->lock);
++ smp_mb__after_spinlock();
++
++ update_rq_clock(rq);
++
++ switch_count = &prev->nivcsw;
++ /*
++ * We must load prev->state once (task_struct::state is volatile), such
++ * that we form a control dependency vs deactivate_task() below.
++ */
++ prev_state = READ_ONCE(prev->__state);
++ if (!(sched_mode & SM_MASK_PREEMPT) && prev_state) {
++ if (signal_pending_state(prev_state, prev)) {
++ WRITE_ONCE(prev->__state, TASK_RUNNING);
++ } else {
++ prev->sched_contributes_to_load =
++ (prev_state & TASK_UNINTERRUPTIBLE) &&
++ !(prev_state & TASK_NOLOAD) &&
++ !(prev->flags & PF_FROZEN);
++
++ if (prev->sched_contributes_to_load)
++ rq->nr_uninterruptible++;
++
++ /*
++ * __schedule() ttwu()
++ * prev_state = prev->state; if (p->on_rq && ...)
++ * if (prev_state) goto out;
++ * p->on_rq = 0; smp_acquire__after_ctrl_dep();
++ * p->state = TASK_WAKING
++ *
++ * Where __schedule() and ttwu() have matching control dependencies.
++ *
++ * After this, schedule() must not care about p->state any more.
++ */
++ sched_task_deactivate(prev, rq);
++ deactivate_task(prev, rq);
++ deactivated = 1;
++
++ if (prev->in_iowait) {
++ atomic_inc(&rq->nr_iowait);
++ delayacct_blkio_start();
++ }
++ }
++ switch_count = &prev->nvcsw;
++ }
++
++ check_curr(prev, rq);
++
++ next = choose_next_task(rq, cpu, prev);
++ clear_tsk_need_resched(prev);
++ clear_preempt_need_resched();
++#ifdef CONFIG_SCHED_DEBUG
++ rq->last_seen_need_resched_ns = 0;
++#endif
++
++ if (likely(prev != next)) {
++ if (deactivated)
++ update_sched_rq_watermark(rq);
++ next->last_ran = rq->clock_task;
++ rq->last_ts_switch = rq->clock;
++
++ rq->nr_switches++;
++ /*
++ * RCU users of rcu_dereference(rq->curr) may not see
++ * changes to task_struct made by pick_next_task().
++ */
++ RCU_INIT_POINTER(rq->curr, next);
++ /*
++ * The membarrier system call requires each architecture
++ * to have a full memory barrier after updating
++ * rq->curr, before returning to user-space.
++ *
++ * Here are the schemes providing that barrier on the
++ * various architectures:
++ * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC.
++ * switch_mm() rely on membarrier_arch_switch_mm() on PowerPC.
++ * - finish_lock_switch() for weakly-ordered
++ * architectures where spin_unlock is a full barrier,
++ * - switch_to() for arm64 (weakly-ordered, spin_unlock
++ * is a RELEASE barrier),
++ */
++ ++*switch_count;
++
++ psi_sched_switch(prev, next, !task_on_rq_queued(prev));
++
++ trace_sched_switch(sched_mode & SM_MASK_PREEMPT, prev, next, prev_state);
++
++ /* Also unlocks the rq: */
++ rq = context_switch(rq, prev, next);
++ } else {
++ __balance_callbacks(rq);
++ raw_spin_unlock_irq(&rq->lock);
++ }
++
++#ifdef CONFIG_SCHED_SMT
++ sg_balance(rq);
++#endif
++}
++
++void __noreturn do_task_dead(void)
++{
++ /* Causes final put_task_struct in finish_task_switch(): */
++ set_special_state(TASK_DEAD);
++
++ /* Tell freezer to ignore us: */
++ current->flags |= PF_NOFREEZE;
++
++ __schedule(SM_NONE);
++ BUG();
++
++ /* Avoid "noreturn function does return" - but don't continue if BUG() is a NOP: */
++ for (;;)
++ cpu_relax();
++}
++
++static inline void sched_submit_work(struct task_struct *tsk)
++{
++ unsigned int task_flags;
++
++ if (task_is_running(tsk))
++ return;
++
++ task_flags = tsk->flags;
++ /*
++ * If a worker goes to sleep, notify and ask workqueue whether it
++ * wants to wake up a task to maintain concurrency.
++ */
++ if (task_flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
++ if (task_flags & PF_WQ_WORKER)
++ wq_worker_sleeping(tsk);
++ else
++ io_wq_worker_sleeping(tsk);
++ }
++
++ /*
++ * spinlock and rwlock must not flush block requests. This will
++ * deadlock if the callback attempts to acquire a lock which is
++ * already acquired.
++ */
++ SCHED_WARN_ON(current->__state & TASK_RTLOCK_WAIT);
++
++ /*
++ * If we are going to sleep and we have plugged IO queued,
++ * make sure to submit it to avoid deadlocks.
++ */
++ blk_flush_plug(tsk->plug, true);
++}
++
++static void sched_update_worker(struct task_struct *tsk)
++{
++ if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
++ if (tsk->flags & PF_WQ_WORKER)
++ wq_worker_running(tsk);
++ else
++ io_wq_worker_running(tsk);
++ }
++}
++
++asmlinkage __visible void __sched schedule(void)
++{
++ struct task_struct *tsk = current;
++
++ sched_submit_work(tsk);
++ do {
++ preempt_disable();
++ __schedule(SM_NONE);
++ sched_preempt_enable_no_resched();
++ } while (need_resched());
++ sched_update_worker(tsk);
++}
++EXPORT_SYMBOL(schedule);
++
++/*
++ * synchronize_rcu_tasks() makes sure that no task is stuck in preempted
++ * state (have scheduled out non-voluntarily) by making sure that all
++ * tasks have either left the run queue or have gone into user space.
++ * As idle tasks do not do either, they must not ever be preempted
++ * (schedule out non-voluntarily).
++ *
++ * schedule_idle() is similar to schedule_preempt_disable() except that it
++ * never enables preemption because it does not call sched_submit_work().
++ */
++void __sched schedule_idle(void)
++{
++ /*
++ * As this skips calling sched_submit_work(), which the idle task does
++ * regardless because that function is a nop when the task is in a
++ * TASK_RUNNING state, make sure this isn't used someplace that the
++ * current task can be in any other state. Note, idle is always in the
++ * TASK_RUNNING state.
++ */
++ WARN_ON_ONCE(current->__state);
++ do {
++ __schedule(SM_NONE);
++ } while (need_resched());
++}
++
++#if defined(CONFIG_CONTEXT_TRACKING_USER) && !defined(CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK)
++asmlinkage __visible void __sched schedule_user(void)
++{
++ /*
++ * If we come here after a random call to set_need_resched(),
++ * or we have been woken up remotely but the IPI has not yet arrived,
++ * we haven't yet exited the RCU idle mode. Do it here manually until
++ * we find a better solution.
++ *
++ * NB: There are buggy callers of this function. Ideally we
++ * should warn if prev_state != CONTEXT_USER, but that will trigger
++ * too frequently to make sense yet.
++ */
++ enum ctx_state prev_state = exception_enter();
++ schedule();
++ exception_exit(prev_state);
++}
++#endif
++
++/**
++ * schedule_preempt_disabled - called with preemption disabled
++ *
++ * Returns with preemption disabled. Note: preempt_count must be 1
++ */
++void __sched schedule_preempt_disabled(void)
++{
++ sched_preempt_enable_no_resched();
++ schedule();
++ preempt_disable();
++}
++
++#ifdef CONFIG_PREEMPT_RT
++void __sched notrace schedule_rtlock(void)
++{
++ do {
++ preempt_disable();
++ __schedule(SM_RTLOCK_WAIT);
++ sched_preempt_enable_no_resched();
++ } while (need_resched());
++}
++NOKPROBE_SYMBOL(schedule_rtlock);
++#endif
++
++static void __sched notrace preempt_schedule_common(void)
++{
++ do {
++ /*
++ * Because the function tracer can trace preempt_count_sub()
++ * and it also uses preempt_enable/disable_notrace(), if
++ * NEED_RESCHED is set, the preempt_enable_notrace() called
++ * by the function tracer will call this function again and
++ * cause infinite recursion.
++ *
++ * Preemption must be disabled here before the function
++ * tracer can trace. Break up preempt_disable() into two
++ * calls. One to disable preemption without fear of being
++ * traced. The other to still record the preemption latency,
++ * which can also be traced by the function tracer.
++ */
++ preempt_disable_notrace();
++ preempt_latency_start(1);
++ __schedule(SM_PREEMPT);
++ preempt_latency_stop(1);
++ preempt_enable_no_resched_notrace();
++
++ /*
++ * Check again in case we missed a preemption opportunity
++ * between schedule and now.
++ */
++ } while (need_resched());
++}
++
++#ifdef CONFIG_PREEMPTION
++/*
++ * This is the entry point to schedule() from in-kernel preemption
++ * off of preempt_enable.
++ */
++asmlinkage __visible void __sched notrace preempt_schedule(void)
++{
++ /*
++ * If there is a non-zero preempt_count or interrupts are disabled,
++ * we do not want to preempt the current task. Just return..
++ */
++ if (likely(!preemptible()))
++ return;
++
++ preempt_schedule_common();
++}
++NOKPROBE_SYMBOL(preempt_schedule);
++EXPORT_SYMBOL(preempt_schedule);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#ifndef preempt_schedule_dynamic_enabled
++#define preempt_schedule_dynamic_enabled preempt_schedule
++#define preempt_schedule_dynamic_disabled NULL
++#endif
++DEFINE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled);
++EXPORT_STATIC_CALL_TRAMP(preempt_schedule);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule);
++void __sched notrace dynamic_preempt_schedule(void)
++{
++ if (!static_branch_unlikely(&sk_dynamic_preempt_schedule))
++ return;
++ preempt_schedule();
++}
++NOKPROBE_SYMBOL(dynamic_preempt_schedule);
++EXPORT_SYMBOL(dynamic_preempt_schedule);
++#endif
++#endif
++
++/**
++ * preempt_schedule_notrace - preempt_schedule called by tracing
++ *
++ * The tracing infrastructure uses preempt_enable_notrace to prevent
++ * recursion and tracing preempt enabling caused by the tracing
++ * infrastructure itself. But as tracing can happen in areas coming
++ * from userspace or just about to enter userspace, a preempt enable
++ * can occur before user_exit() is called. This will cause the scheduler
++ * to be called when the system is still in usermode.
++ *
++ * To prevent this, the preempt_enable_notrace will use this function
++ * instead of preempt_schedule() to exit user context if needed before
++ * calling the scheduler.
++ */
++asmlinkage __visible void __sched notrace preempt_schedule_notrace(void)
++{
++ enum ctx_state prev_ctx;
++
++ if (likely(!preemptible()))
++ return;
++
++ do {
++ /*
++ * Because the function tracer can trace preempt_count_sub()
++ * and it also uses preempt_enable/disable_notrace(), if
++ * NEED_RESCHED is set, the preempt_enable_notrace() called
++ * by the function tracer will call this function again and
++ * cause infinite recursion.
++ *
++ * Preemption must be disabled here before the function
++ * tracer can trace. Break up preempt_disable() into two
++ * calls. One to disable preemption without fear of being
++ * traced. The other to still record the preemption latency,
++ * which can also be traced by the function tracer.
++ */
++ preempt_disable_notrace();
++ preempt_latency_start(1);
++ /*
++ * Needs preempt disabled in case user_exit() is traced
++ * and the tracer calls preempt_enable_notrace() causing
++ * an infinite recursion.
++ */
++ prev_ctx = exception_enter();
++ __schedule(SM_PREEMPT);
++ exception_exit(prev_ctx);
++
++ preempt_latency_stop(1);
++ preempt_enable_no_resched_notrace();
++ } while (need_resched());
++}
++EXPORT_SYMBOL_GPL(preempt_schedule_notrace);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#ifndef preempt_schedule_notrace_dynamic_enabled
++#define preempt_schedule_notrace_dynamic_enabled preempt_schedule_notrace
++#define preempt_schedule_notrace_dynamic_disabled NULL
++#endif
++DEFINE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled);
++EXPORT_STATIC_CALL_TRAMP(preempt_schedule_notrace);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule_notrace);
++void __sched notrace dynamic_preempt_schedule_notrace(void)
++{
++ if (!static_branch_unlikely(&sk_dynamic_preempt_schedule_notrace))
++ return;
++ preempt_schedule_notrace();
++}
++NOKPROBE_SYMBOL(dynamic_preempt_schedule_notrace);
++EXPORT_SYMBOL(dynamic_preempt_schedule_notrace);
++#endif
++#endif
++
++#endif /* CONFIG_PREEMPTION */
++
++/*
++ * This is the entry point to schedule() from kernel preemption
++ * off of irq context.
++ * Note, that this is called and return with irqs disabled. This will
++ * protect us against recursive calling from irq.
++ */
++asmlinkage __visible void __sched preempt_schedule_irq(void)
++{
++ enum ctx_state prev_state;
++
++ /* Catch callers which need to be fixed */
++ BUG_ON(preempt_count() || !irqs_disabled());
++
++ prev_state = exception_enter();
++
++ do {
++ preempt_disable();
++ local_irq_enable();
++ __schedule(SM_PREEMPT);
++ local_irq_disable();
++ sched_preempt_enable_no_resched();
++ } while (need_resched());
++
++ exception_exit(prev_state);
++}
++
++int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags,
++ void *key)
++{
++ WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~WF_SYNC);
++ return try_to_wake_up(curr->private, mode, wake_flags);
++}
++EXPORT_SYMBOL(default_wake_function);
++
++static inline void check_task_changed(struct task_struct *p, struct rq *rq)
++{
++ int idx;
++
++ /* Trigger resched if task sched_prio has been modified. */
++ if (task_on_rq_queued(p) && (idx = task_sched_prio_idx(p, rq)) != p->sq_idx) {
++ requeue_task(p, rq, idx);
++ check_preempt_curr(rq);
++ }
++}
++
++static void __setscheduler_prio(struct task_struct *p, int prio)
++{
++ p->prio = prio;
++}
++
++#ifdef CONFIG_RT_MUTEXES
++
++static inline int __rt_effective_prio(struct task_struct *pi_task, int prio)
++{
++ if (pi_task)
++ prio = min(prio, pi_task->prio);
++
++ return prio;
++}
++
++static inline int rt_effective_prio(struct task_struct *p, int prio)
++{
++ struct task_struct *pi_task = rt_mutex_get_top_task(p);
++
++ return __rt_effective_prio(pi_task, prio);
++}
++
++/*
++ * rt_mutex_setprio - set the current priority of a task
++ * @p: task to boost
++ * @pi_task: donor task
++ *
++ * This function changes the 'effective' priority of a task. It does
++ * not touch ->normal_prio like __setscheduler().
++ *
++ * Used by the rt_mutex code to implement priority inheritance
++ * logic. Call site only calls if the priority of the task changed.
++ */
++void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
++{
++ int prio;
++ struct rq *rq;
++ raw_spinlock_t *lock;
++
++ /* XXX used to be waiter->prio, not waiter->task->prio */
++ prio = __rt_effective_prio(pi_task, p->normal_prio);
++
++ /*
++ * If nothing changed; bail early.
++ */
++ if (p->pi_top_task == pi_task && prio == p->prio)
++ return;
++
++ rq = __task_access_lock(p, &lock);
++ /*
++ * Set under pi_lock && rq->lock, such that the value can be used under
++ * either lock.
++ *
++ * Note that there is loads of tricky to make this pointer cache work
++ * right. rt_mutex_slowunlock()+rt_mutex_postunlock() work together to
++ * ensure a task is de-boosted (pi_task is set to NULL) before the
++ * task is allowed to run again (and can exit). This ensures the pointer
++ * points to a blocked task -- which guarantees the task is present.
++ */
++ p->pi_top_task = pi_task;
++
++ /*
++ * For FIFO/RR we only need to set prio, if that matches we're done.
++ */
++ if (prio == p->prio)
++ goto out_unlock;
++
++ /*
++ * Idle task boosting is a nono in general. There is one
++ * exception, when PREEMPT_RT and NOHZ is active:
++ *
++ * The idle task calls get_next_timer_interrupt() and holds
++ * the timer wheel base->lock on the CPU and another CPU wants
++ * to access the timer (probably to cancel it). We can safely
++ * ignore the boosting request, as the idle CPU runs this code
++ * with interrupts disabled and will complete the lock
++ * protected section without being interrupted. So there is no
++ * real need to boost.
++ */
++ if (unlikely(p == rq->idle)) {
++ WARN_ON(p != rq->curr);
++ WARN_ON(p->pi_blocked_on);
++ goto out_unlock;
++ }
++
++ trace_sched_pi_setprio(p, pi_task);
++
++ __setscheduler_prio(p, prio);
++
++ check_task_changed(p, rq);
++out_unlock:
++ /* Avoid rq from going away on us: */
++ preempt_disable();
++
++ __balance_callbacks(rq);
++ __task_access_unlock(p, lock);
++
++ preempt_enable();
++}
++#else
++static inline int rt_effective_prio(struct task_struct *p, int prio)
++{
++ return prio;
++}
++#endif
++
++void set_user_nice(struct task_struct *p, long nice)
++{
++ unsigned long flags;
++ struct rq *rq;
++ raw_spinlock_t *lock;
++
++ if (task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE)
++ return;
++ /*
++ * We have to be careful, if called from sys_setpriority(),
++ * the task might be in the middle of scheduling on another CPU.
++ */
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++ rq = __task_access_lock(p, &lock);
++
++ p->static_prio = NICE_TO_PRIO(nice);
++ /*
++ * The RT priorities are set via sched_setscheduler(), but we still
++ * allow the 'normal' nice value to be set - but as expected
++ * it won't have any effect on scheduling until the task is
++ * not SCHED_NORMAL/SCHED_BATCH:
++ */
++ if (task_has_rt_policy(p))
++ goto out_unlock;
++
++ p->prio = effective_prio(p);
++
++ check_task_changed(p, rq);
++out_unlock:
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++EXPORT_SYMBOL(set_user_nice);
++
++/*
++ * is_nice_reduction - check if nice value is an actual reduction
++ *
++ * Similar to can_nice() but does not perform a capability check.
++ *
++ * @p: task
++ * @nice: nice value
++ */
++static bool is_nice_reduction(const struct task_struct *p, const int nice)
++{
++ /* Convert nice value [19,-20] to rlimit style value [1,40]: */
++ int nice_rlim = nice_to_rlimit(nice);
++
++ return (nice_rlim <= task_rlimit(p, RLIMIT_NICE));
++}
++
++/*
++ * can_nice - check if a task can reduce its nice value
++ * @p: task
++ * @nice: nice value
++ */
++int can_nice(const struct task_struct *p, const int nice)
++{
++ return is_nice_reduction(p, nice) || capable(CAP_SYS_NICE);
++}
++
++#ifdef __ARCH_WANT_SYS_NICE
++
++/*
++ * sys_nice - change the priority of the current process.
++ * @increment: priority increment
++ *
++ * sys_setpriority is a more generic, but much slower function that
++ * does similar things.
++ */
++SYSCALL_DEFINE1(nice, int, increment)
++{
++ long nice, retval;
++
++ /*
++ * Setpriority might change our priority at the same moment.
++ * We don't have to worry. Conceptually one call occurs first
++ * and we have a single winner.
++ */
++
++ increment = clamp(increment, -NICE_WIDTH, NICE_WIDTH);
++ nice = task_nice(current) + increment;
++
++ nice = clamp_val(nice, MIN_NICE, MAX_NICE);
++ if (increment < 0 && !can_nice(current, nice))
++ return -EPERM;
++
++ retval = security_task_setnice(current, nice);
++ if (retval)
++ return retval;
++
++ set_user_nice(current, nice);
++ return 0;
++}
++
++#endif
++
++/**
++ * task_prio - return the priority value of a given task.
++ * @p: the task in question.
++ *
++ * Return: The priority value as seen by users in /proc.
++ *
++ * sched policy return value kernel prio user prio/nice
++ *
++ * (BMQ)normal, batch, idle[0 ... 53] [100 ... 139] 0/[-20 ... 19]/[-7 ... 7]
++ * (PDS)normal, batch, idle[0 ... 39] 100 0/[-20 ... 19]
++ * fifo, rr [-1 ... -100] [99 ... 0] [0 ... 99]
++ */
++int task_prio(const struct task_struct *p)
++{
++ return (p->prio < MAX_RT_PRIO) ? p->prio - MAX_RT_PRIO :
++ task_sched_prio_normal(p, task_rq(p));
++}
++
++/**
++ * idle_cpu - is a given CPU idle currently?
++ * @cpu: the processor in question.
++ *
++ * Return: 1 if the CPU is currently idle. 0 otherwise.
++ */
++int idle_cpu(int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ if (rq->curr != rq->idle)
++ return 0;
++
++ if (rq->nr_running)
++ return 0;
++
++#ifdef CONFIG_SMP
++ if (rq->ttwu_pending)
++ return 0;
++#endif
++
++ return 1;
++}
++
++/**
++ * idle_task - return the idle task for a given CPU.
++ * @cpu: the processor in question.
++ *
++ * Return: The idle task for the cpu @cpu.
++ */
++struct task_struct *idle_task(int cpu)
++{
++ return cpu_rq(cpu)->idle;
++}
++
++/**
++ * find_process_by_pid - find a process with a matching PID value.
++ * @pid: the pid in question.
++ *
++ * The task of @pid, if found. %NULL otherwise.
++ */
++static inline struct task_struct *find_process_by_pid(pid_t pid)
++{
++ return pid ? find_task_by_vpid(pid) : current;
++}
++
++/*
++ * sched_setparam() passes in -1 for its policy, to let the functions
++ * it calls know not to change it.
++ */
++#define SETPARAM_POLICY -1
++
++static void __setscheduler_params(struct task_struct *p,
++ const struct sched_attr *attr)
++{
++ int policy = attr->sched_policy;
++
++ if (policy == SETPARAM_POLICY)
++ policy = p->policy;
++
++ p->policy = policy;
++
++ /*
++ * allow normal nice value to be set, but will not have any
++ * effect on scheduling until the task not SCHED_NORMAL/
++ * SCHED_BATCH
++ */
++ p->static_prio = NICE_TO_PRIO(attr->sched_nice);
++
++ /*
++ * __sched_setscheduler() ensures attr->sched_priority == 0 when
++ * !rt_policy. Always setting this ensures that things like
++ * getparam()/getattr() don't report silly values for !rt tasks.
++ */
++ p->rt_priority = attr->sched_priority;
++ p->normal_prio = normal_prio(p);
++}
++
++/*
++ * check the target process has a UID that matches the current process's
++ */
++static bool check_same_owner(struct task_struct *p)
++{
++ const struct cred *cred = current_cred(), *pcred;
++ bool match;
++
++ rcu_read_lock();
++ pcred = __task_cred(p);
++ match = (uid_eq(cred->euid, pcred->euid) ||
++ uid_eq(cred->euid, pcred->uid));
++ rcu_read_unlock();
++ return match;
++}
++
++/*
++ * Allow unprivileged RT tasks to decrease priority.
++ * Only issue a capable test if needed and only once to avoid an audit
++ * event on permitted non-privileged operations:
++ */
++static int user_check_sched_setscheduler(struct task_struct *p,
++ const struct sched_attr *attr,
++ int policy, int reset_on_fork)
++{
++ if (rt_policy(policy)) {
++ unsigned long rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO);
++
++ /* Can't set/change the rt policy: */
++ if (policy != p->policy && !rlim_rtprio)
++ goto req_priv;
++
++ /* Can't increase priority: */
++ if (attr->sched_priority > p->rt_priority &&
++ attr->sched_priority > rlim_rtprio)
++ goto req_priv;
++ }
++
++ /* Can't change other user's priorities: */
++ if (!check_same_owner(p))
++ goto req_priv;
++
++ /* Normal users shall not reset the sched_reset_on_fork flag: */
++ if (p->sched_reset_on_fork && !reset_on_fork)
++ goto req_priv;
++
++ return 0;
++
++req_priv:
++ if (!capable(CAP_SYS_NICE))
++ return -EPERM;
++
++ return 0;
++}
++
++static int __sched_setscheduler(struct task_struct *p,
++ const struct sched_attr *attr,
++ bool user, bool pi)
++{
++ const struct sched_attr dl_squash_attr = {
++ .size = sizeof(struct sched_attr),
++ .sched_policy = SCHED_FIFO,
++ .sched_nice = 0,
++ .sched_priority = 99,
++ };
++ int oldpolicy = -1, policy = attr->sched_policy;
++ int retval, newprio;
++ struct callback_head *head;
++ unsigned long flags;
++ struct rq *rq;
++ int reset_on_fork;
++ raw_spinlock_t *lock;
++
++ /* The pi code expects interrupts enabled */
++ BUG_ON(pi && in_interrupt());
++
++ /*
++ * Alt schedule FW supports SCHED_DEADLINE by squash it as prio 0 SCHED_FIFO
++ */
++ if (unlikely(SCHED_DEADLINE == policy)) {
++ attr = &dl_squash_attr;
++ policy = attr->sched_policy;
++ }
++recheck:
++ /* Double check policy once rq lock held */
++ if (policy < 0) {
++ reset_on_fork = p->sched_reset_on_fork;
++ policy = oldpolicy = p->policy;
++ } else {
++ reset_on_fork = !!(attr->sched_flags & SCHED_RESET_ON_FORK);
++
++ if (policy > SCHED_IDLE)
++ return -EINVAL;
++ }
++
++ if (attr->sched_flags & ~(SCHED_FLAG_ALL))
++ return -EINVAL;
++
++ /*
++ * Valid priorities for SCHED_FIFO and SCHED_RR are
++ * 1..MAX_RT_PRIO-1, valid priority for SCHED_NORMAL and
++ * SCHED_BATCH and SCHED_IDLE is 0.
++ */
++ if (attr->sched_priority < 0 ||
++ (p->mm && attr->sched_priority > MAX_RT_PRIO - 1) ||
++ (!p->mm && attr->sched_priority > MAX_RT_PRIO - 1))
++ return -EINVAL;
++ if ((SCHED_RR == policy || SCHED_FIFO == policy) !=
++ (attr->sched_priority != 0))
++ return -EINVAL;
++
++ if (user) {
++ retval = user_check_sched_setscheduler(p, attr, policy, reset_on_fork);
++ if (retval)
++ return retval;
++
++ retval = security_task_setscheduler(p);
++ if (retval)
++ return retval;
++ }
++
++ if (pi)
++ cpuset_read_lock();
++
++ /*
++ * Make sure no PI-waiters arrive (or leave) while we are
++ * changing the priority of the task:
++ */
++ raw_spin_lock_irqsave(&p->pi_lock, flags);
++
++ /*
++ * To be able to change p->policy safely, task_access_lock()
++ * must be called.
++ * IF use task_access_lock() here:
++ * For the task p which is not running, reading rq->stop is
++ * racy but acceptable as ->stop doesn't change much.
++ * An enhancemnet can be made to read rq->stop saftly.
++ */
++ rq = __task_access_lock(p, &lock);
++
++ /*
++ * Changing the policy of the stop threads its a very bad idea
++ */
++ if (p == rq->stop) {
++ retval = -EINVAL;
++ goto unlock;
++ }
++
++ /*
++ * If not changing anything there's no need to proceed further:
++ */
++ if (unlikely(policy == p->policy)) {
++ if (rt_policy(policy) && attr->sched_priority != p->rt_priority)
++ goto change;
++ if (!rt_policy(policy) &&
++ NICE_TO_PRIO(attr->sched_nice) != p->static_prio)
++ goto change;
++
++ p->sched_reset_on_fork = reset_on_fork;
++ retval = 0;
++ goto unlock;
++ }
++change:
++
++ /* Re-check policy now with rq lock held */
++ if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
++ policy = oldpolicy = -1;
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++ if (pi)
++ cpuset_read_unlock();
++ goto recheck;
++ }
++
++ p->sched_reset_on_fork = reset_on_fork;
++
++ newprio = __normal_prio(policy, attr->sched_priority, NICE_TO_PRIO(attr->sched_nice));
++ if (pi) {
++ /*
++ * Take priority boosted tasks into account. If the new
++ * effective priority is unchanged, we just store the new
++ * normal parameters and do not touch the scheduler class and
++ * the runqueue. This will be done when the task deboost
++ * itself.
++ */
++ newprio = rt_effective_prio(p, newprio);
++ }
++
++ if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
++ __setscheduler_params(p, attr);
++ __setscheduler_prio(p, newprio);
++ }
++
++ check_task_changed(p, rq);
++
++ /* Avoid rq from going away on us: */
++ preempt_disable();
++ head = splice_balance_callbacks(rq);
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++ if (pi) {
++ cpuset_read_unlock();
++ rt_mutex_adjust_pi(p);
++ }
++
++ /* Run balance callbacks after we've adjusted the PI chain: */
++ balance_callbacks(rq, head);
++ preempt_enable();
++
++ return 0;
++
++unlock:
++ __task_access_unlock(p, lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++ if (pi)
++ cpuset_read_unlock();
++ return retval;
++}
++
++static int _sched_setscheduler(struct task_struct *p, int policy,
++ const struct sched_param *param, bool check)
++{
++ struct sched_attr attr = {
++ .sched_policy = policy,
++ .sched_priority = param->sched_priority,
++ .sched_nice = PRIO_TO_NICE(p->static_prio),
++ };
++
++ /* Fixup the legacy SCHED_RESET_ON_FORK hack. */
++ if ((policy != SETPARAM_POLICY) && (policy & SCHED_RESET_ON_FORK)) {
++ attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
++ policy &= ~SCHED_RESET_ON_FORK;
++ attr.sched_policy = policy;
++ }
++
++ return __sched_setscheduler(p, &attr, check, true);
++}
++
++/**
++ * sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
++ * @p: the task in question.
++ * @policy: new policy.
++ * @param: structure containing the new RT priority.
++ *
++ * Use sched_set_fifo(), read its comment.
++ *
++ * Return: 0 on success. An error code otherwise.
++ *
++ * NOTE that the task may be already dead.
++ */
++int sched_setscheduler(struct task_struct *p, int policy,
++ const struct sched_param *param)
++{
++ return _sched_setscheduler(p, policy, param, true);
++}
++
++int sched_setattr(struct task_struct *p, const struct sched_attr *attr)
++{
++ return __sched_setscheduler(p, attr, true, true);
++}
++
++int sched_setattr_nocheck(struct task_struct *p, const struct sched_attr *attr)
++{
++ return __sched_setscheduler(p, attr, false, true);
++}
++EXPORT_SYMBOL_GPL(sched_setattr_nocheck);
++
++/**
++ * sched_setscheduler_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace.
++ * @p: the task in question.
++ * @policy: new policy.
++ * @param: structure containing the new RT priority.
++ *
++ * Just like sched_setscheduler, only don't bother checking if the
++ * current context has permission. For example, this is needed in
++ * stop_machine(): we create temporary high priority worker threads,
++ * but our caller might not have that capability.
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++int sched_setscheduler_nocheck(struct task_struct *p, int policy,
++ const struct sched_param *param)
++{
++ return _sched_setscheduler(p, policy, param, false);
++}
++
++/*
++ * SCHED_FIFO is a broken scheduler model; that is, it is fundamentally
++ * incapable of resource management, which is the one thing an OS really should
++ * be doing.
++ *
++ * This is of course the reason it is limited to privileged users only.
++ *
++ * Worse still; it is fundamentally impossible to compose static priority
++ * workloads. You cannot take two correctly working static prio workloads
++ * and smash them together and still expect them to work.
++ *
++ * For this reason 'all' FIFO tasks the kernel creates are basically at:
++ *
++ * MAX_RT_PRIO / 2
++ *
++ * The administrator _MUST_ configure the system, the kernel simply doesn't
++ * know enough information to make a sensible choice.
++ */
++void sched_set_fifo(struct task_struct *p)
++{
++ struct sched_param sp = { .sched_priority = MAX_RT_PRIO / 2 };
++ WARN_ON_ONCE(sched_setscheduler_nocheck(p, SCHED_FIFO, &sp) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_fifo);
++
++/*
++ * For when you don't much care about FIFO, but want to be above SCHED_NORMAL.
++ */
++void sched_set_fifo_low(struct task_struct *p)
++{
++ struct sched_param sp = { .sched_priority = 1 };
++ WARN_ON_ONCE(sched_setscheduler_nocheck(p, SCHED_FIFO, &sp) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_fifo_low);
++
++void sched_set_normal(struct task_struct *p, int nice)
++{
++ struct sched_attr attr = {
++ .sched_policy = SCHED_NORMAL,
++ .sched_nice = nice,
++ };
++ WARN_ON_ONCE(sched_setattr_nocheck(p, &attr) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_normal);
++
++static int
++do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
++{
++ struct sched_param lparam;
++ struct task_struct *p;
++ int retval;
++
++ if (!param || pid < 0)
++ return -EINVAL;
++ if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
++ return -EFAULT;
++
++ rcu_read_lock();
++ retval = -ESRCH;
++ p = find_process_by_pid(pid);
++ if (likely(p))
++ get_task_struct(p);
++ rcu_read_unlock();
++
++ if (likely(p)) {
++ retval = sched_setscheduler(p, policy, &lparam);
++ put_task_struct(p);
++ }
++
++ return retval;
++}
++
++/*
++ * Mimics kernel/events/core.c perf_copy_attr().
++ */
++static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *attr)
++{
++ u32 size;
++ int ret;
++
++ /* Zero the full structure, so that a short copy will be nice: */
++ memset(attr, 0, sizeof(*attr));
++
++ ret = get_user(size, &uattr->size);
++ if (ret)
++ return ret;
++
++ /* ABI compatibility quirk: */
++ if (!size)
++ size = SCHED_ATTR_SIZE_VER0;
++
++ if (size < SCHED_ATTR_SIZE_VER0 || size > PAGE_SIZE)
++ goto err_size;
++
++ ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size);
++ if (ret) {
++ if (ret == -E2BIG)
++ goto err_size;
++ return ret;
++ }
++
++ /*
++ * XXX: Do we want to be lenient like existing syscalls; or do we want
++ * to be strict and return an error on out-of-bounds values?
++ */
++ attr->sched_nice = clamp(attr->sched_nice, -20, 19);
++
++ /* sched/core.c uses zero here but we already know ret is zero */
++ return 0;
++
++err_size:
++ put_user(sizeof(*attr), &uattr->size);
++ return -E2BIG;
++}
++
++/**
++ * sys_sched_setscheduler - set/change the scheduler policy and RT priority
++ * @pid: the pid in question.
++ * @policy: new policy.
++ *
++ * Return: 0 on success. An error code otherwise.
++ * @param: structure containing the new RT priority.
++ */
++SYSCALL_DEFINE3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param)
++{
++ if (policy < 0)
++ return -EINVAL;
++
++ return do_sched_setscheduler(pid, policy, param);
++}
++
++/**
++ * sys_sched_setparam - set/change the RT priority of a thread
++ * @pid: the pid in question.
++ * @param: structure containing the new RT priority.
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param)
++{
++ return do_sched_setscheduler(pid, SETPARAM_POLICY, param);
++}
++
++/**
++ * sys_sched_setattr - same as above, but with extended sched_attr
++ * @pid: the pid in question.
++ * @uattr: structure containing the extended parameters.
++ */
++SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr,
++ unsigned int, flags)
++{
++ struct sched_attr attr;
++ struct task_struct *p;
++ int retval;
++
++ if (!uattr || pid < 0 || flags)
++ return -EINVAL;
++
++ retval = sched_copy_attr(uattr, &attr);
++ if (retval)
++ return retval;
++
++ if ((int)attr.sched_policy < 0)
++ return -EINVAL;
++
++ rcu_read_lock();
++ retval = -ESRCH;
++ p = find_process_by_pid(pid);
++ if (likely(p))
++ get_task_struct(p);
++ rcu_read_unlock();
++
++ if (likely(p)) {
++ retval = sched_setattr(p, &attr);
++ put_task_struct(p);
++ }
++
++ return retval;
++}
++
++/**
++ * sys_sched_getscheduler - get the policy (scheduling class) of a thread
++ * @pid: the pid in question.
++ *
++ * Return: On success, the policy of the thread. Otherwise, a negative error
++ * code.
++ */
++SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)
++{
++ struct task_struct *p;
++ int retval = -EINVAL;
++
++ if (pid < 0)
++ goto out_nounlock;
++
++ retval = -ESRCH;
++ rcu_read_lock();
++ p = find_process_by_pid(pid);
++ if (p) {
++ retval = security_task_getscheduler(p);
++ if (!retval)
++ retval = p->policy;
++ }
++ rcu_read_unlock();
++
++out_nounlock:
++ return retval;
++}
++
++/**
++ * sys_sched_getscheduler - get the RT priority of a thread
++ * @pid: the pid in question.
++ * @param: structure containing the RT priority.
++ *
++ * Return: On success, 0 and the RT priority is in @param. Otherwise, an error
++ * code.
++ */
++SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
++{
++ struct sched_param lp = { .sched_priority = 0 };
++ struct task_struct *p;
++ int retval = -EINVAL;
++
++ if (!param || pid < 0)
++ goto out_nounlock;
++
++ rcu_read_lock();
++ p = find_process_by_pid(pid);
++ retval = -ESRCH;
++ if (!p)
++ goto out_unlock;
++
++ retval = security_task_getscheduler(p);
++ if (retval)
++ goto out_unlock;
++
++ if (task_has_rt_policy(p))
++ lp.sched_priority = p->rt_priority;
++ rcu_read_unlock();
++
++ /*
++ * This one might sleep, we cannot do it with a spinlock held ...
++ */
++ retval = copy_to_user(param, &lp, sizeof(*param)) ? -EFAULT : 0;
++
++out_nounlock:
++ return retval;
++
++out_unlock:
++ rcu_read_unlock();
++ return retval;
++}
++
++/*
++ * Copy the kernel size attribute structure (which might be larger
++ * than what user-space knows about) to user-space.
++ *
++ * Note that all cases are valid: user-space buffer can be larger or
++ * smaller than the kernel-space buffer. The usual case is that both
++ * have the same size.
++ */
++static int
++sched_attr_copy_to_user(struct sched_attr __user *uattr,
++ struct sched_attr *kattr,
++ unsigned int usize)
++{
++ unsigned int ksize = sizeof(*kattr);
++
++ if (!access_ok(uattr, usize))
++ return -EFAULT;
++
++ /*
++ * sched_getattr() ABI forwards and backwards compatibility:
++ *
++ * If usize == ksize then we just copy everything to user-space and all is good.
++ *
++ * If usize < ksize then we only copy as much as user-space has space for,
++ * this keeps ABI compatibility as well. We skip the rest.
++ *
++ * If usize > ksize then user-space is using a newer version of the ABI,
++ * which part the kernel doesn't know about. Just ignore it - tooling can
++ * detect the kernel's knowledge of attributes from the attr->size value
++ * which is set to ksize in this case.
++ */
++ kattr->size = min(usize, ksize);
++
++ if (copy_to_user(uattr, kattr, kattr->size))
++ return -EFAULT;
++
++ return 0;
++}
++
++/**
++ * sys_sched_getattr - similar to sched_getparam, but with sched_attr
++ * @pid: the pid in question.
++ * @uattr: structure containing the extended parameters.
++ * @usize: sizeof(attr) for fwd/bwd comp.
++ * @flags: for future extension.
++ */
++SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
++ unsigned int, usize, unsigned int, flags)
++{
++ struct sched_attr kattr = { };
++ struct task_struct *p;
++ int retval;
++
++ if (!uattr || pid < 0 || usize > PAGE_SIZE ||
++ usize < SCHED_ATTR_SIZE_VER0 || flags)
++ return -EINVAL;
++
++ rcu_read_lock();
++ p = find_process_by_pid(pid);
++ retval = -ESRCH;
++ if (!p)
++ goto out_unlock;
++
++ retval = security_task_getscheduler(p);
++ if (retval)
++ goto out_unlock;
++
++ kattr.sched_policy = p->policy;
++ if (p->sched_reset_on_fork)
++ kattr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
++ if (task_has_rt_policy(p))
++ kattr.sched_priority = p->rt_priority;
++ else
++ kattr.sched_nice = task_nice(p);
++ kattr.sched_flags &= SCHED_FLAG_ALL;
++
++#ifdef CONFIG_UCLAMP_TASK
++ kattr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value;
++ kattr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value;
++#endif
++
++ rcu_read_unlock();
++
++ return sched_attr_copy_to_user(uattr, &kattr, usize);
++
++out_unlock:
++ rcu_read_unlock();
++ return retval;
++}
++
++static int
++__sched_setaffinity(struct task_struct *p, const struct cpumask *mask)
++{
++ int retval;
++ cpumask_var_t cpus_allowed, new_mask;
++
++ if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL))
++ return -ENOMEM;
++
++ if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
++ retval = -ENOMEM;
++ goto out_free_cpus_allowed;
++ }
++
++ cpuset_cpus_allowed(p, cpus_allowed);
++ cpumask_and(new_mask, mask, cpus_allowed);
++again:
++ retval = __set_cpus_allowed_ptr(p, new_mask, SCA_CHECK | SCA_USER);
++ if (retval)
++ goto out_free_new_mask;
++
++ cpuset_cpus_allowed(p, cpus_allowed);
++ if (!cpumask_subset(new_mask, cpus_allowed)) {
++ /*
++ * We must have raced with a concurrent cpuset
++ * update. Just reset the cpus_allowed to the
++ * cpuset's cpus_allowed
++ */
++ cpumask_copy(new_mask, cpus_allowed);
++ goto again;
++ }
++
++out_free_new_mask:
++ free_cpumask_var(new_mask);
++out_free_cpus_allowed:
++ free_cpumask_var(cpus_allowed);
++ return retval;
++}
++
++long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
++{
++ struct task_struct *p;
++ int retval;
++
++ rcu_read_lock();
++
++ p = find_process_by_pid(pid);
++ if (!p) {
++ rcu_read_unlock();
++ return -ESRCH;
++ }
++
++ /* Prevent p going away */
++ get_task_struct(p);
++ rcu_read_unlock();
++
++ if (p->flags & PF_NO_SETAFFINITY) {
++ retval = -EINVAL;
++ goto out_put_task;
++ }
++
++ if (!check_same_owner(p)) {
++ rcu_read_lock();
++ if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
++ rcu_read_unlock();
++ retval = -EPERM;
++ goto out_put_task;
++ }
++ rcu_read_unlock();
++ }
++
++ retval = security_task_setscheduler(p);
++ if (retval)
++ goto out_put_task;
++
++ retval = __sched_setaffinity(p, in_mask);
++out_put_task:
++ put_task_struct(p);
++ return retval;
++}
++
++static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
++ struct cpumask *new_mask)
++{
++ if (len < cpumask_size())
++ cpumask_clear(new_mask);
++ else if (len > cpumask_size())
++ len = cpumask_size();
++
++ return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0;
++}
++
++/**
++ * sys_sched_setaffinity - set the CPU affinity of a process
++ * @pid: pid of the process
++ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
++ * @user_mask_ptr: user-space pointer to the new CPU mask
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
++ unsigned long __user *, user_mask_ptr)
++{
++ cpumask_var_t new_mask;
++ int retval;
++
++ if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
++ return -ENOMEM;
++
++ retval = get_user_cpu_mask(user_mask_ptr, len, new_mask);
++ if (retval == 0)
++ retval = sched_setaffinity(pid, new_mask);
++ free_cpumask_var(new_mask);
++ return retval;
++}
++
++long sched_getaffinity(pid_t pid, cpumask_t *mask)
++{
++ struct task_struct *p;
++ raw_spinlock_t *lock;
++ unsigned long flags;
++ int retval;
++
++ rcu_read_lock();
++
++ retval = -ESRCH;
++ p = find_process_by_pid(pid);
++ if (!p)
++ goto out_unlock;
++
++ retval = security_task_getscheduler(p);
++ if (retval)
++ goto out_unlock;
++
++ task_access_lock_irqsave(p, &lock, &flags);
++ cpumask_and(mask, &p->cpus_mask, cpu_active_mask);
++ task_access_unlock_irqrestore(p, lock, &flags);
++
++out_unlock:
++ rcu_read_unlock();
++
++ return retval;
++}
++
++/**
++ * sys_sched_getaffinity - get the CPU affinity of a process
++ * @pid: pid of the process
++ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
++ * @user_mask_ptr: user-space pointer to hold the current CPU mask
++ *
++ * Return: size of CPU mask copied to user_mask_ptr on success. An
++ * error code otherwise.
++ */
++SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
++ unsigned long __user *, user_mask_ptr)
++{
++ int ret;
++ cpumask_var_t mask;
++
++ if ((len * BITS_PER_BYTE) < nr_cpu_ids)
++ return -EINVAL;
++ if (len & (sizeof(unsigned long)-1))
++ return -EINVAL;
++
++ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
++ return -ENOMEM;
++
++ ret = sched_getaffinity(pid, mask);
++ if (ret == 0) {
++ unsigned int retlen = min_t(size_t, len, cpumask_size());
++
++ if (copy_to_user(user_mask_ptr, mask, retlen))
++ ret = -EFAULT;
++ else
++ ret = retlen;
++ }
++ free_cpumask_var(mask);
++
++ return ret;
++}
++
++static void do_sched_yield(void)
++{
++ struct rq *rq;
++ struct rq_flags rf;
++
++ if (!sched_yield_type)
++ return;
++
++ rq = this_rq_lock_irq(&rf);
++
++ schedstat_inc(rq->yld_count);
++
++ if (1 == sched_yield_type) {
++ if (!rt_task(current))
++ do_sched_yield_type_1(current, rq);
++ } else if (2 == sched_yield_type) {
++ if (rq->nr_running > 1)
++ rq->skip = current;
++ }
++
++ preempt_disable();
++ raw_spin_unlock_irq(&rq->lock);
++ sched_preempt_enable_no_resched();
++
++ schedule();
++}
++
++/**
++ * sys_sched_yield - yield the current processor to other threads.
++ *
++ * This function yields the current CPU to other tasks. If there are no
++ * other threads running on this CPU then this function will return.
++ *
++ * Return: 0.
++ */
++SYSCALL_DEFINE0(sched_yield)
++{
++ do_sched_yield();
++ return 0;
++}
++
++#if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
++int __sched __cond_resched(void)
++{
++ if (should_resched(0)) {
++ preempt_schedule_common();
++ return 1;
++ }
++ /*
++ * In preemptible kernels, ->rcu_read_lock_nesting tells the tick
++ * whether the current CPU is in an RCU read-side critical section,
++ * so the tick can report quiescent states even for CPUs looping
++ * in kernel context. In contrast, in non-preemptible kernels,
++ * RCU readers leave no in-memory hints, which means that CPU-bound
++ * processes executing in kernel context might never report an
++ * RCU quiescent state. Therefore, the following code causes
++ * cond_resched() to report a quiescent state, but only when RCU
++ * is in urgent need of one.
++ */
++#ifndef CONFIG_PREEMPT_RCU
++ rcu_all_qs();
++#endif
++ return 0;
++}
++EXPORT_SYMBOL(__cond_resched);
++#endif
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#define cond_resched_dynamic_enabled __cond_resched
++#define cond_resched_dynamic_disabled ((void *)&__static_call_return0)
++DEFINE_STATIC_CALL_RET0(cond_resched, __cond_resched);
++EXPORT_STATIC_CALL_TRAMP(cond_resched);
++
++#define might_resched_dynamic_enabled __cond_resched
++#define might_resched_dynamic_disabled ((void *)&__static_call_return0)
++DEFINE_STATIC_CALL_RET0(might_resched, __cond_resched);
++EXPORT_STATIC_CALL_TRAMP(might_resched);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_FALSE(sk_dynamic_cond_resched);
++int __sched dynamic_cond_resched(void)
++{
++ if (!static_branch_unlikely(&sk_dynamic_cond_resched))
++ return 0;
++ return __cond_resched();
++}
++EXPORT_SYMBOL(dynamic_cond_resched);
++
++static DEFINE_STATIC_KEY_FALSE(sk_dynamic_might_resched);
++int __sched dynamic_might_resched(void)
++{
++ if (!static_branch_unlikely(&sk_dynamic_might_resched))
++ return 0;
++ return __cond_resched();
++}
++EXPORT_SYMBOL(dynamic_might_resched);
++#endif
++#endif
++
++/*
++ * __cond_resched_lock() - if a reschedule is pending, drop the given lock,
++ * call schedule, and on return reacquire the lock.
++ *
++ * This works OK both with and without CONFIG_PREEMPTION. We do strange low-level
++ * operations here to prevent schedule() from being called twice (once via
++ * spin_unlock(), once by hand).
++ */
++int __cond_resched_lock(spinlock_t *lock)
++{
++ int resched = should_resched(PREEMPT_LOCK_OFFSET);
++ int ret = 0;
++
++ lockdep_assert_held(lock);
++
++ if (spin_needbreak(lock) || resched) {
++ spin_unlock(lock);
++ if (!_cond_resched())
++ cpu_relax();
++ ret = 1;
++ spin_lock(lock);
++ }
++ return ret;
++}
++EXPORT_SYMBOL(__cond_resched_lock);
++
++int __cond_resched_rwlock_read(rwlock_t *lock)
++{
++ int resched = should_resched(PREEMPT_LOCK_OFFSET);
++ int ret = 0;
++
++ lockdep_assert_held_read(lock);
++
++ if (rwlock_needbreak(lock) || resched) {
++ read_unlock(lock);
++ if (!_cond_resched())
++ cpu_relax();
++ ret = 1;
++ read_lock(lock);
++ }
++ return ret;
++}
++EXPORT_SYMBOL(__cond_resched_rwlock_read);
++
++int __cond_resched_rwlock_write(rwlock_t *lock)
++{
++ int resched = should_resched(PREEMPT_LOCK_OFFSET);
++ int ret = 0;
++
++ lockdep_assert_held_write(lock);
++
++ if (rwlock_needbreak(lock) || resched) {
++ write_unlock(lock);
++ if (!_cond_resched())
++ cpu_relax();
++ ret = 1;
++ write_lock(lock);
++ }
++ return ret;
++}
++EXPORT_SYMBOL(__cond_resched_rwlock_write);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++
++#ifdef CONFIG_GENERIC_ENTRY
++#include <linux/entry-common.h>
++#endif
++
++/*
++ * SC:cond_resched
++ * SC:might_resched
++ * SC:preempt_schedule
++ * SC:preempt_schedule_notrace
++ * SC:irqentry_exit_cond_resched
++ *
++ *
++ * NONE:
++ * cond_resched <- __cond_resched
++ * might_resched <- RET0
++ * preempt_schedule <- NOP
++ * preempt_schedule_notrace <- NOP
++ * irqentry_exit_cond_resched <- NOP
++ *
++ * VOLUNTARY:
++ * cond_resched <- __cond_resched
++ * might_resched <- __cond_resched
++ * preempt_schedule <- NOP
++ * preempt_schedule_notrace <- NOP
++ * irqentry_exit_cond_resched <- NOP
++ *
++ * FULL:
++ * cond_resched <- RET0
++ * might_resched <- RET0
++ * preempt_schedule <- preempt_schedule
++ * preempt_schedule_notrace <- preempt_schedule_notrace
++ * irqentry_exit_cond_resched <- irqentry_exit_cond_resched
++ */
++
++enum {
++ preempt_dynamic_undefined = -1,
++ preempt_dynamic_none,
++ preempt_dynamic_voluntary,
++ preempt_dynamic_full,
++};
++
++int preempt_dynamic_mode = preempt_dynamic_undefined;
++
++int sched_dynamic_mode(const char *str)
++{
++ if (!strcmp(str, "none"))
++ return preempt_dynamic_none;
++
++ if (!strcmp(str, "voluntary"))
++ return preempt_dynamic_voluntary;
++
++ if (!strcmp(str, "full"))
++ return preempt_dynamic_full;
++
++ return -EINVAL;
++}
++
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#define preempt_dynamic_enable(f) static_call_update(f, f##_dynamic_enabled)
++#define preempt_dynamic_disable(f) static_call_update(f, f##_dynamic_disabled)
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++#define preempt_dynamic_enable(f) static_key_enable(&sk_dynamic_##f.key)
++#define preempt_dynamic_disable(f) static_key_disable(&sk_dynamic_##f.key)
++#else
++#error "Unsupported PREEMPT_DYNAMIC mechanism"
++#endif
++
++void sched_dynamic_update(int mode)
++{
++ /*
++ * Avoid {NONE,VOLUNTARY} -> FULL transitions from ever ending up in
++ * the ZERO state, which is invalid.
++ */
++ preempt_dynamic_enable(cond_resched);
++ preempt_dynamic_enable(might_resched);
++ preempt_dynamic_enable(preempt_schedule);
++ preempt_dynamic_enable(preempt_schedule_notrace);
++ preempt_dynamic_enable(irqentry_exit_cond_resched);
++
++ switch (mode) {
++ case preempt_dynamic_none:
++ preempt_dynamic_enable(cond_resched);
++ preempt_dynamic_disable(might_resched);
++ preempt_dynamic_disable(preempt_schedule);
++ preempt_dynamic_disable(preempt_schedule_notrace);
++ preempt_dynamic_disable(irqentry_exit_cond_resched);
++ pr_info("Dynamic Preempt: none\n");
++ break;
++
++ case preempt_dynamic_voluntary:
++ preempt_dynamic_enable(cond_resched);
++ preempt_dynamic_enable(might_resched);
++ preempt_dynamic_disable(preempt_schedule);
++ preempt_dynamic_disable(preempt_schedule_notrace);
++ preempt_dynamic_disable(irqentry_exit_cond_resched);
++ pr_info("Dynamic Preempt: voluntary\n");
++ break;
++
++ case preempt_dynamic_full:
++ preempt_dynamic_disable(cond_resched);
++ preempt_dynamic_disable(might_resched);
++ preempt_dynamic_enable(preempt_schedule);
++ preempt_dynamic_enable(preempt_schedule_notrace);
++ preempt_dynamic_enable(irqentry_exit_cond_resched);
++ pr_info("Dynamic Preempt: full\n");
++ break;
++ }
++
++ preempt_dynamic_mode = mode;
++}
++
++static int __init setup_preempt_mode(char *str)
++{
++ int mode = sched_dynamic_mode(str);
++ if (mode < 0) {
++ pr_warn("Dynamic Preempt: unsupported mode: %s\n", str);
++ return 0;
++ }
++
++ sched_dynamic_update(mode);
++ return 1;
++}
++__setup("preempt=", setup_preempt_mode);
++
++static void __init preempt_dynamic_init(void)
++{
++ if (preempt_dynamic_mode == preempt_dynamic_undefined) {
++ if (IS_ENABLED(CONFIG_PREEMPT_NONE)) {
++ sched_dynamic_update(preempt_dynamic_none);
++ } else if (IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY)) {
++ sched_dynamic_update(preempt_dynamic_voluntary);
++ } else {
++ /* Default static call setting, nothing to do */
++ WARN_ON_ONCE(!IS_ENABLED(CONFIG_PREEMPT));
++ preempt_dynamic_mode = preempt_dynamic_full;
++ pr_info("Dynamic Preempt: full\n");
++ }
++ }
++}
++
++#define PREEMPT_MODEL_ACCESSOR(mode) \
++ bool preempt_model_##mode(void) \
++ { \
++ WARN_ON_ONCE(preempt_dynamic_mode == preempt_dynamic_undefined); \
++ return preempt_dynamic_mode == preempt_dynamic_##mode; \
++ } \
++ EXPORT_SYMBOL_GPL(preempt_model_##mode)
++
++PREEMPT_MODEL_ACCESSOR(none);
++PREEMPT_MODEL_ACCESSOR(voluntary);
++PREEMPT_MODEL_ACCESSOR(full);
++
++#else /* !CONFIG_PREEMPT_DYNAMIC */
++
++static inline void preempt_dynamic_init(void) { }
++
++#endif /* #ifdef CONFIG_PREEMPT_DYNAMIC */
++
++/**
++ * yield - yield the current processor to other threads.
++ *
++ * Do not ever use this function, there's a 99% chance you're doing it wrong.
++ *
++ * The scheduler is at all times free to pick the calling task as the most
++ * eligible task to run, if removing the yield() call from your code breaks
++ * it, it's already broken.
++ *
++ * Typical broken usage is:
++ *
++ * while (!event)
++ * yield();
++ *
++ * where one assumes that yield() will let 'the other' process run that will
++ * make event true. If the current task is a SCHED_FIFO task that will never
++ * happen. Never use yield() as a progress guarantee!!
++ *
++ * If you want to use yield() to wait for something, use wait_event().
++ * If you want to use yield() to be 'nice' for others, use cond_resched().
++ * If you still want to use yield(), do not!
++ */
++void __sched yield(void)
++{
++ set_current_state(TASK_RUNNING);
++ do_sched_yield();
++}
++EXPORT_SYMBOL(yield);
++
++/**
++ * yield_to - yield the current processor to another thread in
++ * your thread group, or accelerate that thread toward the
++ * processor it's on.
++ * @p: target task
++ * @preempt: whether task preemption is allowed or not
++ *
++ * It's the caller's job to ensure that the target task struct
++ * can't go away on us before we can do any checks.
++ *
++ * In Alt schedule FW, yield_to is not supported.
++ *
++ * Return:
++ * true (>0) if we indeed boosted the target task.
++ * false (0) if we failed to boost the target.
++ * -ESRCH if there's no task to yield to.
++ */
++int __sched yield_to(struct task_struct *p, bool preempt)
++{
++ return 0;
++}
++EXPORT_SYMBOL_GPL(yield_to);
++
++int io_schedule_prepare(void)
++{
++ int old_iowait = current->in_iowait;
++
++ current->in_iowait = 1;
++ blk_flush_plug(current->plug, true);
++ return old_iowait;
++}
++
++void io_schedule_finish(int token)
++{
++ current->in_iowait = token;
++}
++
++/*
++ * This task is about to go to sleep on IO. Increment rq->nr_iowait so
++ * that process accounting knows that this is a task in IO wait state.
++ *
++ * But don't do that if it is a deliberate, throttling IO wait (this task
++ * has set its backing_dev_info: the queue against which it should throttle)
++ */
++
++long __sched io_schedule_timeout(long timeout)
++{
++ int token;
++ long ret;
++
++ token = io_schedule_prepare();
++ ret = schedule_timeout(timeout);
++ io_schedule_finish(token);
++
++ return ret;
++}
++EXPORT_SYMBOL(io_schedule_timeout);
++
++void __sched io_schedule(void)
++{
++ int token;
++
++ token = io_schedule_prepare();
++ schedule();
++ io_schedule_finish(token);
++}
++EXPORT_SYMBOL(io_schedule);
++
++/**
++ * sys_sched_get_priority_max - return maximum RT priority.
++ * @policy: scheduling class.
++ *
++ * Return: On success, this syscall returns the maximum
++ * rt_priority that can be used by a given scheduling class.
++ * On failure, a negative error code is returned.
++ */
++SYSCALL_DEFINE1(sched_get_priority_max, int, policy)
++{
++ int ret = -EINVAL;
++
++ switch (policy) {
++ case SCHED_FIFO:
++ case SCHED_RR:
++ ret = MAX_RT_PRIO - 1;
++ break;
++ case SCHED_NORMAL:
++ case SCHED_BATCH:
++ case SCHED_IDLE:
++ ret = 0;
++ break;
++ }
++ return ret;
++}
++
++/**
++ * sys_sched_get_priority_min - return minimum RT priority.
++ * @policy: scheduling class.
++ *
++ * Return: On success, this syscall returns the minimum
++ * rt_priority that can be used by a given scheduling class.
++ * On failure, a negative error code is returned.
++ */
++SYSCALL_DEFINE1(sched_get_priority_min, int, policy)
++{
++ int ret = -EINVAL;
++
++ switch (policy) {
++ case SCHED_FIFO:
++ case SCHED_RR:
++ ret = 1;
++ break;
++ case SCHED_NORMAL:
++ case SCHED_BATCH:
++ case SCHED_IDLE:
++ ret = 0;
++ break;
++ }
++ return ret;
++}
++
++static int sched_rr_get_interval(pid_t pid, struct timespec64 *t)
++{
++ struct task_struct *p;
++ int retval;
++
++ alt_sched_debug();
++
++ if (pid < 0)
++ return -EINVAL;
++
++ retval = -ESRCH;
++ rcu_read_lock();
++ p = find_process_by_pid(pid);
++ if (!p)
++ goto out_unlock;
++
++ retval = security_task_getscheduler(p);
++ if (retval)
++ goto out_unlock;
++ rcu_read_unlock();
++
++ *t = ns_to_timespec64(sched_timeslice_ns);
++ return 0;
++
++out_unlock:
++ rcu_read_unlock();
++ return retval;
++}
++
++/**
++ * sys_sched_rr_get_interval - return the default timeslice of a process.
++ * @pid: pid of the process.
++ * @interval: userspace pointer to the timeslice value.
++ *
++ *
++ * Return: On success, 0 and the timeslice is in @interval. Otherwise,
++ * an error code.
++ */
++SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
++ struct __kernel_timespec __user *, interval)
++{
++ struct timespec64 t;
++ int retval = sched_rr_get_interval(pid, &t);
++
++ if (retval == 0)
++ retval = put_timespec64(&t, interval);
++
++ return retval;
++}
++
++#ifdef CONFIG_COMPAT_32BIT_TIME
++SYSCALL_DEFINE2(sched_rr_get_interval_time32, pid_t, pid,
++ struct old_timespec32 __user *, interval)
++{
++ struct timespec64 t;
++ int retval = sched_rr_get_interval(pid, &t);
++
++ if (retval == 0)
++ retval = put_old_timespec32(&t, interval);
++ return retval;
++}
++#endif
++
++void sched_show_task(struct task_struct *p)
++{
++ unsigned long free = 0;
++ int ppid;
++
++ if (!try_get_task_stack(p))
++ return;
++
++ pr_info("task:%-15.15s state:%c", p->comm, task_state_to_char(p));
++
++ if (task_is_running(p))
++ pr_cont(" running task ");
++#ifdef CONFIG_DEBUG_STACK_USAGE
++ free = stack_not_used(p);
++#endif
++ ppid = 0;
++ rcu_read_lock();
++ if (pid_alive(p))
++ ppid = task_pid_nr(rcu_dereference(p->real_parent));
++ rcu_read_unlock();
++ pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
++ free, task_pid_nr(p), ppid,
++ read_task_thread_flags(p));
++
++ print_worker_info(KERN_INFO, p);
++ print_stop_info(KERN_INFO, p);
++ show_stack(p, NULL, KERN_INFO);
++ put_task_stack(p);
++}
++EXPORT_SYMBOL_GPL(sched_show_task);
++
++static inline bool
++state_filter_match(unsigned long state_filter, struct task_struct *p)
++{
++ unsigned int state = READ_ONCE(p->__state);
++
++ /* no filter, everything matches */
++ if (!state_filter)
++ return true;
++
++ /* filter, but doesn't match */
++ if (!(state & state_filter))
++ return false;
++
++ /*
++ * When looking for TASK_UNINTERRUPTIBLE skip TASK_IDLE (allows
++ * TASK_KILLABLE).
++ */
++ if (state_filter == TASK_UNINTERRUPTIBLE && state == TASK_IDLE)
++ return false;
++
++ return true;
++}
++
++
++void show_state_filter(unsigned int state_filter)
++{
++ struct task_struct *g, *p;
++
++ rcu_read_lock();
++ for_each_process_thread(g, p) {
++ /*
++ * reset the NMI-timeout, listing all files on a slow
++ * console might take a lot of time:
++ * Also, reset softlockup watchdogs on all CPUs, because
++ * another CPU might be blocked waiting for us to process
++ * an IPI.
++ */
++ touch_nmi_watchdog();
++ touch_all_softlockup_watchdogs();
++ if (state_filter_match(state_filter, p))
++ sched_show_task(p);
++ }
++
++#ifdef CONFIG_SCHED_DEBUG
++ /* TODO: Alt schedule FW should support this
++ if (!state_filter)
++ sysrq_sched_debug_show();
++ */
++#endif
++ rcu_read_unlock();
++ /*
++ * Only show locks if all tasks are dumped:
++ */
++ if (!state_filter)
++ debug_show_all_locks();
++}
++
++void dump_cpu_task(int cpu)
++{
++ pr_info("Task dump for CPU %d:\n", cpu);
++ sched_show_task(cpu_curr(cpu));
++}
++
++/**
++ * init_idle - set up an idle thread for a given CPU
++ * @idle: task in question
++ * @cpu: CPU the idle task belongs to
++ *
++ * NOTE: this function does not set the idle thread's NEED_RESCHED
++ * flag, to make booting more robust.
++ */
++void __init init_idle(struct task_struct *idle, int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++
++ __sched_fork(0, idle);
++
++ raw_spin_lock_irqsave(&idle->pi_lock, flags);
++ raw_spin_lock(&rq->lock);
++ update_rq_clock(rq);
++
++ idle->last_ran = rq->clock_task;
++ idle->__state = TASK_RUNNING;
++ /*
++ * PF_KTHREAD should already be set at this point; regardless, make it
++ * look like a proper per-CPU kthread.
++ */
++ idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY;
++ kthread_set_per_cpu(idle, cpu);
++
++ sched_queue_init_idle(&rq->queue, idle);
++
++#ifdef CONFIG_SMP
++ /*
++ * It's possible that init_idle() gets called multiple times on a task,
++ * in that case do_set_cpus_allowed() will not do the right thing.
++ *
++ * And since this is boot we can forgo the serialisation.
++ */
++ set_cpus_allowed_common(idle, cpumask_of(cpu));
++#endif
++
++ /* Silence PROVE_RCU */
++ rcu_read_lock();
++ __set_task_cpu(idle, cpu);
++ rcu_read_unlock();
++
++ rq->idle = idle;
++ rcu_assign_pointer(rq->curr, idle);
++ idle->on_cpu = 1;
++
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock_irqrestore(&idle->pi_lock, flags);
++
++ /* Set the preempt count _outside_ the spinlocks! */
++ init_idle_preempt_count(idle, cpu);
++
++ ftrace_graph_init_idle_task(idle, cpu);
++ vtime_init_idle(idle, cpu);
++#ifdef CONFIG_SMP
++ sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
++#endif
++}
++
++#ifdef CONFIG_SMP
++
++int cpuset_cpumask_can_shrink(const struct cpumask __maybe_unused *cur,
++ const struct cpumask __maybe_unused *trial)
++{
++ return 1;
++}
++
++int task_can_attach(struct task_struct *p,
++ const struct cpumask *cs_effective_cpus)
++{
++ int ret = 0;
++
++ /*
++ * Kthreads which disallow setaffinity shouldn't be moved
++ * to a new cpuset; we don't want to change their CPU
++ * affinity and isolating such threads by their set of
++ * allowed nodes is unnecessary. Thus, cpusets are not
++ * applicable for such threads. This prevents checking for
++ * success of set_cpus_allowed_ptr() on all attached tasks
++ * before cpus_mask may be changed.
++ */
++ if (p->flags & PF_NO_SETAFFINITY)
++ ret = -EINVAL;
++
++ return ret;
++}
++
++bool sched_smp_initialized __read_mostly;
++
++#ifdef CONFIG_HOTPLUG_CPU
++/*
++ * Ensures that the idle task is using init_mm right before its CPU goes
++ * offline.
++ */
++void idle_task_exit(void)
++{
++ struct mm_struct *mm = current->active_mm;
++
++ BUG_ON(current != this_rq()->idle);
++
++ if (mm != &init_mm) {
++ switch_mm(mm, &init_mm, current);
++ finish_arch_post_lock_switch();
++ }
++
++ /* finish_cpu(), as ran on the BP, will clean up the active_mm state */
++}
++
++static int __balance_push_cpu_stop(void *arg)
++{
++ struct task_struct *p = arg;
++ struct rq *rq = this_rq();
++ struct rq_flags rf;
++ int cpu;
++
++ raw_spin_lock_irq(&p->pi_lock);
++ rq_lock(rq, &rf);
++
++ update_rq_clock(rq);
++
++ if (task_rq(p) == rq && task_on_rq_queued(p)) {
++ cpu = select_fallback_rq(rq->cpu, p);
++ rq = __migrate_task(rq, p, cpu);
++ }
++
++ rq_unlock(rq, &rf);
++ raw_spin_unlock_irq(&p->pi_lock);
++
++ put_task_struct(p);
++
++ return 0;
++}
++
++static DEFINE_PER_CPU(struct cpu_stop_work, push_work);
++
++/*
++ * This is enabled below SCHED_AP_ACTIVE; when !cpu_active(), but only
++ * effective when the hotplug motion is down.
++ */
++static void balance_push(struct rq *rq)
++{
++ struct task_struct *push_task = rq->curr;
++
++ lockdep_assert_held(&rq->lock);
++
++ /*
++ * Ensure the thing is persistent until balance_push_set(.on = false);
++ */
++ rq->balance_callback = &balance_push_callback;
++
++ /*
++ * Only active while going offline and when invoked on the outgoing
++ * CPU.
++ */
++ if (!cpu_dying(rq->cpu) || rq != this_rq())
++ return;
++
++ /*
++ * Both the cpu-hotplug and stop task are in this case and are
++ * required to complete the hotplug process.
++ */
++ if (kthread_is_per_cpu(push_task) ||
++ is_migration_disabled(push_task)) {
++
++ /*
++ * If this is the idle task on the outgoing CPU try to wake
++ * up the hotplug control thread which might wait for the
++ * last task to vanish. The rcuwait_active() check is
++ * accurate here because the waiter is pinned on this CPU
++ * and can't obviously be running in parallel.
++ *
++ * On RT kernels this also has to check whether there are
++ * pinned and scheduled out tasks on the runqueue. They
++ * need to leave the migrate disabled section first.
++ */
++ if (!rq->nr_running && !rq_has_pinned_tasks(rq) &&
++ rcuwait_active(&rq->hotplug_wait)) {
++ raw_spin_unlock(&rq->lock);
++ rcuwait_wake_up(&rq->hotplug_wait);
++ raw_spin_lock(&rq->lock);
++ }
++ return;
++ }
++
++ get_task_struct(push_task);
++ /*
++ * Temporarily drop rq->lock such that we can wake-up the stop task.
++ * Both preemption and IRQs are still disabled.
++ */
++ raw_spin_unlock(&rq->lock);
++ stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task,
++ this_cpu_ptr(&push_work));
++ /*
++ * At this point need_resched() is true and we'll take the loop in
++ * schedule(). The next pick is obviously going to be the stop task
++ * which kthread_is_per_cpu() and will push this task away.
++ */
++ raw_spin_lock(&rq->lock);
++}
++
++static void balance_push_set(int cpu, bool on)
++{
++ struct rq *rq = cpu_rq(cpu);
++ struct rq_flags rf;
++
++ rq_lock_irqsave(rq, &rf);
++ if (on) {
++ WARN_ON_ONCE(rq->balance_callback);
++ rq->balance_callback = &balance_push_callback;
++ } else if (rq->balance_callback == &balance_push_callback) {
++ rq->balance_callback = NULL;
++ }
++ rq_unlock_irqrestore(rq, &rf);
++}
++
++/*
++ * Invoked from a CPUs hotplug control thread after the CPU has been marked
++ * inactive. All tasks which are not per CPU kernel threads are either
++ * pushed off this CPU now via balance_push() or placed on a different CPU
++ * during wakeup. Wait until the CPU is quiescent.
++ */
++static void balance_hotplug_wait(void)
++{
++ struct rq *rq = this_rq();
++
++ rcuwait_wait_event(&rq->hotplug_wait,
++ rq->nr_running == 1 && !rq_has_pinned_tasks(rq),
++ TASK_UNINTERRUPTIBLE);
++}
++
++#else
++
++static void balance_push(struct rq *rq)
++{
++}
++
++static void balance_push_set(int cpu, bool on)
++{
++}
++
++static inline void balance_hotplug_wait(void)
++{
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static void set_rq_offline(struct rq *rq)
++{
++ if (rq->online)
++ rq->online = false;
++}
++
++static void set_rq_online(struct rq *rq)
++{
++ if (!rq->online)
++ rq->online = true;
++}
++
++/*
++ * used to mark begin/end of suspend/resume:
++ */
++static int num_cpus_frozen;
++
++/*
++ * Update cpusets according to cpu_active mask. If cpusets are
++ * disabled, cpuset_update_active_cpus() becomes a simple wrapper
++ * around partition_sched_domains().
++ *
++ * If we come here as part of a suspend/resume, don't touch cpusets because we
++ * want to restore it back to its original state upon resume anyway.
++ */
++static void cpuset_cpu_active(void)
++{
++ if (cpuhp_tasks_frozen) {
++ /*
++ * num_cpus_frozen tracks how many CPUs are involved in suspend
++ * resume sequence. As long as this is not the last online
++ * operation in the resume sequence, just build a single sched
++ * domain, ignoring cpusets.
++ */
++ partition_sched_domains(1, NULL, NULL);
++ if (--num_cpus_frozen)
++ return;
++ /*
++ * This is the last CPU online operation. So fall through and
++ * restore the original sched domains by considering the
++ * cpuset configurations.
++ */
++ cpuset_force_rebuild();
++ }
++
++ cpuset_update_active_cpus();
++}
++
++static int cpuset_cpu_inactive(unsigned int cpu)
++{
++ if (!cpuhp_tasks_frozen) {
++ cpuset_update_active_cpus();
++ } else {
++ num_cpus_frozen++;
++ partition_sched_domains(1, NULL, NULL);
++ }
++ return 0;
++}
++
++int sched_cpu_activate(unsigned int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++
++ /*
++ * Clear the balance_push callback and prepare to schedule
++ * regular tasks.
++ */
++ balance_push_set(cpu, false);
++
++#ifdef CONFIG_SCHED_SMT
++ /*
++ * When going up, increment the number of cores with SMT present.
++ */
++ if (cpumask_weight(cpu_smt_mask(cpu)) == 2)
++ static_branch_inc_cpuslocked(&sched_smt_present);
++#endif
++ set_cpu_active(cpu, true);
++
++ if (sched_smp_initialized)
++ cpuset_cpu_active();
++
++ /*
++ * Put the rq online, if not already. This happens:
++ *
++ * 1) In the early boot process, because we build the real domains
++ * after all cpus have been brought up.
++ *
++ * 2) At runtime, if cpuset_cpu_active() fails to rebuild the
++ * domains.
++ */
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ set_rq_online(rq);
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++ return 0;
++}
++
++int sched_cpu_deactivate(unsigned int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++ int ret;
++
++ set_cpu_active(cpu, false);
++
++ /*
++ * From this point forward, this CPU will refuse to run any task that
++ * is not: migrate_disable() or KTHREAD_IS_PER_CPU, and will actively
++ * push those tasks away until this gets cleared, see
++ * sched_cpu_dying().
++ */
++ balance_push_set(cpu, true);
++
++ /*
++ * We've cleared cpu_active_mask, wait for all preempt-disabled and RCU
++ * users of this state to go away such that all new such users will
++ * observe it.
++ *
++ * Specifically, we rely on ttwu to no longer target this CPU, see
++ * ttwu_queue_cond() and is_cpu_allowed().
++ *
++ * Do sync before park smpboot threads to take care the rcu boost case.
++ */
++ synchronize_rcu();
++
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ update_rq_clock(rq);
++ set_rq_offline(rq);
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++#ifdef CONFIG_SCHED_SMT
++ /*
++ * When going down, decrement the number of cores with SMT present.
++ */
++ if (cpumask_weight(cpu_smt_mask(cpu)) == 2) {
++ static_branch_dec_cpuslocked(&sched_smt_present);
++ if (!static_branch_likely(&sched_smt_present))
++ cpumask_clear(&sched_sg_idle_mask);
++ }
++#endif
++
++ if (!sched_smp_initialized)
++ return 0;
++
++ ret = cpuset_cpu_inactive(cpu);
++ if (ret) {
++ balance_push_set(cpu, false);
++ set_cpu_active(cpu, true);
++ return ret;
++ }
++
++ return 0;
++}
++
++static void sched_rq_cpu_starting(unsigned int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++
++ rq->calc_load_update = calc_load_update;
++}
++
++int sched_cpu_starting(unsigned int cpu)
++{
++ sched_rq_cpu_starting(cpu);
++ sched_tick_start(cpu);
++ return 0;
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++/*
++ * Invoked immediately before the stopper thread is invoked to bring the
++ * CPU down completely. At this point all per CPU kthreads except the
++ * hotplug thread (current) and the stopper thread (inactive) have been
++ * either parked or have been unbound from the outgoing CPU. Ensure that
++ * any of those which might be on the way out are gone.
++ *
++ * If after this point a bound task is being woken on this CPU then the
++ * responsible hotplug callback has failed to do it's job.
++ * sched_cpu_dying() will catch it with the appropriate fireworks.
++ */
++int sched_cpu_wait_empty(unsigned int cpu)
++{
++ balance_hotplug_wait();
++ return 0;
++}
++
++/*
++ * Since this CPU is going 'away' for a while, fold any nr_active delta we
++ * might have. Called from the CPU stopper task after ensuring that the
++ * stopper is the last running task on the CPU, so nr_active count is
++ * stable. We need to take the teardown thread which is calling this into
++ * account, so we hand in adjust = 1 to the load calculation.
++ *
++ * Also see the comment "Global load-average calculations".
++ */
++static void calc_load_migrate(struct rq *rq)
++{
++ long delta = calc_load_fold_active(rq, 1);
++
++ if (delta)
++ atomic_long_add(delta, &calc_load_tasks);
++}
++
++static void dump_rq_tasks(struct rq *rq, const char *loglvl)
++{
++ struct task_struct *g, *p;
++ int cpu = cpu_of(rq);
++
++ lockdep_assert_held(&rq->lock);
++
++ printk("%sCPU%d enqueued tasks (%u total):\n", loglvl, cpu, rq->nr_running);
++ for_each_process_thread(g, p) {
++ if (task_cpu(p) != cpu)
++ continue;
++
++ if (!task_on_rq_queued(p))
++ continue;
++
++ printk("%s\tpid: %d, name: %s\n", loglvl, p->pid, p->comm);
++ }
++}
++
++int sched_cpu_dying(unsigned int cpu)
++{
++ struct rq *rq = cpu_rq(cpu);
++ unsigned long flags;
++
++ /* Handle pending wakeups and then migrate everything off */
++ sched_tick_stop(cpu);
++
++ raw_spin_lock_irqsave(&rq->lock, flags);
++ if (rq->nr_running != 1 || rq_has_pinned_tasks(rq)) {
++ WARN(true, "Dying CPU not properly vacated!");
++ dump_rq_tasks(rq, KERN_WARNING);
++ }
++ raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++ calc_load_migrate(rq);
++ hrtick_clear(rq);
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_SMP
++static void sched_init_topology_cpumask_early(void)
++{
++ int cpu;
++ cpumask_t *tmp;
++
++ for_each_possible_cpu(cpu) {
++ /* init topo masks */
++ tmp = per_cpu(sched_cpu_topo_masks, cpu);
++
++ cpumask_copy(tmp, cpumask_of(cpu));
++ tmp++;
++ cpumask_copy(tmp, cpu_possible_mask);
++ per_cpu(sched_cpu_llc_mask, cpu) = tmp;
++ per_cpu(sched_cpu_topo_end_mask, cpu) = ++tmp;
++ /*per_cpu(sd_llc_id, cpu) = cpu;*/
++ }
++}
++
++#define TOPOLOGY_CPUMASK(name, mask, last)\
++ if (cpumask_and(topo, topo, mask)) { \
++ cpumask_copy(topo, mask); \
++ printk(KERN_INFO "sched: cpu#%02d topo: 0x%08lx - "#name, \
++ cpu, (topo++)->bits[0]); \
++ } \
++ if (!last) \
++ cpumask_complement(topo, mask)
++
++static void sched_init_topology_cpumask(void)
++{
++ int cpu;
++ cpumask_t *topo;
++
++ for_each_online_cpu(cpu) {
++ /* take chance to reset time slice for idle tasks */
++ cpu_rq(cpu)->idle->time_slice = sched_timeslice_ns;
++
++ topo = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++
++ cpumask_complement(topo, cpumask_of(cpu));
++#ifdef CONFIG_SCHED_SMT
++ TOPOLOGY_CPUMASK(smt, topology_sibling_cpumask(cpu), false);
++#endif
++ per_cpu(sd_llc_id, cpu) = cpumask_first(cpu_coregroup_mask(cpu));
++ per_cpu(sched_cpu_llc_mask, cpu) = topo;
++ TOPOLOGY_CPUMASK(coregroup, cpu_coregroup_mask(cpu), false);
++
++ TOPOLOGY_CPUMASK(core, topology_core_cpumask(cpu), false);
++
++ TOPOLOGY_CPUMASK(others, cpu_online_mask, true);
++
++ per_cpu(sched_cpu_topo_end_mask, cpu) = topo;
++ printk(KERN_INFO "sched: cpu#%02d llc_id = %d, llc_mask idx = %d\n",
++ cpu, per_cpu(sd_llc_id, cpu),
++ (int) (per_cpu(sched_cpu_llc_mask, cpu) -
++ per_cpu(sched_cpu_topo_masks, cpu)));
++ }
++}
++#endif
++
++void __init sched_init_smp(void)
++{
++ /* Move init over to a non-isolated CPU */
++ if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_DOMAIN)) < 0)
++ BUG();
++ current->flags &= ~PF_NO_SETAFFINITY;
++
++ sched_init_topology_cpumask();
++
++ sched_smp_initialized = true;
++}
++#else
++void __init sched_init_smp(void)
++{
++ cpu_rq(0)->idle->time_slice = sched_timeslice_ns;
++}
++#endif /* CONFIG_SMP */
++
++int in_sched_functions(unsigned long addr)
++{
++ return in_lock_functions(addr) ||
++ (addr >= (unsigned long)__sched_text_start
++ && addr < (unsigned long)__sched_text_end);
++}
++
++#ifdef CONFIG_CGROUP_SCHED
++/* task group related information */
++struct task_group {
++ struct cgroup_subsys_state css;
++
++ struct rcu_head rcu;
++ struct list_head list;
++
++ struct task_group *parent;
++ struct list_head siblings;
++ struct list_head children;
++#ifdef CONFIG_FAIR_GROUP_SCHED
++ unsigned long shares;
++#endif
++};
++
++/*
++ * Default task group.
++ * Every task in system belongs to this group at bootup.
++ */
++struct task_group root_task_group;
++LIST_HEAD(task_groups);
++
++/* Cacheline aligned slab cache for task_group */
++static struct kmem_cache *task_group_cache __read_mostly;
++#endif /* CONFIG_CGROUP_SCHED */
++
++void __init sched_init(void)
++{
++ int i;
++ struct rq *rq;
++
++ printk(KERN_INFO ALT_SCHED_VERSION_MSG);
++
++ wait_bit_init();
++
++#ifdef CONFIG_SMP
++ for (i = 0; i < SCHED_QUEUE_BITS; i++)
++ cpumask_copy(sched_rq_watermark + i, cpu_present_mask);
++#endif
++
++#ifdef CONFIG_CGROUP_SCHED
++ task_group_cache = KMEM_CACHE(task_group, 0);
++
++ list_add(&root_task_group.list, &task_groups);
++ INIT_LIST_HEAD(&root_task_group.children);
++ INIT_LIST_HEAD(&root_task_group.siblings);
++#endif /* CONFIG_CGROUP_SCHED */
++ for_each_possible_cpu(i) {
++ rq = cpu_rq(i);
++
++ sched_queue_init(&rq->queue);
++ rq->watermark = IDLE_TASK_SCHED_PRIO;
++ rq->skip = NULL;
++
++ raw_spin_lock_init(&rq->lock);
++ rq->nr_running = rq->nr_uninterruptible = 0;
++ rq->calc_load_active = 0;
++ rq->calc_load_update = jiffies + LOAD_FREQ;
++#ifdef CONFIG_SMP
++ rq->online = false;
++ rq->cpu = i;
++
++#ifdef CONFIG_SCHED_SMT
++ rq->active_balance = 0;
++#endif
++
++#ifdef CONFIG_NO_HZ_COMMON
++ INIT_CSD(&rq->nohz_csd, nohz_csd_func, rq);
++#endif
++ rq->balance_callback = &balance_push_callback;
++#ifdef CONFIG_HOTPLUG_CPU
++ rcuwait_init(&rq->hotplug_wait);
++#endif
++#endif /* CONFIG_SMP */
++ rq->nr_switches = 0;
++
++ hrtick_rq_init(rq);
++ atomic_set(&rq->nr_iowait, 0);
++ }
++#ifdef CONFIG_SMP
++ /* Set rq->online for cpu 0 */
++ cpu_rq(0)->online = true;
++#endif
++ /*
++ * The boot idle thread does lazy MMU switching as well:
++ */
++ mmgrab(&init_mm);
++ enter_lazy_tlb(&init_mm, current);
++
++ /*
++ * The idle task doesn't need the kthread struct to function, but it
++ * is dressed up as a per-CPU kthread and thus needs to play the part
++ * if we want to avoid special-casing it in code that deals with per-CPU
++ * kthreads.
++ */
++ WARN_ON(!set_kthread_struct(current));
++
++ /*
++ * Make us the idle thread. Technically, schedule() should not be
++ * called from this thread, however somewhere below it might be,
++ * but because we are the idle thread, we just pick up running again
++ * when this runqueue becomes "idle".
++ */
++ init_idle(current, smp_processor_id());
++
++ calc_load_update = jiffies + LOAD_FREQ;
++
++#ifdef CONFIG_SMP
++ idle_thread_set_boot_cpu();
++ balance_push_set(smp_processor_id(), false);
++
++ sched_init_topology_cpumask_early();
++#endif /* SMP */
++
++ psi_init();
++
++ preempt_dynamic_init();
++}
++
++#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
++
++void __might_sleep(const char *file, int line)
++{
++ unsigned int state = get_current_state();
++ /*
++ * Blocking primitives will set (and therefore destroy) current->state,
++ * since we will exit with TASK_RUNNING make sure we enter with it,
++ * otherwise we will destroy state.
++ */
++ WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
++ "do not call blocking ops when !TASK_RUNNING; "
++ "state=%x set at [<%p>] %pS\n", state,
++ (void *)current->task_state_change,
++ (void *)current->task_state_change);
++
++ __might_resched(file, line, 0);
++}
++EXPORT_SYMBOL(__might_sleep);
++
++static void print_preempt_disable_ip(int preempt_offset, unsigned long ip)
++{
++ if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT))
++ return;
++
++ if (preempt_count() == preempt_offset)
++ return;
++
++ pr_err("Preemption disabled at:");
++ print_ip_sym(KERN_ERR, ip);
++}
++
++static inline bool resched_offsets_ok(unsigned int offsets)
++{
++ unsigned int nested = preempt_count();
++
++ nested += rcu_preempt_depth() << MIGHT_RESCHED_RCU_SHIFT;
++
++ return nested == offsets;
++}
++
++void __might_resched(const char *file, int line, unsigned int offsets)
++{
++ /* Ratelimiting timestamp: */
++ static unsigned long prev_jiffy;
++
++ unsigned long preempt_disable_ip;
++
++ /* WARN_ON_ONCE() by default, no rate limit required: */
++ rcu_sleep_check();
++
++ if ((resched_offsets_ok(offsets) && !irqs_disabled() &&
++ !is_idle_task(current) && !current->non_block_count) ||
++ system_state == SYSTEM_BOOTING || system_state > SYSTEM_RUNNING ||
++ oops_in_progress)
++ return;
++ if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++ return;
++ prev_jiffy = jiffies;
++
++ /* Save this before calling printk(), since that will clobber it: */
++ preempt_disable_ip = get_preempt_disable_ip(current);
++
++ pr_err("BUG: sleeping function called from invalid context at %s:%d\n",
++ file, line);
++ pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
++ in_atomic(), irqs_disabled(), current->non_block_count,
++ current->pid, current->comm);
++ pr_err("preempt_count: %x, expected: %x\n", preempt_count(),
++ offsets & MIGHT_RESCHED_PREEMPT_MASK);
++
++ if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {
++ pr_err("RCU nest depth: %d, expected: %u\n",
++ rcu_preempt_depth(), offsets >> MIGHT_RESCHED_RCU_SHIFT);
++ }
++
++ if (task_stack_end_corrupted(current))
++ pr_emerg("Thread overran stack, or stack corrupted\n");
++
++ debug_show_held_locks(current);
++ if (irqs_disabled())
++ print_irqtrace_events(current);
++
++ print_preempt_disable_ip(offsets & MIGHT_RESCHED_PREEMPT_MASK,
++ preempt_disable_ip);
++
++ dump_stack();
++ add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL(__might_resched);
++
++void __cant_sleep(const char *file, int line, int preempt_offset)
++{
++ static unsigned long prev_jiffy;
++
++ if (irqs_disabled())
++ return;
++
++ if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
++ return;
++
++ if (preempt_count() > preempt_offset)
++ return;
++
++ if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++ return;
++ prev_jiffy = jiffies;
++
++ printk(KERN_ERR "BUG: assuming atomic context at %s:%d\n", file, line);
++ printk(KERN_ERR "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
++ in_atomic(), irqs_disabled(),
++ current->pid, current->comm);
++
++ debug_show_held_locks(current);
++ dump_stack();
++ add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL_GPL(__cant_sleep);
++
++#ifdef CONFIG_SMP
++void __cant_migrate(const char *file, int line)
++{
++ static unsigned long prev_jiffy;
++
++ if (irqs_disabled())
++ return;
++
++ if (is_migration_disabled(current))
++ return;
++
++ if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
++ return;
++
++ if (preempt_count() > 0)
++ return;
++
++ if (current->migration_flags & MDF_FORCE_ENABLED)
++ return;
++
++ if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++ return;
++ prev_jiffy = jiffies;
++
++ pr_err("BUG: assuming non migratable context at %s:%d\n", file, line);
++ pr_err("in_atomic(): %d, irqs_disabled(): %d, migration_disabled() %u pid: %d, name: %s\n",
++ in_atomic(), irqs_disabled(), is_migration_disabled(current),
++ current->pid, current->comm);
++
++ debug_show_held_locks(current);
++ dump_stack();
++ add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL_GPL(__cant_migrate);
++#endif
++#endif
++
++#ifdef CONFIG_MAGIC_SYSRQ
++void normalize_rt_tasks(void)
++{
++ struct task_struct *g, *p;
++ struct sched_attr attr = {
++ .sched_policy = SCHED_NORMAL,
++ };
++
++ read_lock(&tasklist_lock);
++ for_each_process_thread(g, p) {
++ /*
++ * Only normalize user tasks:
++ */
++ if (p->flags & PF_KTHREAD)
++ continue;
++
++ schedstat_set(p->stats.wait_start, 0);
++ schedstat_set(p->stats.sleep_start, 0);
++ schedstat_set(p->stats.block_start, 0);
++
++ if (!rt_task(p)) {
++ /*
++ * Renice negative nice level userspace
++ * tasks back to 0:
++ */
++ if (task_nice(p) < 0)
++ set_user_nice(p, 0);
++ continue;
++ }
++
++ __sched_setscheduler(p, &attr, false, false);
++ }
++ read_unlock(&tasklist_lock);
++}
++#endif /* CONFIG_MAGIC_SYSRQ */
++
++#if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB)
++/*
++ * These functions are only useful for the IA64 MCA handling, or kdb.
++ *
++ * They can only be called when the whole system has been
++ * stopped - every CPU needs to be quiescent, and no scheduling
++ * activity can take place. Using them for anything else would
++ * be a serious bug, and as a result, they aren't even visible
++ * under any other configuration.
++ */
++
++/**
++ * curr_task - return the current task for a given CPU.
++ * @cpu: the processor in question.
++ *
++ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
++ *
++ * Return: The current task for @cpu.
++ */
++struct task_struct *curr_task(int cpu)
++{
++ return cpu_curr(cpu);
++}
++
++#endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */
++
++#ifdef CONFIG_IA64
++/**
++ * ia64_set_curr_task - set the current task for a given CPU.
++ * @cpu: the processor in question.
++ * @p: the task pointer to set.
++ *
++ * Description: This function must only be used when non-maskable interrupts
++ * are serviced on a separate stack. It allows the architecture to switch the
++ * notion of the current task on a CPU in a non-blocking manner. This function
++ * must be called with all CPU's synchronised, and interrupts disabled, the
++ * and caller must save the original value of the current task (see
++ * curr_task() above) and restore that value before reenabling interrupts and
++ * re-starting the system.
++ *
++ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
++ */
++void ia64_set_curr_task(int cpu, struct task_struct *p)
++{
++ cpu_curr(cpu) = p;
++}
++
++#endif
++
++#ifdef CONFIG_CGROUP_SCHED
++static void sched_free_group(struct task_group *tg)
++{
++ kmem_cache_free(task_group_cache, tg);
++}
++
++static void sched_free_group_rcu(struct rcu_head *rhp)
++{
++ sched_free_group(container_of(rhp, struct task_group, rcu));
++}
++
++static void sched_unregister_group(struct task_group *tg)
++{
++ /*
++ * We have to wait for yet another RCU grace period to expire, as
++ * print_cfs_stats() might run concurrently.
++ */
++ call_rcu(&tg->rcu, sched_free_group_rcu);
++}
++
++/* allocate runqueue etc for a new task group */
++struct task_group *sched_create_group(struct task_group *parent)
++{
++ struct task_group *tg;
++
++ tg = kmem_cache_alloc(task_group_cache, GFP_KERNEL | __GFP_ZERO);
++ if (!tg)
++ return ERR_PTR(-ENOMEM);
++
++ return tg;
++}
++
++void sched_online_group(struct task_group *tg, struct task_group *parent)
++{
++}
++
++/* rcu callback to free various structures associated with a task group */
++static void sched_unregister_group_rcu(struct rcu_head *rhp)
++{
++ /* Now it should be safe to free those cfs_rqs: */
++ sched_unregister_group(container_of(rhp, struct task_group, rcu));
++}
++
++void sched_destroy_group(struct task_group *tg)
++{
++ /* Wait for possible concurrent references to cfs_rqs complete: */
++ call_rcu(&tg->rcu, sched_unregister_group_rcu);
++}
++
++void sched_release_group(struct task_group *tg)
++{
++}
++
++static inline struct task_group *css_tg(struct cgroup_subsys_state *css)
++{
++ return css ? container_of(css, struct task_group, css) : NULL;
++}
++
++static struct cgroup_subsys_state *
++cpu_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
++{
++ struct task_group *parent = css_tg(parent_css);
++ struct task_group *tg;
++
++ if (!parent) {
++ /* This is early initialization for the top cgroup */
++ return &root_task_group.css;
++ }
++
++ tg = sched_create_group(parent);
++ if (IS_ERR(tg))
++ return ERR_PTR(-ENOMEM);
++ return &tg->css;
++}
++
++/* Expose task group only after completing cgroup initialization */
++static int cpu_cgroup_css_online(struct cgroup_subsys_state *css)
++{
++ struct task_group *tg = css_tg(css);
++ struct task_group *parent = css_tg(css->parent);
++
++ if (parent)
++ sched_online_group(tg, parent);
++ return 0;
++}
++
++static void cpu_cgroup_css_released(struct cgroup_subsys_state *css)
++{
++ struct task_group *tg = css_tg(css);
++
++ sched_release_group(tg);
++}
++
++static void cpu_cgroup_css_free(struct cgroup_subsys_state *css)
++{
++ struct task_group *tg = css_tg(css);
++
++ /*
++ * Relies on the RCU grace period between css_released() and this.
++ */
++ sched_unregister_group(tg);
++}
++
++static void cpu_cgroup_fork(struct task_struct *task)
++{
++}
++
++static int cpu_cgroup_can_attach(struct cgroup_taskset *tset)
++{
++ return 0;
++}
++
++static void cpu_cgroup_attach(struct cgroup_taskset *tset)
++{
++}
++
++#ifdef CONFIG_FAIR_GROUP_SCHED
++static DEFINE_MUTEX(shares_mutex);
++
++int sched_group_set_shares(struct task_group *tg, unsigned long shares)
++{
++ /*
++ * We can't change the weight of the root cgroup.
++ */
++ if (&root_task_group == tg)
++ return -EINVAL;
++
++ shares = clamp(shares, scale_load(MIN_SHARES), scale_load(MAX_SHARES));
++
++ mutex_lock(&shares_mutex);
++ if (tg->shares == shares)
++ goto done;
++
++ tg->shares = shares;
++done:
++ mutex_unlock(&shares_mutex);
++ return 0;
++}
++
++static int cpu_shares_write_u64(struct cgroup_subsys_state *css,
++ struct cftype *cftype, u64 shareval)
++{
++ if (shareval > scale_load_down(ULONG_MAX))
++ shareval = MAX_SHARES;
++ return sched_group_set_shares(css_tg(css), scale_load(shareval));
++}
++
++static u64 cpu_shares_read_u64(struct cgroup_subsys_state *css,
++ struct cftype *cft)
++{
++ struct task_group *tg = css_tg(css);
++
++ return (u64) scale_load_down(tg->shares);
++}
++#endif
++
++static struct cftype cpu_legacy_files[] = {
++#ifdef CONFIG_FAIR_GROUP_SCHED
++ {
++ .name = "shares",
++ .read_u64 = cpu_shares_read_u64,
++ .write_u64 = cpu_shares_write_u64,
++ },
++#endif
++ { } /* Terminate */
++};
++
++
++static struct cftype cpu_files[] = {
++ { } /* terminate */
++};
++
++static int cpu_extra_stat_show(struct seq_file *sf,
++ struct cgroup_subsys_state *css)
++{
++ return 0;
++}
++
++struct cgroup_subsys cpu_cgrp_subsys = {
++ .css_alloc = cpu_cgroup_css_alloc,
++ .css_online = cpu_cgroup_css_online,
++ .css_released = cpu_cgroup_css_released,
++ .css_free = cpu_cgroup_css_free,
++ .css_extra_stat_show = cpu_extra_stat_show,
++ .fork = cpu_cgroup_fork,
++ .can_attach = cpu_cgroup_can_attach,
++ .attach = cpu_cgroup_attach,
++ .legacy_cftypes = cpu_files,
++ .legacy_cftypes = cpu_legacy_files,
++ .dfl_cftypes = cpu_files,
++ .early_init = true,
++ .threaded = true,
++};
++#endif /* CONFIG_CGROUP_SCHED */
++
++#undef CREATE_TRACE_POINTS
+diff --git a/kernel/sched/alt_debug.c b/kernel/sched/alt_debug.c
+new file mode 100644
+index 000000000000..1212a031700e
+--- /dev/null
++++ b/kernel/sched/alt_debug.c
+@@ -0,0 +1,31 @@
++/*
++ * kernel/sched/alt_debug.c
++ *
++ * Print the alt scheduler debugging details
++ *
++ * Author: Alfred Chen
++ * Date : 2020
++ */
++#include "sched.h"
++
++/*
++ * This allows printing both to /proc/sched_debug and
++ * to the console
++ */
++#define SEQ_printf(m, x...) \
++ do { \
++ if (m) \
++ seq_printf(m, x); \
++ else \
++ pr_cont(x); \
++ } while (0)
++
++void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
++ struct seq_file *m)
++{
++ SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, task_pid_nr_ns(p, ns),
++ get_nr_threads(p));
++}
++
++void proc_sched_set_task(struct task_struct *p)
++{}
+diff --git a/kernel/sched/alt_sched.h b/kernel/sched/alt_sched.h
+new file mode 100644
+index 000000000000..bec061f2ae10
+--- /dev/null
++++ b/kernel/sched/alt_sched.h
+@@ -0,0 +1,645 @@
++#ifndef ALT_SCHED_H
++#define ALT_SCHED_H
++
++#include <linux/context_tracking.h>
++#include <linux/psi.h>
++#include <linux/stop_machine.h>
++#include <linux/syscalls.h>
++#include <linux/tick.h>
++
++#include <trace/events/power.h>
++#include <trace/events/sched.h>
++
++#include "../workqueue_internal.h"
++
++#include "cpupri.h"
++
++#ifdef CONFIG_SCHED_BMQ
++/* bits:
++ * RT(0-99), (Low prio adj range, nice width, high prio adj range) / 2, cpu idle task */
++#define SCHED_BITS (MAX_RT_PRIO + NICE_WIDTH / 2 + MAX_PRIORITY_ADJ + 1)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++/* bits: RT(0-99), reserved(100-127), NORMAL_PRIO_NUM, cpu idle task */
++#define SCHED_BITS (MIN_NORMAL_PRIO + NORMAL_PRIO_NUM + 1)
++#endif /* CONFIG_SCHED_PDS */
++
++#define IDLE_TASK_SCHED_PRIO (SCHED_BITS - 1)
++
++#ifdef CONFIG_SCHED_DEBUG
++# define SCHED_WARN_ON(x) WARN_ONCE(x, #x)
++extern void resched_latency_warn(int cpu, u64 latency);
++#else
++# define SCHED_WARN_ON(x) ({ (void)(x), 0; })
++static inline void resched_latency_warn(int cpu, u64 latency) {}
++#endif
++
++/*
++ * Increase resolution of nice-level calculations for 64-bit architectures.
++ * The extra resolution improves shares distribution and load balancing of
++ * low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup
++ * hierarchies, especially on larger systems. This is not a user-visible change
++ * and does not change the user-interface for setting shares/weights.
++ *
++ * We increase resolution only if we have enough bits to allow this increased
++ * resolution (i.e. 64-bit). The costs for increasing resolution when 32-bit
++ * are pretty high and the returns do not justify the increased costs.
++ *
++ * Really only required when CONFIG_FAIR_GROUP_SCHED=y is also set, but to
++ * increase coverage and consistency always enable it on 64-bit platforms.
++ */
++#ifdef CONFIG_64BIT
++# define NICE_0_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT + SCHED_FIXEDPOINT_SHIFT)
++# define scale_load(w) ((w) << SCHED_FIXEDPOINT_SHIFT)
++# define scale_load_down(w) \
++({ \
++ unsigned long __w = (w); \
++ if (__w) \
++ __w = max(2UL, __w >> SCHED_FIXEDPOINT_SHIFT); \
++ __w; \
++})
++#else
++# define NICE_0_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT)
++# define scale_load(w) (w)
++# define scale_load_down(w) (w)
++#endif
++
++#ifdef CONFIG_FAIR_GROUP_SCHED
++#define ROOT_TASK_GROUP_LOAD NICE_0_LOAD
++
++/*
++ * A weight of 0 or 1 can cause arithmetics problems.
++ * A weight of a cfs_rq is the sum of weights of which entities
++ * are queued on this cfs_rq, so a weight of a entity should not be
++ * too large, so as the shares value of a task group.
++ * (The default weight is 1024 - so there's no practical
++ * limitation from this.)
++ */
++#define MIN_SHARES (1UL << 1)
++#define MAX_SHARES (1UL << 18)
++#endif
++
++/* task_struct::on_rq states: */
++#define TASK_ON_RQ_QUEUED 1
++#define TASK_ON_RQ_MIGRATING 2
++
++static inline int task_on_rq_queued(struct task_struct *p)
++{
++ return p->on_rq == TASK_ON_RQ_QUEUED;
++}
++
++static inline int task_on_rq_migrating(struct task_struct *p)
++{
++ return READ_ONCE(p->on_rq) == TASK_ON_RQ_MIGRATING;
++}
++
++/*
++ * wake flags
++ */
++#define WF_SYNC 0x01 /* waker goes to sleep after wakeup */
++#define WF_FORK 0x02 /* child wakeup after fork */
++#define WF_MIGRATED 0x04 /* internal use, task got migrated */
++
++#define SCHED_QUEUE_BITS (SCHED_BITS - 1)
++
++struct sched_queue {
++ DECLARE_BITMAP(bitmap, SCHED_QUEUE_BITS);
++ struct list_head heads[SCHED_BITS];
++};
++
++/*
++ * This is the main, per-CPU runqueue data structure.
++ * This data should only be modified by the local cpu.
++ */
++struct rq {
++ /* runqueue lock: */
++ raw_spinlock_t lock;
++
++ struct task_struct __rcu *curr;
++ struct task_struct *idle, *stop, *skip;
++ struct mm_struct *prev_mm;
++
++ struct sched_queue queue;
++#ifdef CONFIG_SCHED_PDS
++ u64 time_edge;
++#endif
++ unsigned long watermark;
++
++ /* switch count */
++ u64 nr_switches;
++
++ atomic_t nr_iowait;
++
++#ifdef CONFIG_SCHED_DEBUG
++ u64 last_seen_need_resched_ns;
++ int ticks_without_resched;
++#endif
++
++#ifdef CONFIG_MEMBARRIER
++ int membarrier_state;
++#endif
++
++#ifdef CONFIG_SMP
++ int cpu; /* cpu of this runqueue */
++ bool online;
++
++ unsigned int ttwu_pending;
++ unsigned char nohz_idle_balance;
++ unsigned char idle_balance;
++
++#ifdef CONFIG_HAVE_SCHED_AVG_IRQ
++ struct sched_avg avg_irq;
++#endif
++
++#ifdef CONFIG_SCHED_SMT
++ int active_balance;
++ struct cpu_stop_work active_balance_work;
++#endif
++ struct callback_head *balance_callback;
++#ifdef CONFIG_HOTPLUG_CPU
++ struct rcuwait hotplug_wait;
++#endif
++ unsigned int nr_pinned;
++
++#endif /* CONFIG_SMP */
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++ u64 prev_irq_time;
++#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
++#ifdef CONFIG_PARAVIRT
++ u64 prev_steal_time;
++#endif /* CONFIG_PARAVIRT */
++#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
++ u64 prev_steal_time_rq;
++#endif /* CONFIG_PARAVIRT_TIME_ACCOUNTING */
++
++ /* For genenal cpu load util */
++ s32 load_history;
++ u64 load_block;
++ u64 load_stamp;
++
++ /* calc_load related fields */
++ unsigned long calc_load_update;
++ long calc_load_active;
++
++ u64 clock, last_tick;
++ u64 last_ts_switch;
++ u64 clock_task;
++
++ unsigned int nr_running;
++ unsigned long nr_uninterruptible;
++
++#ifdef CONFIG_SCHED_HRTICK
++#ifdef CONFIG_SMP
++ call_single_data_t hrtick_csd;
++#endif
++ struct hrtimer hrtick_timer;
++ ktime_t hrtick_time;
++#endif
++
++#ifdef CONFIG_SCHEDSTATS
++
++ /* latency stats */
++ struct sched_info rq_sched_info;
++ unsigned long long rq_cpu_time;
++ /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */
++
++ /* sys_sched_yield() stats */
++ unsigned int yld_count;
++
++ /* schedule() stats */
++ unsigned int sched_switch;
++ unsigned int sched_count;
++ unsigned int sched_goidle;
++
++ /* try_to_wake_up() stats */
++ unsigned int ttwu_count;
++ unsigned int ttwu_local;
++#endif /* CONFIG_SCHEDSTATS */
++
++#ifdef CONFIG_CPU_IDLE
++ /* Must be inspected within a rcu lock section */
++ struct cpuidle_state *idle_state;
++#endif
++
++#ifdef CONFIG_NO_HZ_COMMON
++#ifdef CONFIG_SMP
++ call_single_data_t nohz_csd;
++#endif
++ atomic_t nohz_flags;
++#endif /* CONFIG_NO_HZ_COMMON */
++};
++
++extern unsigned long rq_load_util(int cpu);
++
++extern unsigned long calc_load_update;
++extern atomic_long_t calc_load_tasks;
++
++extern void calc_global_load_tick(struct rq *this_rq);
++extern long calc_load_fold_active(struct rq *this_rq, long adjust);
++
++DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
++#define this_rq() this_cpu_ptr(&runqueues)
++#define task_rq(p) cpu_rq(task_cpu(p))
++#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
++#define raw_rq() raw_cpu_ptr(&runqueues)
++
++#ifdef CONFIG_SMP
++#if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
++void register_sched_domain_sysctl(void);
++void unregister_sched_domain_sysctl(void);
++#else
++static inline void register_sched_domain_sysctl(void)
++{
++}
++static inline void unregister_sched_domain_sysctl(void)
++{
++}
++#endif
++
++extern bool sched_smp_initialized;
++
++enum {
++ ITSELF_LEVEL_SPACE_HOLDER,
++#ifdef CONFIG_SCHED_SMT
++ SMT_LEVEL_SPACE_HOLDER,
++#endif
++ COREGROUP_LEVEL_SPACE_HOLDER,
++ CORE_LEVEL_SPACE_HOLDER,
++ OTHER_LEVEL_SPACE_HOLDER,
++ NR_CPU_AFFINITY_LEVELS
++};
++
++DECLARE_PER_CPU(cpumask_t [NR_CPU_AFFINITY_LEVELS], sched_cpu_topo_masks);
++DECLARE_PER_CPU(cpumask_t *, sched_cpu_llc_mask);
++
++static inline int
++__best_mask_cpu(const cpumask_t *cpumask, const cpumask_t *mask)
++{
++ int cpu;
++
++ while ((cpu = cpumask_any_and(cpumask, mask)) >= nr_cpu_ids)
++ mask++;
++
++ return cpu;
++}
++
++static inline int best_mask_cpu(int cpu, const cpumask_t *mask)
++{
++ return __best_mask_cpu(mask, per_cpu(sched_cpu_topo_masks, cpu));
++}
++
++extern void flush_smp_call_function_queue(void);
++
++#else /* !CONFIG_SMP */
++static inline void flush_smp_call_function_queue(void) { }
++#endif
++
++#ifndef arch_scale_freq_tick
++static __always_inline
++void arch_scale_freq_tick(void)
++{
++}
++#endif
++
++#ifndef arch_scale_freq_capacity
++static __always_inline
++unsigned long arch_scale_freq_capacity(int cpu)
++{
++ return SCHED_CAPACITY_SCALE;
++}
++#endif
++
++static inline u64 __rq_clock_broken(struct rq *rq)
++{
++ return READ_ONCE(rq->clock);
++}
++
++static inline u64 rq_clock(struct rq *rq)
++{
++ /*
++ * Relax lockdep_assert_held() checking as in VRQ, call to
++ * sched_info_xxxx() may not held rq->lock
++ * lockdep_assert_held(&rq->lock);
++ */
++ return rq->clock;
++}
++
++static inline u64 rq_clock_task(struct rq *rq)
++{
++ /*
++ * Relax lockdep_assert_held() checking as in VRQ, call to
++ * sched_info_xxxx() may not held rq->lock
++ * lockdep_assert_held(&rq->lock);
++ */
++ return rq->clock_task;
++}
++
++/*
++ * {de,en}queue flags:
++ *
++ * DEQUEUE_SLEEP - task is no longer runnable
++ * ENQUEUE_WAKEUP - task just became runnable
++ *
++ */
++
++#define DEQUEUE_SLEEP 0x01
++
++#define ENQUEUE_WAKEUP 0x01
++
++
++/*
++ * Below are scheduler API which using in other kernel code
++ * It use the dummy rq_flags
++ * ToDo : BMQ need to support these APIs for compatibility with mainline
++ * scheduler code.
++ */
++struct rq_flags {
++ unsigned long flags;
++};
++
++struct rq *__task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++ __acquires(rq->lock);
++
++struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++ __acquires(p->pi_lock)
++ __acquires(rq->lock);
++
++static inline void __task_rq_unlock(struct rq *rq, struct rq_flags *rf)
++ __releases(rq->lock)
++{
++ raw_spin_unlock(&rq->lock);
++}
++
++static inline void
++task_rq_unlock(struct rq *rq, struct task_struct *p, struct rq_flags *rf)
++ __releases(rq->lock)
++ __releases(p->pi_lock)
++{
++ raw_spin_unlock(&rq->lock);
++ raw_spin_unlock_irqrestore(&p->pi_lock, rf->flags);
++}
++
++static inline void
++rq_lock(struct rq *rq, struct rq_flags *rf)
++ __acquires(rq->lock)
++{
++ raw_spin_lock(&rq->lock);
++}
++
++static inline void
++rq_unlock_irq(struct rq *rq, struct rq_flags *rf)
++ __releases(rq->lock)
++{
++ raw_spin_unlock_irq(&rq->lock);
++}
++
++static inline void
++rq_unlock(struct rq *rq, struct rq_flags *rf)
++ __releases(rq->lock)
++{
++ raw_spin_unlock(&rq->lock);
++}
++
++static inline struct rq *
++this_rq_lock_irq(struct rq_flags *rf)
++ __acquires(rq->lock)
++{
++ struct rq *rq;
++
++ local_irq_disable();
++ rq = this_rq();
++ raw_spin_lock(&rq->lock);
++
++ return rq;
++}
++
++static inline raw_spinlock_t *__rq_lockp(struct rq *rq)
++{
++ return &rq->lock;
++}
++
++static inline raw_spinlock_t *rq_lockp(struct rq *rq)
++{
++ return __rq_lockp(rq);
++}
++
++static inline void lockdep_assert_rq_held(struct rq *rq)
++{
++ lockdep_assert_held(__rq_lockp(rq));
++}
++
++extern void raw_spin_rq_lock_nested(struct rq *rq, int subclass);
++extern void raw_spin_rq_unlock(struct rq *rq);
++
++static inline void raw_spin_rq_lock(struct rq *rq)
++{
++ raw_spin_rq_lock_nested(rq, 0);
++}
++
++static inline void raw_spin_rq_lock_irq(struct rq *rq)
++{
++ local_irq_disable();
++ raw_spin_rq_lock(rq);
++}
++
++static inline void raw_spin_rq_unlock_irq(struct rq *rq)
++{
++ raw_spin_rq_unlock(rq);
++ local_irq_enable();
++}
++
++static inline int task_current(struct rq *rq, struct task_struct *p)
++{
++ return rq->curr == p;
++}
++
++static inline bool task_running(struct task_struct *p)
++{
++ return p->on_cpu;
++}
++
++extern int task_running_nice(struct task_struct *p);
++
++extern struct static_key_false sched_schedstats;
++
++#ifdef CONFIG_CPU_IDLE
++static inline void idle_set_state(struct rq *rq,
++ struct cpuidle_state *idle_state)
++{
++ rq->idle_state = idle_state;
++}
++
++static inline struct cpuidle_state *idle_get_state(struct rq *rq)
++{
++ WARN_ON(!rcu_read_lock_held());
++ return rq->idle_state;
++}
++#else
++static inline void idle_set_state(struct rq *rq,
++ struct cpuidle_state *idle_state)
++{
++}
++
++static inline struct cpuidle_state *idle_get_state(struct rq *rq)
++{
++ return NULL;
++}
++#endif
++
++static inline int cpu_of(const struct rq *rq)
++{
++#ifdef CONFIG_SMP
++ return rq->cpu;
++#else
++ return 0;
++#endif
++}
++
++#include "stats.h"
++
++#ifdef CONFIG_NO_HZ_COMMON
++#define NOHZ_BALANCE_KICK_BIT 0
++#define NOHZ_STATS_KICK_BIT 1
++
++#define NOHZ_BALANCE_KICK BIT(NOHZ_BALANCE_KICK_BIT)
++#define NOHZ_STATS_KICK BIT(NOHZ_STATS_KICK_BIT)
++
++#define NOHZ_KICK_MASK (NOHZ_BALANCE_KICK | NOHZ_STATS_KICK)
++
++#define nohz_flags(cpu) (&cpu_rq(cpu)->nohz_flags)
++
++/* TODO: needed?
++extern void nohz_balance_exit_idle(struct rq *rq);
++#else
++static inline void nohz_balance_exit_idle(struct rq *rq) { }
++*/
++#endif
++
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++struct irqtime {
++ u64 total;
++ u64 tick_delta;
++ u64 irq_start_time;
++ struct u64_stats_sync sync;
++};
++
++DECLARE_PER_CPU(struct irqtime, cpu_irqtime);
++
++/*
++ * Returns the irqtime minus the softirq time computed by ksoftirqd.
++ * Otherwise ksoftirqd's sum_exec_runtime is substracted its own runtime
++ * and never move forward.
++ */
++static inline u64 irq_time_read(int cpu)
++{
++ struct irqtime *irqtime = &per_cpu(cpu_irqtime, cpu);
++ unsigned int seq;
++ u64 total;
++
++ do {
++ seq = __u64_stats_fetch_begin(&irqtime->sync);
++ total = irqtime->total;
++ } while (__u64_stats_fetch_retry(&irqtime->sync, seq));
++
++ return total;
++}
++#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
++
++#ifdef CONFIG_CPU_FREQ
++DECLARE_PER_CPU(struct update_util_data __rcu *, cpufreq_update_util_data);
++#endif /* CONFIG_CPU_FREQ */
++
++#ifdef CONFIG_NO_HZ_FULL
++extern int __init sched_tick_offload_init(void);
++#else
++static inline int sched_tick_offload_init(void) { return 0; }
++#endif
++
++#ifdef arch_scale_freq_capacity
++#ifndef arch_scale_freq_invariant
++#define arch_scale_freq_invariant() (true)
++#endif
++#else /* arch_scale_freq_capacity */
++#define arch_scale_freq_invariant() (false)
++#endif
++
++extern void schedule_idle(void);
++
++#define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT)
++
++/*
++ * !! For sched_setattr_nocheck() (kernel) only !!
++ *
++ * This is actually gross. :(
++ *
++ * It is used to make schedutil kworker(s) higher priority than SCHED_DEADLINE
++ * tasks, but still be able to sleep. We need this on platforms that cannot
++ * atomically change clock frequency. Remove once fast switching will be
++ * available on such platforms.
++ *
++ * SUGOV stands for SchedUtil GOVernor.
++ */
++#define SCHED_FLAG_SUGOV 0x10000000
++
++#ifdef CONFIG_MEMBARRIER
++/*
++ * The scheduler provides memory barriers required by membarrier between:
++ * - prior user-space memory accesses and store to rq->membarrier_state,
++ * - store to rq->membarrier_state and following user-space memory accesses.
++ * In the same way it provides those guarantees around store to rq->curr.
++ */
++static inline void membarrier_switch_mm(struct rq *rq,
++ struct mm_struct *prev_mm,
++ struct mm_struct *next_mm)
++{
++ int membarrier_state;
++
++ if (prev_mm == next_mm)
++ return;
++
++ membarrier_state = atomic_read(&next_mm->membarrier_state);
++ if (READ_ONCE(rq->membarrier_state) == membarrier_state)
++ return;
++
++ WRITE_ONCE(rq->membarrier_state, membarrier_state);
++}
++#else
++static inline void membarrier_switch_mm(struct rq *rq,
++ struct mm_struct *prev_mm,
++ struct mm_struct *next_mm)
++{
++}
++#endif
++
++#ifdef CONFIG_NUMA
++extern int sched_numa_find_closest(const struct cpumask *cpus, int cpu);
++#else
++static inline int sched_numa_find_closest(const struct cpumask *cpus, int cpu)
++{
++ return nr_cpu_ids;
++}
++#endif
++
++extern void swake_up_all_locked(struct swait_queue_head *q);
++extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++extern int preempt_dynamic_mode;
++extern int sched_dynamic_mode(const char *str);
++extern void sched_dynamic_update(int mode);
++#endif
++
++static inline void nohz_run_idle_balance(int cpu) { }
++
++static inline
++unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
++ struct task_struct *p)
++{
++ return util;
++}
++
++static inline bool uclamp_rq_is_capped(struct rq *rq) { return false; }
++
++#endif /* ALT_SCHED_H */
+diff --git a/kernel/sched/bmq.h b/kernel/sched/bmq.h
+new file mode 100644
+index 000000000000..66b77291b9d0
+--- /dev/null
++++ b/kernel/sched/bmq.h
+@@ -0,0 +1,110 @@
++#define ALT_SCHED_VERSION_MSG "sched/bmq: BMQ CPU Scheduler "ALT_SCHED_VERSION" by Alfred Chen.\n"
++
++/*
++ * BMQ only routines
++ */
++#define rq_switch_time(rq) ((rq)->clock - (rq)->last_ts_switch)
++#define boost_threshold(p) (sched_timeslice_ns >>\
++ (15 - MAX_PRIORITY_ADJ - (p)->boost_prio))
++
++static inline void boost_task(struct task_struct *p)
++{
++ int limit;
++
++ switch (p->policy) {
++ case SCHED_NORMAL:
++ limit = -MAX_PRIORITY_ADJ;
++ break;
++ case SCHED_BATCH:
++ case SCHED_IDLE:
++ limit = 0;
++ break;
++ default:
++ return;
++ }
++
++ if (p->boost_prio > limit)
++ p->boost_prio--;
++}
++
++static inline void deboost_task(struct task_struct *p)
++{
++ if (p->boost_prio < MAX_PRIORITY_ADJ)
++ p->boost_prio++;
++}
++
++/*
++ * Common interfaces
++ */
++static inline void sched_timeslice_imp(const int timeslice_ms) {}
++
++static inline int
++task_sched_prio_normal(const struct task_struct *p, const struct rq *rq)
++{
++ return p->prio + p->boost_prio - MAX_RT_PRIO;
++}
++
++static inline int task_sched_prio(const struct task_struct *p)
++{
++ return (p->prio < MAX_RT_PRIO)? p->prio : MAX_RT_PRIO / 2 + (p->prio + p->boost_prio) / 2;
++}
++
++static inline int
++task_sched_prio_idx(const struct task_struct *p, const struct rq *rq)
++{
++ return task_sched_prio(p);
++}
++
++static inline int sched_prio2idx(int prio, struct rq *rq)
++{
++ return prio;
++}
++
++static inline int sched_idx2prio(int idx, struct rq *rq)
++{
++ return idx;
++}
++
++static inline void time_slice_expired(struct task_struct *p, struct rq *rq)
++{
++ p->time_slice = sched_timeslice_ns;
++
++ if (SCHED_FIFO != p->policy && task_on_rq_queued(p)) {
++ if (SCHED_RR != p->policy)
++ deboost_task(p);
++ requeue_task(p, rq, task_sched_prio_idx(p, rq));
++ }
++}
++
++static inline void sched_task_sanity_check(struct task_struct *p, struct rq *rq) {}
++
++inline int task_running_nice(struct task_struct *p)
++{
++ return (p->prio + p->boost_prio > DEFAULT_PRIO + MAX_PRIORITY_ADJ);
++}
++
++static void sched_task_fork(struct task_struct *p, struct rq *rq)
++{
++ p->boost_prio = MAX_PRIORITY_ADJ;
++}
++
++static inline void do_sched_yield_type_1(struct task_struct *p, struct rq *rq)
++{
++ p->boost_prio = MAX_PRIORITY_ADJ;
++}
++
++#ifdef CONFIG_SMP
++static inline void sched_task_ttwu(struct task_struct *p)
++{
++ if(this_rq()->clock_task - p->last_ran > sched_timeslice_ns)
++ boost_task(p);
++}
++#endif
++
++static inline void sched_task_deactivate(struct task_struct *p, struct rq *rq)
++{
++ if (rq_switch_time(rq) < boost_threshold(p))
++ boost_task(p);
++}
++
++static inline void update_rq_time_edge(struct rq *rq) {}
+diff --git a/kernel/sched/build_policy.c b/kernel/sched/build_policy.c
+index d9dc9ab3773f..71a25540d65e 100644
+--- a/kernel/sched/build_policy.c
++++ b/kernel/sched/build_policy.c
+@@ -42,13 +42,19 @@
+
+ #include "idle.c"
+
++#ifndef CONFIG_SCHED_ALT
+ #include "rt.c"
++#endif
+
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ # include "cpudeadline.c"
++#endif
+ # include "pelt.c"
+ #endif
+
+ #include "cputime.c"
+-#include "deadline.c"
+
++#ifndef CONFIG_SCHED_ALT
++#include "deadline.c"
++#endif
+diff --git a/kernel/sched/build_utility.c b/kernel/sched/build_utility.c
+index 99bdd96f454f..23f80a86d2d7 100644
+--- a/kernel/sched/build_utility.c
++++ b/kernel/sched/build_utility.c
+@@ -85,7 +85,9 @@
+
+ #ifdef CONFIG_SMP
+ # include "cpupri.c"
++#ifndef CONFIG_SCHED_ALT
+ # include "stop_task.c"
++#endif
+ # include "topology.c"
+ #endif
+
+diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
+index 1207c78f85c1..3ed06d7ef4f8 100644
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -159,9 +159,14 @@ static void sugov_get_util(struct sugov_cpu *sg_cpu)
+ struct rq *rq = cpu_rq(sg_cpu->cpu);
+
+ sg_cpu->max = arch_scale_cpu_capacity(sg_cpu->cpu);
++#ifndef CONFIG_SCHED_ALT
+ sg_cpu->bw_dl = cpu_bw_dl(rq);
+ sg_cpu->util = effective_cpu_util(sg_cpu->cpu, cpu_util_cfs(sg_cpu->cpu),
+ FREQUENCY_UTIL, NULL);
++#else
++ sg_cpu->bw_dl = 0;
++ sg_cpu->util = rq_load_util(cpu_of(rq));
++#endif /* CONFIG_SCHED_ALT */
+ }
+
+ /**
+@@ -305,8 +310,10 @@ static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; }
+ */
+ static inline void ignore_dl_rate_limit(struct sugov_cpu *sg_cpu)
+ {
++#ifndef CONFIG_SCHED_ALT
+ if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_dl)
+ sg_cpu->sg_policy->limits_changed = true;
++#endif
+ }
+
+ static inline bool sugov_update_single_common(struct sugov_cpu *sg_cpu,
+@@ -606,6 +613,7 @@ static int sugov_kthread_create(struct sugov_policy *sg_policy)
+ }
+
+ ret = sched_setattr_nocheck(thread, &attr);
++
+ if (ret) {
+ kthread_stop(thread);
+ pr_warn("%s: failed to set SCHED_DEADLINE\n", __func__);
+@@ -838,7 +846,9 @@ cpufreq_governor_init(schedutil_gov);
+ #ifdef CONFIG_ENERGY_MODEL
+ static void rebuild_sd_workfn(struct work_struct *work)
+ {
++#ifndef CONFIG_SCHED_ALT
+ rebuild_sched_domains_energy();
++#endif /* CONFIG_SCHED_ALT */
+ }
+ static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
+
+diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
+index 95fc77853743..b48b3f9ed47f 100644
+--- a/kernel/sched/cputime.c
++++ b/kernel/sched/cputime.c
+@@ -122,7 +122,7 @@ void account_user_time(struct task_struct *p, u64 cputime)
+ p->utime += cputime;
+ account_group_user_time(p, cputime);
+
+- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
++ index = task_running_nice(p) ? CPUTIME_NICE : CPUTIME_USER;
+
+ /* Add user time to cpustat. */
+ task_group_account_field(p, index, cputime);
+@@ -146,7 +146,7 @@ void account_guest_time(struct task_struct *p, u64 cputime)
+ p->gtime += cputime;
+
+ /* Add guest time to cpustat. */
+- if (task_nice(p) > 0) {
++ if (task_running_nice(p)) {
+ task_group_account_field(p, CPUTIME_NICE, cputime);
+ cpustat[CPUTIME_GUEST_NICE] += cputime;
+ } else {
+@@ -284,7 +284,7 @@ static inline u64 account_other_time(u64 max)
+ #ifdef CONFIG_64BIT
+ static inline u64 read_sum_exec_runtime(struct task_struct *t)
+ {
+- return t->se.sum_exec_runtime;
++ return tsk_seruntime(t);
+ }
+ #else
+ static u64 read_sum_exec_runtime(struct task_struct *t)
+@@ -294,7 +294,7 @@ static u64 read_sum_exec_runtime(struct task_struct *t)
+ struct rq *rq;
+
+ rq = task_rq_lock(t, &rf);
+- ns = t->se.sum_exec_runtime;
++ ns = tsk_seruntime(t);
+ task_rq_unlock(rq, t, &rf);
+
+ return ns;
+@@ -626,7 +626,7 @@ void cputime_adjust(struct task_cputime *curr, struct prev_cputime *prev,
+ void task_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st)
+ {
+ struct task_cputime cputime = {
+- .sum_exec_runtime = p->se.sum_exec_runtime,
++ .sum_exec_runtime = tsk_seruntime(p),
+ };
+
+ if (task_cputime(p, &cputime.utime, &cputime.stime))
+diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
+index 667876da8382..a416d4bedd98 100644
+--- a/kernel/sched/debug.c
++++ b/kernel/sched/debug.c
+@@ -7,6 +7,7 @@
+ * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar
+ */
+
++#ifndef CONFIG_SCHED_ALT
+ /*
+ * This allows printing both to /proc/sched_debug and
+ * to the console
+@@ -215,6 +216,7 @@ static const struct file_operations sched_scaling_fops = {
+ };
+
+ #endif /* SMP */
++#endif /* !CONFIG_SCHED_ALT */
+
+ #ifdef CONFIG_PREEMPT_DYNAMIC
+
+@@ -278,6 +280,7 @@ static const struct file_operations sched_dynamic_fops = {
+
+ #endif /* CONFIG_PREEMPT_DYNAMIC */
+
++#ifndef CONFIG_SCHED_ALT
+ __read_mostly bool sched_debug_verbose;
+
+ static const struct seq_operations sched_debug_sops;
+@@ -293,6 +296,7 @@ static const struct file_operations sched_debug_fops = {
+ .llseek = seq_lseek,
+ .release = seq_release,
+ };
++#endif /* !CONFIG_SCHED_ALT */
+
+ static struct dentry *debugfs_sched;
+
+@@ -302,12 +306,15 @@ static __init int sched_init_debug(void)
+
+ debugfs_sched = debugfs_create_dir("sched", NULL);
+
++#ifndef CONFIG_SCHED_ALT
+ debugfs_create_file("features", 0644, debugfs_sched, NULL, &sched_feat_fops);
+ debugfs_create_bool("verbose", 0644, debugfs_sched, &sched_debug_verbose);
++#endif /* !CONFIG_SCHED_ALT */
+ #ifdef CONFIG_PREEMPT_DYNAMIC
+ debugfs_create_file("preempt", 0644, debugfs_sched, NULL, &sched_dynamic_fops);
+ #endif
+
++#ifndef CONFIG_SCHED_ALT
+ debugfs_create_u32("latency_ns", 0644, debugfs_sched, &sysctl_sched_latency);
+ debugfs_create_u32("min_granularity_ns", 0644, debugfs_sched, &sysctl_sched_min_granularity);
+ debugfs_create_u32("idle_min_granularity_ns", 0644, debugfs_sched, &sysctl_sched_idle_min_granularity);
+@@ -336,11 +343,13 @@ static __init int sched_init_debug(void)
+ #endif
+
+ debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);
++#endif /* !CONFIG_SCHED_ALT */
+
+ return 0;
+ }
+ late_initcall(sched_init_debug);
+
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_SMP
+
+ static cpumask_var_t sd_sysctl_cpus;
+@@ -1067,6 +1076,7 @@ void proc_sched_set_task(struct task_struct *p)
+ memset(&p->stats, 0, sizeof(p->stats));
+ #endif
+ }
++#endif /* !CONFIG_SCHED_ALT */
+
+ void resched_latency_warn(int cpu, u64 latency)
+ {
+diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
+index f26ab2675f7d..480d4ad16d45 100644
+--- a/kernel/sched/idle.c
++++ b/kernel/sched/idle.c
+@@ -400,6 +400,7 @@ void cpu_startup_entry(enum cpuhp_state state)
+ do_idle();
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ /*
+ * idle-task scheduling class.
+ */
+@@ -521,3 +522,4 @@ DEFINE_SCHED_CLASS(idle) = {
+ .switched_to = switched_to_idle,
+ .update_curr = update_curr_idle,
+ };
++#endif
+diff --git a/kernel/sched/pds.h b/kernel/sched/pds.h
+new file mode 100644
+index 000000000000..56a649d02e49
+--- /dev/null
++++ b/kernel/sched/pds.h
+@@ -0,0 +1,127 @@
++#define ALT_SCHED_VERSION_MSG "sched/pds: PDS CPU Scheduler "ALT_SCHED_VERSION" by Alfred Chen.\n"
++
++static int sched_timeslice_shift = 22;
++
++#define NORMAL_PRIO_MOD(x) ((x) & (NORMAL_PRIO_NUM - 1))
++
++/*
++ * Common interfaces
++ */
++static inline void sched_timeslice_imp(const int timeslice_ms)
++{
++ if (2 == timeslice_ms)
++ sched_timeslice_shift = 21;
++}
++
++static inline int
++task_sched_prio_normal(const struct task_struct *p, const struct rq *rq)
++{
++ s64 delta = p->deadline - rq->time_edge + NORMAL_PRIO_NUM - NICE_WIDTH;
++
++ if (WARN_ONCE(delta > NORMAL_PRIO_NUM - 1,
++ "pds: task_sched_prio_normal() delta %lld\n", delta))
++ return NORMAL_PRIO_NUM - 1;
++
++ return (delta < 0) ? 0 : delta;
++}
++
++static inline int task_sched_prio(const struct task_struct *p)
++{
++ return (p->prio < MAX_RT_PRIO) ? p->prio :
++ MIN_NORMAL_PRIO + task_sched_prio_normal(p, task_rq(p));
++}
++
++static inline int
++task_sched_prio_idx(const struct task_struct *p, const struct rq *rq)
++{
++ return (p->prio < MAX_RT_PRIO) ? p->prio : MIN_NORMAL_PRIO +
++ NORMAL_PRIO_MOD(task_sched_prio_normal(p, rq) + rq->time_edge);
++}
++
++static inline int sched_prio2idx(int prio, struct rq *rq)
++{
++ return (IDLE_TASK_SCHED_PRIO == prio || prio < MAX_RT_PRIO) ? prio :
++ MIN_NORMAL_PRIO + NORMAL_PRIO_MOD((prio - MIN_NORMAL_PRIO) +
++ rq->time_edge);
++}
++
++static inline int sched_idx2prio(int idx, struct rq *rq)
++{
++ return (idx < MAX_RT_PRIO) ? idx : MIN_NORMAL_PRIO +
++ NORMAL_PRIO_MOD((idx - MIN_NORMAL_PRIO) + NORMAL_PRIO_NUM -
++ NORMAL_PRIO_MOD(rq->time_edge));
++}
++
++static inline void sched_renew_deadline(struct task_struct *p, const struct rq *rq)
++{
++ if (p->prio >= MAX_RT_PRIO)
++ p->deadline = (rq->clock >> sched_timeslice_shift) +
++ p->static_prio - (MAX_PRIO - NICE_WIDTH);
++}
++
++int task_running_nice(struct task_struct *p)
++{
++ return (p->prio > DEFAULT_PRIO);
++}
++
++static inline void update_rq_time_edge(struct rq *rq)
++{
++ struct list_head head;
++ u64 old = rq->time_edge;
++ u64 now = rq->clock >> sched_timeslice_shift;
++ u64 prio, delta;
++
++ if (now == old)
++ return;
++
++ delta = min_t(u64, NORMAL_PRIO_NUM, now - old);
++ INIT_LIST_HEAD(&head);
++
++ for_each_set_bit(prio, &rq->queue.bitmap[2], delta)
++ list_splice_tail_init(rq->queue.heads + MIN_NORMAL_PRIO +
++ NORMAL_PRIO_MOD(prio + old), &head);
++
++ rq->queue.bitmap[2] = (NORMAL_PRIO_NUM == delta) ? 0UL :
++ rq->queue.bitmap[2] >> delta;
++ rq->time_edge = now;
++ if (!list_empty(&head)) {
++ u64 idx = MIN_NORMAL_PRIO + NORMAL_PRIO_MOD(now);
++ struct task_struct *p;
++
++ list_for_each_entry(p, &head, sq_node)
++ p->sq_idx = idx;
++
++ list_splice(&head, rq->queue.heads + idx);
++ rq->queue.bitmap[2] |= 1UL;
++ }
++}
++
++static inline void time_slice_expired(struct task_struct *p, struct rq *rq)
++{
++ p->time_slice = sched_timeslice_ns;
++ sched_renew_deadline(p, rq);
++ if (SCHED_FIFO != p->policy && task_on_rq_queued(p))
++ requeue_task(p, rq, task_sched_prio_idx(p, rq));
++}
++
++static inline void sched_task_sanity_check(struct task_struct *p, struct rq *rq)
++{
++ u64 max_dl = rq->time_edge + NICE_WIDTH - 1;
++ if (unlikely(p->deadline > max_dl))
++ p->deadline = max_dl;
++}
++
++static void sched_task_fork(struct task_struct *p, struct rq *rq)
++{
++ sched_renew_deadline(p, rq);
++}
++
++static inline void do_sched_yield_type_1(struct task_struct *p, struct rq *rq)
++{
++ time_slice_expired(p, rq);
++}
++
++#ifdef CONFIG_SMP
++static inline void sched_task_ttwu(struct task_struct *p) {}
++#endif
++static inline void sched_task_deactivate(struct task_struct *p, struct rq *rq) {}
+diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c
+index 0f310768260c..bd38bf738fe9 100644
+--- a/kernel/sched/pelt.c
++++ b/kernel/sched/pelt.c
+@@ -266,6 +266,7 @@ ___update_load_avg(struct sched_avg *sa, unsigned long load)
+ WRITE_ONCE(sa->util_avg, sa->util_sum / divider);
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ /*
+ * sched_entity:
+ *
+@@ -383,8 +384,9 @@ int update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
+
+ return 0;
+ }
++#endif
+
+-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
++#if defined(CONFIG_SCHED_THERMAL_PRESSURE) && !defined(CONFIG_SCHED_ALT)
+ /*
+ * thermal:
+ *
+diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h
+index 3a0e0dc28721..e8a7d84aa5a5 100644
+--- a/kernel/sched/pelt.h
++++ b/kernel/sched/pelt.h
+@@ -1,13 +1,15 @@
+ #ifdef CONFIG_SMP
+ #include "sched-pelt.h"
+
++#ifndef CONFIG_SCHED_ALT
+ int __update_load_avg_blocked_se(u64 now, struct sched_entity *se);
+ int __update_load_avg_se(u64 now, struct cfs_rq *cfs_rq, struct sched_entity *se);
+ int __update_load_avg_cfs_rq(u64 now, struct cfs_rq *cfs_rq);
+ int update_rt_rq_load_avg(u64 now, struct rq *rq, int running);
+ int update_dl_rq_load_avg(u64 now, struct rq *rq, int running);
++#endif
+
+-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
++#if defined(CONFIG_SCHED_THERMAL_PRESSURE) && !defined(CONFIG_SCHED_ALT)
+ int update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity);
+
+ static inline u64 thermal_load_avg(struct rq *rq)
+@@ -44,6 +46,7 @@ static inline u32 get_pelt_divider(struct sched_avg *avg)
+ return PELT_MIN_DIVIDER + avg->period_contrib;
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ static inline void cfs_se_util_change(struct sched_avg *avg)
+ {
+ unsigned int enqueued;
+@@ -180,9 +183,11 @@ static inline u64 cfs_rq_clock_pelt(struct cfs_rq *cfs_rq)
+ return rq_clock_pelt(rq_of(cfs_rq));
+ }
+ #endif
++#endif /* CONFIG_SCHED_ALT */
+
+ #else
+
++#ifndef CONFIG_SCHED_ALT
+ static inline int
+ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
+ {
+@@ -200,6 +205,7 @@ update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
+ {
+ return 0;
+ }
++#endif
+
+ static inline int
+ update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity)
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index e26688d387ae..48d5823f9d84 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -5,6 +5,10 @@
+ #ifndef _KERNEL_SCHED_SCHED_H
+ #define _KERNEL_SCHED_SCHED_H
+
++#ifdef CONFIG_SCHED_ALT
++#include "alt_sched.h"
++#else
++
+ #include <linux/sched/affinity.h>
+ #include <linux/sched/autogroup.h>
+ #include <linux/sched/cpufreq.h>
+@@ -3157,4 +3161,9 @@ extern int sched_dynamic_mode(const char *str);
+ extern void sched_dynamic_update(int mode);
+ #endif
+
++static inline int task_running_nice(struct task_struct *p)
++{
++ return (task_nice(p) > 0);
++}
++#endif /* !CONFIG_SCHED_ALT */
+ #endif /* _KERNEL_SCHED_SCHED_H */
+diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c
+index 857f837f52cb..5486c63e4790 100644
+--- a/kernel/sched/stats.c
++++ b/kernel/sched/stats.c
+@@ -125,8 +125,10 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ } else {
+ struct rq *rq;
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ struct sched_domain *sd;
+ int dcount = 0;
++#endif
+ #endif
+ cpu = (unsigned long)(v - 2);
+ rq = cpu_rq(cpu);
+@@ -143,6 +145,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ seq_printf(seq, "\n");
+
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ /* domain-specific stats */
+ rcu_read_lock();
+ for_each_domain(cpu, sd) {
+@@ -171,6 +174,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ sd->ttwu_move_balance);
+ }
+ rcu_read_unlock();
++#endif
+ #endif
+ }
+ return 0;
+diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
+index baa839c1ba96..15238be0581b 100644
+--- a/kernel/sched/stats.h
++++ b/kernel/sched/stats.h
+@@ -89,6 +89,7 @@ static inline void rq_sched_info_depart (struct rq *rq, unsigned long long delt
+
+ #endif /* CONFIG_SCHEDSTATS */
+
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_FAIR_GROUP_SCHED
+ struct sched_entity_stats {
+ struct sched_entity se;
+@@ -105,6 +106,7 @@ __schedstats_from_se(struct sched_entity *se)
+ #endif
+ return &task_of(se)->stats;
+ }
++#endif /* CONFIG_SCHED_ALT */
+
+ #ifdef CONFIG_PSI
+ /*
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 8739c2a5a54e..d8dd6c15eb47 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -3,6 +3,7 @@
+ * Scheduler topology setup/handling methods
+ */
+
++#ifndef CONFIG_SCHED_ALT
+ DEFINE_MUTEX(sched_domains_mutex);
+
+ /* Protected by sched_domains_mutex: */
+@@ -1413,8 +1414,10 @@ static void asym_cpu_capacity_scan(void)
+ */
+
+ static int default_relax_domain_level = -1;
++#endif /* CONFIG_SCHED_ALT */
+ int sched_domain_level_max;
+
++#ifndef CONFIG_SCHED_ALT
+ static int __init setup_relax_domain_level(char *str)
+ {
+ if (kstrtoint(str, 0, &default_relax_domain_level))
+@@ -1647,6 +1650,7 @@ sd_init(struct sched_domain_topology_level *tl,
+
+ return sd;
+ }
++#endif /* CONFIG_SCHED_ALT */
+
+ /*
+ * Topology list, bottom-up.
+@@ -1683,6 +1687,7 @@ void set_sched_topology(struct sched_domain_topology_level *tl)
+ sched_domain_topology_saved = NULL;
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_NUMA
+
+ static const struct cpumask *sd_numa_mask(int cpu)
+@@ -2645,3 +2650,15 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
+ partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
+ mutex_unlock(&sched_domains_mutex);
+ }
++#else /* CONFIG_SCHED_ALT */
++void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
++ struct sched_domain_attr *dattr_new)
++{}
++
++#ifdef CONFIG_NUMA
++int sched_numa_find_closest(const struct cpumask *cpus, int cpu)
++{
++ return best_mask_cpu(cpu, cpus);
++}
++#endif /* CONFIG_NUMA */
++#endif
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 205d605cacc5..7dd950601cca 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -86,6 +86,10 @@
+
+ /* Constants used for minimum and maximum */
+
++#ifdef CONFIG_SCHED_ALT
++extern int sched_yield_type;
++#endif
++
+ #ifdef CONFIG_PERF_EVENTS
+ static const int six_hundred_forty_kb = 640 * 1024;
+ #endif
+@@ -1631,6 +1635,7 @@ int proc_do_static_key(struct ctl_table *table, int write,
+ }
+
+ static struct ctl_table kern_table[] = {
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_NUMA_BALANCING
+ {
+ .procname = "numa_balancing",
+@@ -1642,6 +1647,7 @@ static struct ctl_table kern_table[] = {
+ .extra2 = SYSCTL_FOUR,
+ },
+ #endif /* CONFIG_NUMA_BALANCING */
++#endif /* !CONFIG_SCHED_ALT */
+ {
+ .procname = "panic",
+ .data = &panic_timeout,
+@@ -1943,6 +1949,17 @@ static struct ctl_table kern_table[] = {
+ .proc_handler = proc_dointvec,
+ },
+ #endif
++#ifdef CONFIG_SCHED_ALT
++ {
++ .procname = "yield_type",
++ .data = &sched_yield_type,
++ .maxlen = sizeof (int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_TWO,
++ },
++#endif
+ #if defined(CONFIG_S390) && defined(CONFIG_SMP)
+ {
+ .procname = "spin_retry",
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 23af5eca11b1..792f94ce4d80 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2088,8 +2088,10 @@ long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
+ int ret = 0;
+ u64 slack;
+
++#ifndef CONFIG_SCHED_ALT
+ slack = current->timer_slack_ns;
+ if (dl_task(current) || rt_task(current))
++#endif
+ slack = 0;
+
+ hrtimer_init_sleeper_on_stack(&t, clockid, mode);
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index cb925e8ef9a8..67d823510f5c 100644
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -223,7 +223,7 @@ static void task_sample_cputime(struct task_struct *p, u64 *samples)
+ u64 stime, utime;
+
+ task_cputime(p, &utime, &stime);
+- store_samples(samples, stime, utime, p->se.sum_exec_runtime);
++ store_samples(samples, stime, utime, tsk_seruntime(p));
+ }
+
+ static void proc_sample_cputime_atomic(struct task_cputime_atomic *at,
+@@ -866,6 +866,7 @@ static void collect_posix_cputimers(struct posix_cputimers *pct, u64 *samples,
+ }
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ static inline void check_dl_overrun(struct task_struct *tsk)
+ {
+ if (tsk->dl.dl_overrun) {
+@@ -873,6 +874,7 @@ static inline void check_dl_overrun(struct task_struct *tsk)
+ send_signal_locked(SIGXCPU, SEND_SIG_PRIV, tsk, PIDTYPE_TGID);
+ }
+ }
++#endif
+
+ static bool check_rlimit(u64 time, u64 limit, int signo, bool rt, bool hard)
+ {
+@@ -900,8 +902,10 @@ static void check_thread_timers(struct task_struct *tsk,
+ u64 samples[CPUCLOCK_MAX];
+ unsigned long soft;
+
++#ifndef CONFIG_SCHED_ALT
+ if (dl_task(tsk))
+ check_dl_overrun(tsk);
++#endif
+
+ if (expiry_cache_is_inactive(pct))
+ return;
+@@ -915,7 +919,7 @@ static void check_thread_timers(struct task_struct *tsk,
+ soft = task_rlimit(tsk, RLIMIT_RTTIME);
+ if (soft != RLIM_INFINITY) {
+ /* Task RT timeout is accounted in jiffies. RTTIME is usec */
+- unsigned long rttime = tsk->rt.timeout * (USEC_PER_SEC / HZ);
++ unsigned long rttime = tsk_rttimeout(tsk) * (USEC_PER_SEC / HZ);
+ unsigned long hard = task_rlimit_max(tsk, RLIMIT_RTTIME);
+
+ /* At the hard limit, send SIGKILL. No further action. */
+@@ -1151,8 +1155,10 @@ static inline bool fastpath_timer_check(struct task_struct *tsk)
+ return true;
+ }
+
++#ifndef CONFIG_SCHED_ALT
+ if (dl_task(tsk) && tsk->dl.dl_overrun)
+ return true;
++#endif
+
+ return false;
+ }
+diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
+index a2d301f58ced..2ccdede8585c 100644
+--- a/kernel/trace/trace_selftest.c
++++ b/kernel/trace/trace_selftest.c
+@@ -1143,10 +1143,15 @@ static int trace_wakeup_test_thread(void *data)
+ {
+ /* Make this a -deadline thread */
+ static const struct sched_attr attr = {
++#ifdef CONFIG_SCHED_ALT
++ /* No deadline on BMQ/PDS, use RR */
++ .sched_policy = SCHED_RR,
++#else
+ .sched_policy = SCHED_DEADLINE,
+ .sched_runtime = 100000ULL,
+ .sched_deadline = 10000000ULL,
+ .sched_period = 10000000ULL
++#endif
+ };
+ struct wakeup_test_data *x = data;
+
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-06 13:46 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-06 13:46 UTC (permalink / raw
To: gentoo-commits
commit: e01b6489b92edbd322b294a32911346fdac2cc27
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 6 13:45:18 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Dec 6 13:45:18 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e01b6489
netfilter: ctnetlink fix compl. warning after data race fixes in ct mark
Bug: https://bugs.gentoo.org/884585
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 ++
2010_netfilter-ctnetlink-compilation-fix.patch | 90 ++++++++++++++++++++++++++
2 files changed, 94 insertions(+)
diff --git a/0000_README b/0000_README
index 5f75f686..52214e7a 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
+Patch: 2010_netfilter-ctnetlink-compilation-fix.patch
+From: https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
+Desc: netfilter: ctnetlink: fix compilation warning after data race fixes in ct mark
+
Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
From: https://bugs.gentoo.org/710790
Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
diff --git a/2010_netfilter-ctnetlink-compilation-fix.patch b/2010_netfilter-ctnetlink-compilation-fix.patch
new file mode 100644
index 00000000..b7bd4dee
--- /dev/null
+++ b/2010_netfilter-ctnetlink-compilation-fix.patch
@@ -0,0 +1,90 @@
+From 1feeae071507ad65cf9f462a1bdd543a4bf89e71 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Mon, 28 Nov 2022 10:58:53 +0100
+Subject: netfilter: ctnetlink: fix compilation warning after data race fixes
+ in ct mark
+
+All warnings (new ones prefixed by >>):
+
+ net/netfilter/nf_conntrack_netlink.c: In function '__ctnetlink_glue_build':
+>> net/netfilter/nf_conntrack_netlink.c:2674:13: warning: unused variable 'mark' [-Wunused-variable]
+ 2674 | u32 mark;
+ | ^~~~
+
+Fixes: 52d1aa8b8249 ("netfilter: conntrack: Fix data-races around ct mark")
+Reported-by: kernel test robot <lkp@intel.com>
+Tested-by: Ivan Babrou <ivan@ivan.computer>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/nf_conntrack_netlink.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d71150a40fb08..1286ae7d46096 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,8 +328,13 @@ nla_put_failure:
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
++static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+ {
++ u32 mark = READ_ONCE(ct->mark);
++
++ if (!mark)
++ return 0;
++
+ if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ goto nla_put_failure;
+ return 0;
+@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ if (ctnetlink_dump_status(skb, ct) < 0 ||
+- ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
++ ctnetlink_dump_mark(skb, ct) < 0 ||
+ ctnetlink_dump_secctx(skb, ct) < 0 ||
+ ctnetlink_dump_id(skb, ct) < 0 ||
+ ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ struct sk_buff *skb;
+ unsigned int type;
+ unsigned int flags = 0, group;
+- u32 mark;
+ int err;
+
+ if (events & (1 << IPCT_DESTROY)) {
+@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- mark = READ_ONCE(ct->mark);
+- if ((events & (1 << IPCT_MARK) || mark) &&
+- ctnetlink_dump_mark(skb, mark) < 0)
++ if (events & (1 << IPCT_MARK) &&
++ ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+ #endif
+ nlmsg_end(skb, nlh);
+@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ const struct nf_conntrack_zone *zone;
+ struct nlattr *nest_parms;
+- u32 mark;
+
+ zone = nf_ct_zone(ct);
+
+@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ goto nla_put_failure;
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- mark = READ_ONCE(ct->mark);
+- if (mark && ctnetlink_dump_mark(skb, mark) < 0)
++ if (ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+ #endif
+ if (ctnetlink_dump_labels(skb, ct) < 0)
+--
+cgit
+
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-08 11:40 Alice Ferrazzi
0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-08 11:40 UTC (permalink / raw
To: gentoo-commits
commit: a50c38236ed2bbbe1fd3b03fa28959329ea054c6
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 8 11:37:53 2022 +0000
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Dec 8 11:38:02 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a50c3823
Linux patch 6.0.12
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>
0000_README | 4 +
1011_linux-6.0.12.patch | 4938 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 4942 insertions(+)
diff --git a/0000_README b/0000_README
index 52214e7a..37d6ef5a 100644
--- a/0000_README
+++ b/0000_README
@@ -87,6 +87,10 @@ Patch: 1010_linux-6.0.11.patch
From: http://www.kernel.org
Desc: Linux 6.0.11
+Patch: 1011_linux-6.0.12.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.12
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1011_linux-6.0.12.patch b/1011_linux-6.0.12.patch
new file mode 100644
index 00000000..9bfea012
--- /dev/null
+++ b/1011_linux-6.0.12.patch
@@ -0,0 +1,4938 @@
+diff --git a/Makefile b/Makefile
+index 9fecb094c28a2..46c6eb57b354d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 11
++SUBLEVEL = 12
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
+index d1181ead18e5a..21344fbc89e5e 100644
+--- a/arch/arm/boot/dts/at91rm9200.dtsi
++++ b/arch/arm/boot/dts/at91rm9200.dtsi
+@@ -660,7 +660,7 @@
+ compatible = "atmel,at91rm9200-udc";
+ reg = <0xfffb0000 0x4000>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>;
+- clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>;
++ clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
+index 43f1c76d48cea..a379b0ce19ffa 100644
+--- a/arch/powerpc/net/bpf_jit_comp32.c
++++ b/arch/powerpc/net/bpf_jit_comp32.c
+@@ -113,23 +113,19 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
+ {
+ int i;
+
+- /* First arg comes in as a 32 bits pointer. */
+- EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3));
+- EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0));
++ /* Initialize tail_call_cnt, to be skipped if we do tail calls. */
++ EMIT(PPC_RAW_LI(_R4, 0));
++
++#define BPF_TAILCALL_PROLOGUE_SIZE 4
++
+ EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx)));
+
+- /*
+- * Initialize tail_call_cnt in stack frame if we do tail calls.
+- * Otherwise, put in NOPs so that it can be skipped when we are
+- * invoked through a tail call.
+- */
+ if (ctx->seen & SEEN_TAILCALL)
+- EMIT(PPC_RAW_STW(bpf_to_ppc(BPF_REG_1) - 1, _R1,
+- bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+- else
+- EMIT(PPC_RAW_NOP());
++ EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+
+-#define BPF_TAILCALL_PROLOGUE_SIZE 16
++ /* First arg comes in as a 32 bits pointer. */
++ EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3));
++ EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0));
+
+ /*
+ * We need a stack frame, but we don't necessarily need to
+@@ -170,24 +166,24 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
+ for (i = BPF_PPC_NVR_MIN; i <= 31; i++)
+ if (bpf_is_seen_register(ctx, i))
+ EMIT(PPC_RAW_LWZ(i, _R1, bpf_jit_stack_offsetof(ctx, i)));
+-}
+-
+-void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
+-{
+- EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
+-
+- bpf_jit_emit_common_epilogue(image, ctx);
+-
+- /* Tear down our stack frame */
+
+ if (ctx->seen & SEEN_FUNC)
+ EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF));
+
++ /* Tear down our stack frame */
+ EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx)));
+
+ if (ctx->seen & SEEN_FUNC)
+ EMIT(PPC_RAW_MTLR(_R0));
+
++}
++
++void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
++{
++ EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
++
++ bpf_jit_emit_common_epilogue(image, ctx);
++
+ EMIT(PPC_RAW_BLR());
+ }
+
+@@ -244,7 +240,6 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
+ EMIT(PPC_RAW_RLWINM(_R3, b2p_index, 2, 0, 29));
+ EMIT(PPC_RAW_ADD(_R3, _R3, b2p_bpf_array));
+ EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_array, ptrs)));
+- EMIT(PPC_RAW_STW(_R0, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+
+ /*
+ * if (prog == NULL)
+@@ -255,19 +250,14 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
+
+ /* goto *(prog->bpf_func + prologue_size); */
+ EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_prog, bpf_func)));
+-
+- if (ctx->seen & SEEN_FUNC)
+- EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF));
+-
+ EMIT(PPC_RAW_ADDIC(_R3, _R3, BPF_TAILCALL_PROLOGUE_SIZE));
+-
+- if (ctx->seen & SEEN_FUNC)
+- EMIT(PPC_RAW_MTLR(_R0));
+-
+ EMIT(PPC_RAW_MTCTR(_R3));
+
+ EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_1)));
+
++ /* Put tail_call_cnt in r4 */
++ EMIT(PPC_RAW_MR(_R4, _R0));
++
+ /* tear restore NVRs, ... */
+ bpf_jit_emit_common_epilogue(image, ctx);
+
+diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
+index 1b471ff731788..816e753de636d 100644
+--- a/arch/riscv/include/asm/asm.h
++++ b/arch/riscv/include/asm/asm.h
+@@ -23,6 +23,7 @@
+ #define REG_L __REG_SEL(ld, lw)
+ #define REG_S __REG_SEL(sd, sw)
+ #define REG_SC __REG_SEL(sc.d, sc.w)
++#define REG_AMOSWAP_AQ __REG_SEL(amoswap.d.aq, amoswap.w.aq)
+ #define REG_ASM __REG_SEL(.dword, .word)
+ #define SZREG __REG_SEL(8, 4)
+ #define LGREG __REG_SEL(3, 2)
+diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
+index f74879a8f1ea1..e229d7be4b665 100644
+--- a/arch/riscv/include/asm/efi.h
++++ b/arch/riscv/include/asm/efi.h
+@@ -10,6 +10,7 @@
+ #include <asm/mmu_context.h>
+ #include <asm/ptrace.h>
+ #include <asm/tlbflush.h>
++#include <asm/pgalloc.h>
+
+ #ifdef CONFIG_EFI
+ extern void efi_init(void);
+@@ -20,7 +21,10 @@ extern void efi_init(void);
+ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
+ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
+
+-#define arch_efi_call_virt_setup() efi_virtmap_load()
++#define arch_efi_call_virt_setup() ({ \
++ sync_kernel_mappings(efi_mm.pgd); \
++ efi_virtmap_load(); \
++ })
+ #define arch_efi_call_virt_teardown() efi_virtmap_unload()
+
+ #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE)
+diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
+index 947f23d7b6af5..59dc12b5b7e8f 100644
+--- a/arch/riscv/include/asm/pgalloc.h
++++ b/arch/riscv/include/asm/pgalloc.h
+@@ -127,6 +127,13 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+ #define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d)
+ #endif /* __PAGETABLE_PMD_FOLDED */
+
++static inline void sync_kernel_mappings(pgd_t *pgd)
++{
++ memcpy(pgd + USER_PTRS_PER_PGD,
++ init_mm.pgd + USER_PTRS_PER_PGD,
++ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++}
++
+ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+ pgd_t *pgd;
+@@ -135,9 +142,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ if (likely(pgd != NULL)) {
+ memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+ /* Copy kernel mappings */
+- memcpy(pgd + USER_PTRS_PER_PGD,
+- init_mm.pgd + USER_PTRS_PER_PGD,
+- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++ sync_kernel_mappings(pgd);
+ }
+ return pgd;
+ }
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
+index b9eda3fcbd6d7..186abd146eaff 100644
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -404,6 +404,19 @@ handle_syscall_trace_exit:
+
+ #ifdef CONFIG_VMAP_STACK
+ handle_kernel_stack_overflow:
++ /*
++ * Takes the psuedo-spinlock for the shadow stack, in case multiple
++ * harts are concurrently overflowing their kernel stacks. We could
++ * store any value here, but since we're overflowing the kernel stack
++ * already we only have SP to use as a scratch register. So we just
++ * swap in the address of the spinlock, as that's definately non-zero.
++ *
++ * Pairs with a store_release in handle_bad_stack().
++ */
++1: la sp, spin_shadow_stack
++ REG_AMOSWAP_AQ sp, sp, (sp)
++ bnez sp, 1b
++
+ la sp, shadow_stack
+ addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE
+
+diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
+index ee79e6839b863..db41c676e5a26 100644
+--- a/arch/riscv/kernel/machine_kexec.c
++++ b/arch/riscv/kernel/machine_kexec.c
+@@ -15,6 +15,8 @@
+ #include <linux/compiler.h> /* For unreachable() */
+ #include <linux/cpu.h> /* For cpu_down() */
+ #include <linux/reboot.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
+
+ /*
+ * kexec_image_info - Print received image details
+@@ -154,6 +156,37 @@ void crash_smp_send_stop(void)
+ cpus_stopped = 1;
+ }
+
++static void machine_kexec_mask_interrupts(void)
++{
++ unsigned int i;
++ struct irq_desc *desc;
++
++ for_each_irq_desc(i, desc) {
++ struct irq_chip *chip;
++ int ret;
++
++ chip = irq_desc_get_chip(desc);
++ if (!chip)
++ continue;
++
++ /*
++ * First try to remove the active state. If this
++ * fails, try to EOI the interrupt.
++ */
++ ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
++
++ if (ret && irqd_irq_inprogress(&desc->irq_data) &&
++ chip->irq_eoi)
++ chip->irq_eoi(&desc->irq_data);
++
++ if (chip->irq_mask)
++ chip->irq_mask(&desc->irq_data);
++
++ if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
++ chip->irq_disable(&desc->irq_data);
++ }
++}
++
+ /*
+ * machine_crash_shutdown - Prepare to kexec after a kernel crash
+ *
+@@ -169,6 +202,8 @@ machine_crash_shutdown(struct pt_regs *regs)
+ crash_smp_send_stop();
+
+ crash_save_cpu(regs, smp_processor_id());
++ machine_kexec_mask_interrupts();
++
+ pr_info("Starting crashdump kernel...\n");
+ }
+
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 67ec1fadcfe24..86acd690d5293 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -322,10 +322,11 @@ subsys_initcall(topology_init);
+
+ void free_initmem(void)
+ {
+- if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
+- set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end),
+- IS_ENABLED(CONFIG_64BIT) ?
+- set_memory_rw : set_memory_rw_nx);
++ if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
++ set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), set_memory_rw_nx);
++ if (IS_ENABLED(CONFIG_64BIT))
++ set_kernel_memory(__init_begin, __init_end, set_memory_nx);
++ }
+
+ free_initmem_default(POISON_FREE_INITMEM);
+ }
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 635e6ec269380..6e8822446069e 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -218,11 +218,29 @@ asmlinkage unsigned long get_overflow_stack(void)
+ OVERFLOW_STACK_SIZE;
+ }
+
++/*
++ * A pseudo spinlock to protect the shadow stack from being used by multiple
++ * harts concurrently. This isn't a real spinlock because the lock side must
++ * be taken without a valid stack and only a single register, it's only taken
++ * while in the process of panicing anyway so the performance and error
++ * checking a proper spinlock gives us doesn't matter.
++ */
++unsigned long spin_shadow_stack;
++
+ asmlinkage void handle_bad_stack(struct pt_regs *regs)
+ {
+ unsigned long tsk_stk = (unsigned long)current->stack;
+ unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack);
+
++ /*
++ * We're done with the shadow stack by this point, as we're on the
++ * overflow stack. Tell any other concurrent overflowing harts that
++ * they can proceed with panicing by releasing the pseudo-spinlock.
++ *
++ * This pairs with an amoswap.aq in handle_kernel_stack_overflow.
++ */
++ smp_store_release(&spin_shadow_stack, 0);
++
+ console_verbose();
+
+ pr_emerg("Insufficient stack space to handle exception!\n");
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index db6548509bb3e..06e6b27f3bcc9 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -17,6 +17,7 @@ vdso-syms += flush_icache
+ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
+
+ ccflags-y := -fno-stack-protector
++ccflags-y += -DDISABLE_BRANCH_PROFILING
+
+ ifneq ($(c-gettimeofday-y),)
+ CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
+diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
+index c936ce9f0c47c..dfdb103ae4f6f 100644
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -321,7 +321,7 @@ static inline void indirect_branch_prediction_barrier(void)
+ /* The Intel SPEC CTRL MSR base value cache */
+ extern u64 x86_spec_ctrl_base;
+ DECLARE_PER_CPU(u64, x86_spec_ctrl_current);
+-extern void write_spec_ctrl_current(u64 val, bool force);
++extern void update_spec_ctrl_cond(u64 val);
+ extern u64 spec_ctrl_current(void);
+
+ /*
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 6ec0b7ce74531..06ad95ae78ceb 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -60,11 +60,18 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
+
+ static DEFINE_MUTEX(spec_ctrl_mutex);
+
++/* Update SPEC_CTRL MSR and its cached copy unconditionally */
++static void update_spec_ctrl(u64 val)
++{
++ this_cpu_write(x86_spec_ctrl_current, val);
++ wrmsrl(MSR_IA32_SPEC_CTRL, val);
++}
++
+ /*
+ * Keep track of the SPEC_CTRL MSR value for the current task, which may differ
+ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update().
+ */
+-void write_spec_ctrl_current(u64 val, bool force)
++void update_spec_ctrl_cond(u64 val)
+ {
+ if (this_cpu_read(x86_spec_ctrl_current) == val)
+ return;
+@@ -75,7 +82,7 @@ void write_spec_ctrl_current(u64 val, bool force)
+ * When KERNEL_IBRS this MSR is written on return-to-user, unless
+ * forced the update can be delayed until that time.
+ */
+- if (force || !cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
++ if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
+ wrmsrl(MSR_IA32_SPEC_CTRL, val);
+ }
+
+@@ -1328,7 +1335,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
+
+ if (ia32_cap & ARCH_CAP_RRSBA) {
+ x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+ }
+
+@@ -1450,7 +1457,7 @@ static void __init spectre_v2_select_mitigation(void)
+
+ if (spectre_v2_in_ibrs_mode(mode)) {
+ x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+
+ switch (mode) {
+@@ -1564,7 +1571,7 @@ static void __init spectre_v2_select_mitigation(void)
+ static void update_stibp_msr(void * __unused)
+ {
+ u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP);
+- write_spec_ctrl_current(val, true);
++ update_spec_ctrl(val);
+ }
+
+ /* Update x86_spec_ctrl_base in case SMT state changed. */
+@@ -1797,7 +1804,7 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
+ x86_amd_ssb_disable();
+ } else {
+ x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+ }
+
+@@ -2048,7 +2055,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
+ void x86_spec_ctrl_setup_ap(void)
+ {
+ if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+
+ if (ssb_mode == SPEC_STORE_BYPASS_DISABLE)
+ x86_amd_ssb_disable();
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 58a6ea472db92..5e39449b9dfce 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -600,7 +600,7 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
+ }
+
+ if (updmsr)
+- write_spec_ctrl_current(msr, false);
++ update_spec_ctrl_cond(msr);
+ }
+
+ static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
+diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
+index c3d783aca196f..b42653707fdcd 100644
+--- a/drivers/acpi/numa/hmat.c
++++ b/drivers/acpi/numa/hmat.c
+@@ -563,17 +563,26 @@ static int initiator_cmp(void *priv, const struct list_head *a,
+ {
+ struct memory_initiator *ia;
+ struct memory_initiator *ib;
+- unsigned long *p_nodes = priv;
+
+ ia = list_entry(a, struct memory_initiator, node);
+ ib = list_entry(b, struct memory_initiator, node);
+
+- set_bit(ia->processor_pxm, p_nodes);
+- set_bit(ib->processor_pxm, p_nodes);
+-
+ return ia->processor_pxm - ib->processor_pxm;
+ }
+
++static int initiators_to_nodemask(unsigned long *p_nodes)
++{
++ struct memory_initiator *initiator;
++
++ if (list_empty(&initiators))
++ return -ENXIO;
++
++ list_for_each_entry(initiator, &initiators, node)
++ set_bit(initiator->processor_pxm, p_nodes);
++
++ return 0;
++}
++
+ static void hmat_register_target_initiators(struct memory_target *target)
+ {
+ static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
+@@ -610,7 +619,10 @@ static void hmat_register_target_initiators(struct memory_target *target)
+ * initiators.
+ */
+ bitmap_zero(p_nodes, MAX_NUMNODES);
+- list_sort(p_nodes, &initiators, initiator_cmp);
++ list_sort(NULL, &initiators, initiator_cmp);
++ if (initiators_to_nodemask(p_nodes) < 0)
++ return;
++
+ if (!access0done) {
+ for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
+ loc = localities_types[i];
+@@ -644,8 +656,9 @@ static void hmat_register_target_initiators(struct memory_target *target)
+
+ /* Access 1 ignores Generic Initiators */
+ bitmap_zero(p_nodes, MAX_NUMNODES);
+- list_sort(p_nodes, &initiators, initiator_cmp);
+- best = 0;
++ if (initiators_to_nodemask(p_nodes) < 0)
++ return;
++
+ for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
+ loc = localities_types[i];
+ if (!loc)
+diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
+index 1621ce8187052..d69905233aff2 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -401,13 +401,14 @@ int tpm_pm_suspend(struct device *dev)
+ !pm_suspend_via_firmware())
+ goto suspended;
+
+- if (!tpm_chip_start(chip)) {
++ 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_chip_stop(chip);
++ tpm_put_ops(chip);
+ }
+
+ suspended:
+diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
+index b174f727a8ef8..16870943a13e5 100644
+--- a/drivers/clk/at91/at91rm9200.c
++++ b/drivers/clk/at91/at91rm9200.c
+@@ -40,7 +40,7 @@ static const struct clk_pll_characteristics rm9200_pll_characteristics = {
+ };
+
+ static const struct sck at91rm9200_systemck[] = {
+- { .n = "udpck", .p = "usbck", .id = 2 },
++ { .n = "udpck", .p = "usbck", .id = 1 },
+ { .n = "uhpck", .p = "usbck", .id = 4 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c
+index a2f3ffcc58491..fd332383527fc 100644
+--- a/drivers/clk/qcom/gcc-sc8280xp.c
++++ b/drivers/clk/qcom/gcc-sc8280xp.c
+@@ -5364,6 +5364,8 @@ static struct clk_branch gcc_ufs_1_card_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_1_card_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+@@ -5432,6 +5434,8 @@ static struct clk_branch gcc_ufs_card_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_card_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+@@ -5848,6 +5852,8 @@ static struct clk_branch gcc_ufs_ref_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_ref_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
+index d3244006c661a..39b35058ad474 100644
+--- a/drivers/clk/qcom/gdsc.c
++++ b/drivers/clk/qcom/gdsc.c
+@@ -11,7 +11,6 @@
+ #include <linux/kernel.h>
+ #include <linux/ktime.h>
+ #include <linux/pm_domain.h>
+-#include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset-controller.h>
+@@ -56,22 +55,6 @@ enum gdsc_status {
+ GDSC_ON
+ };
+
+-static int gdsc_pm_runtime_get(struct gdsc *sc)
+-{
+- if (!sc->dev)
+- return 0;
+-
+- return pm_runtime_resume_and_get(sc->dev);
+-}
+-
+-static int gdsc_pm_runtime_put(struct gdsc *sc)
+-{
+- if (!sc->dev)
+- return 0;
+-
+- return pm_runtime_put_sync(sc->dev);
+-}
+-
+ /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */
+ static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status)
+ {
+@@ -271,8 +254,9 @@ static void gdsc_retain_ff_on(struct gdsc *sc)
+ regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
+ }
+
+-static int _gdsc_enable(struct gdsc *sc)
++static int gdsc_enable(struct generic_pm_domain *domain)
+ {
++ struct gdsc *sc = domain_to_gdsc(domain);
+ int ret;
+
+ if (sc->pwrsts == PWRSTS_ON)
+@@ -328,22 +312,11 @@ static int _gdsc_enable(struct gdsc *sc)
+ return 0;
+ }
+
+-static int gdsc_enable(struct generic_pm_domain *domain)
++static int gdsc_disable(struct generic_pm_domain *domain)
+ {
+ struct gdsc *sc = domain_to_gdsc(domain);
+ int ret;
+
+- ret = gdsc_pm_runtime_get(sc);
+- if (ret)
+- return ret;
+-
+- return _gdsc_enable(sc);
+-}
+-
+-static int _gdsc_disable(struct gdsc *sc)
+-{
+- int ret;
+-
+ if (sc->pwrsts == PWRSTS_ON)
+ return gdsc_assert_reset(sc);
+
+@@ -378,18 +351,6 @@ static int _gdsc_disable(struct gdsc *sc)
+ return 0;
+ }
+
+-static int gdsc_disable(struct generic_pm_domain *domain)
+-{
+- struct gdsc *sc = domain_to_gdsc(domain);
+- int ret;
+-
+- ret = _gdsc_disable(sc);
+-
+- gdsc_pm_runtime_put(sc);
+-
+- return ret;
+-}
+-
+ static int gdsc_init(struct gdsc *sc)
+ {
+ u32 mask, val;
+@@ -437,14 +398,6 @@ static int gdsc_init(struct gdsc *sc)
+ return ret;
+ }
+
+- /* ...and the power-domain */
+- ret = gdsc_pm_runtime_get(sc);
+- if (ret) {
+- if (sc->rsupply)
+- regulator_disable(sc->rsupply);
+- return ret;
+- }
+-
+ /*
+ * Votable GDSCs can be ON due to Vote from other masters.
+ * If a Votable GDSC is ON, make sure we have a Vote.
+@@ -452,14 +405,14 @@ static int gdsc_init(struct gdsc *sc)
+ if (sc->flags & VOTABLE) {
+ ret = gdsc_update_collapse_bit(sc, false);
+ if (ret)
+- return ret;
++ goto err_disable_supply;
+ }
+
+ /* Turn on HW trigger mode if supported */
+ if (sc->flags & HW_CTRL) {
+ ret = gdsc_hwctrl(sc, true);
+ if (ret < 0)
+- return ret;
++ goto err_disable_supply;
+ }
+
+ /*
+@@ -486,9 +439,18 @@ static int gdsc_init(struct gdsc *sc)
+ sc->pd.power_off = gdsc_disable;
+ if (!sc->pd.power_on)
+ sc->pd.power_on = gdsc_enable;
+- pm_genpd_init(&sc->pd, NULL, !on);
++
++ ret = pm_genpd_init(&sc->pd, NULL, !on);
++ if (ret)
++ goto err_disable_supply;
+
+ return 0;
++
++err_disable_supply:
++ if (on && sc->rsupply)
++ regulator_disable(sc->rsupply);
++
++ return ret;
+ }
+
+ int gdsc_register(struct gdsc_desc *desc,
+@@ -522,8 +484,6 @@ int gdsc_register(struct gdsc_desc *desc,
+ for (i = 0; i < num; i++) {
+ if (!scs[i])
+ continue;
+- if (pm_runtime_enabled(dev))
+- scs[i]->dev = dev;
+ scs[i]->regmap = regmap;
+ scs[i]->rcdev = rcdev;
+ ret = gdsc_init(scs[i]);
+diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
+index 5de48c9439b29..8d569232bbd6b 100644
+--- a/drivers/clk/qcom/gdsc.h
++++ b/drivers/clk/qcom/gdsc.h
+@@ -30,7 +30,6 @@ struct reset_controller_dev;
+ * @resets: ids of resets associated with this gdsc
+ * @reset_count: number of @resets
+ * @rcdev: reset controller
+- * @dev: the device holding the GDSC, used for pm_runtime calls
+ */
+ struct gdsc {
+ struct generic_pm_domain pd;
+@@ -69,7 +68,6 @@ struct gdsc {
+
+ const char *supply;
+ struct regulator *rsupply;
+- struct device *dev;
+ };
+
+ struct gdsc_desc {
+diff --git a/drivers/clk/samsung/clk-exynos7885.c b/drivers/clk/samsung/clk-exynos7885.c
+index a7b1063027067..368c50badd15a 100644
+--- a/drivers/clk/samsung/clk-exynos7885.c
++++ b/drivers/clk/samsung/clk-exynos7885.c
+@@ -182,7 +182,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
+ CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+ DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
+ CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+- DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
++ DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
+ CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+ DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll",
+ CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3),
+@@ -190,7 +190,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
+ CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+ DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
+ CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+- DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
++ DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
+ CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+ /* CORE */
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index a7ff77550e173..933bb960490d0 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -806,6 +806,9 @@ static u64 __arch_timer_check_delta(void)
+ /*
+ * XGene-1 implements CVAL in terms of TVAL, meaning
+ * that the maximum timer range is 32bit. Shame on them.
++ *
++ * Note that TVAL is signed, thus has only 31 of its
++ * 32 bits to express magnitude.
+ */
+ MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM,
+ APM_CPU_PART_POTENZA)),
+@@ -813,8 +816,8 @@ static u64 __arch_timer_check_delta(void)
+ };
+
+ if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) {
+- pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits");
+- return CLOCKSOURCE_MASK(32);
++ pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n");
++ return CLOCKSOURCE_MASK(31);
+ }
+ #endif
+ return CLOCKSOURCE_MASK(arch_counter_get_width());
+diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
+index 969a552da8d29..a0d66fabf0732 100644
+--- a/drivers/clocksource/timer-riscv.c
++++ b/drivers/clocksource/timer-riscv.c
+@@ -51,7 +51,7 @@ static int riscv_clock_next_event(unsigned long delta,
+ static unsigned int riscv_clock_event_irq;
+ static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = {
+ .name = "riscv_timer_clockevent",
+- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP,
++ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 100,
+ .set_next_event = riscv_clock_next_event,
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 7db4aef9c45cb..5e184952ec988 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -985,6 +985,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ struct amdkfd_process_info *process_info = mem->process_info;
+ struct amdgpu_bo *bo = mem->bo;
+ struct ttm_operation_ctx ctx = { true, false };
++ struct hmm_range *range;
+ int ret = 0;
+
+ mutex_lock(&process_info->lock);
+@@ -1014,7 +1015,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ return 0;
+ }
+
+- ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, &range);
+ if (ret) {
+ pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
+ goto unregister_out;
+@@ -1032,7 +1033,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ amdgpu_bo_unreserve(bo);
+
+ release_out:
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+ unregister_out:
+ if (ret)
+ amdgpu_mn_unregister(bo);
+@@ -2367,6 +2368,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ /* Go through userptr_inval_list and update any invalid user_pages */
+ list_for_each_entry(mem, &process_info->userptr_inval_list,
+ validate_list.head) {
++ struct hmm_range *range;
++
+ invalid = atomic_read(&mem->invalid);
+ if (!invalid)
+ /* BO hasn't been invalidated since the last
+@@ -2377,7 +2380,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ bo = mem->bo;
+
+ /* Get updated user pages */
+- ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
++ &range);
+ if (ret) {
+ pr_debug("Failed %d to get user pages\n", ret);
+
+@@ -2396,7 +2400,7 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ * FIXME: Cannot ignore the return code, must hold
+ * notifier_lock
+ */
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+ }
+
+ /* Mark the BO as valid unless it was invalidated
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+index 2168163aad2d3..252a876b07258 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+@@ -209,6 +209,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
+ list_add_tail(&e->tv.head, &bucket[priority]);
+
+ e->user_pages = NULL;
++ e->range = NULL;
+ }
+
+ /* Connect the sorted buckets in the output list. */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+index 9caea1688fc32..e4d78491bcc7e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+@@ -26,6 +26,8 @@
+ #include <drm/ttm/ttm_execbuf_util.h>
+ #include <drm/amdgpu_drm.h>
+
++struct hmm_range;
++
+ struct amdgpu_device;
+ struct amdgpu_bo;
+ struct amdgpu_bo_va;
+@@ -36,6 +38,7 @@ struct amdgpu_bo_list_entry {
+ struct amdgpu_bo_va *bo_va;
+ uint32_t priority;
+ struct page **user_pages;
++ struct hmm_range *range;
+ bool user_invalidated;
+ };
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index b7bae833c804b..7e350ea0368b6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -495,9 +495,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ struct amdgpu_vm *vm = &fpriv->vm;
+ struct amdgpu_bo_list_entry *e;
+ struct list_head duplicates;
+- struct amdgpu_bo *gds;
+- struct amdgpu_bo *gws;
+- struct amdgpu_bo *oa;
+ int r;
+
+ INIT_LIST_HEAD(&p->validated);
+@@ -551,7 +548,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ goto out_free_user_pages;
+ }
+
+- r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages);
++ r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages, &e->range);
+ if (r) {
+ kvfree(e->user_pages);
+ e->user_pages = NULL;
+@@ -611,49 +608,35 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ if (r)
+ goto error_validate;
+
+- amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
+- p->bytes_moved_vis);
+-
+- gds = p->bo_list->gds_obj;
+- gws = p->bo_list->gws_obj;
+- oa = p->bo_list->oa_obj;
+-
+- if (gds) {
+- p->job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
+- p->job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
+- }
+- if (gws) {
+- p->job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
+- p->job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
+- }
+- if (oa) {
+- p->job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
+- p->job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
+- }
+-
+- if (!r && p->uf_entry.tv.bo) {
++ if (p->uf_entry.tv.bo) {
+ struct amdgpu_bo *uf = ttm_to_amdgpu_bo(p->uf_entry.tv.bo);
+
+ r = amdgpu_ttm_alloc_gart(&uf->tbo);
++ if (r)
++ goto error_validate;
++
+ p->job->uf_addr += amdgpu_bo_gpu_offset(uf);
+ }
+
++ amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
++ p->bytes_moved_vis);
++ amdgpu_job_set_resources(p->job, p->bo_list->gds_obj,
++ p->bo_list->gws_obj, p->bo_list->oa_obj);
++ return 0;
++
+ error_validate:
+- if (r)
+- ttm_eu_backoff_reservation(&p->ticket, &p->validated);
++ ttm_eu_backoff_reservation(&p->ticket, &p->validated);
+
+ out_free_user_pages:
+- if (r) {
+- amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+- struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
++ amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
++ struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
+
+- if (!e->user_pages)
+- continue;
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+- kvfree(e->user_pages);
+- e->user_pages = NULL;
+- }
+- mutex_unlock(&p->bo_list->bo_list_mutex);
++ if (!e->user_pages)
++ continue;
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
++ kvfree(e->user_pages);
++ e->user_pages = NULL;
++ e->range = NULL;
+ }
+ return r;
+ }
+@@ -1248,7 +1231,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
+ amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+ struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
+
+- r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
++ e->range = NULL;
+ }
+ if (r) {
+ r = -EAGAIN;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+index 111484ceb47d7..91571b1324f2f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+@@ -378,6 +378,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ struct drm_amdgpu_gem_userptr *args = data;
+ struct drm_gem_object *gobj;
++ struct hmm_range *range;
+ struct amdgpu_bo *bo;
+ uint32_t handle;
+ int r;
+@@ -418,7 +419,8 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ goto release_object;
+
+ if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+- r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
++ &range);
+ if (r)
+ goto release_object;
+
+@@ -441,7 +443,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+
+ user_pages_done:
+ if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+
+ release_object:
+ drm_gem_object_put(gobj);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index c2fd6f3076a6f..3b025aace2831 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -129,6 +129,23 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
+ return r;
+ }
+
++void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
++ struct amdgpu_bo *gws, struct amdgpu_bo *oa)
++{
++ if (gds) {
++ job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
++ job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
++ }
++ if (gws) {
++ job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
++ job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
++ }
++ if (oa) {
++ job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
++ job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
++ }
++}
++
+ void amdgpu_job_free_resources(struct amdgpu_job *job)
+ {
+ struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+index babc0af751c2f..2a1961bf1194f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+@@ -76,6 +76,8 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
+ struct amdgpu_job **job, struct amdgpu_vm *vm);
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
+ enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
++void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
++ struct amdgpu_bo *gws, struct amdgpu_bo *oa);
+ void amdgpu_job_free_resources(struct amdgpu_job *job);
+ void amdgpu_job_free(struct amdgpu_job *job);
+ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 9e6c23266a1a0..dfb8875e0f286 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -642,9 +642,6 @@ struct amdgpu_ttm_tt {
+ struct task_struct *usertask;
+ uint32_t userflags;
+ bool bound;
+-#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+- struct hmm_range *range;
+-#endif
+ };
+
+ #define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm)
+@@ -657,7 +654,8 @@ struct amdgpu_ttm_tt {
+ * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only
+ * once afterwards to stop HMM tracking
+ */
+-int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
++int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
++ struct hmm_range **range)
+ {
+ struct ttm_tt *ttm = bo->tbo.ttm;
+ struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
+@@ -667,16 +665,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
+ bool readonly;
+ int r = 0;
+
++ /* Make sure get_user_pages_done() can cleanup gracefully */
++ *range = NULL;
++
+ mm = bo->notifier.mm;
+ if (unlikely(!mm)) {
+ DRM_DEBUG_DRIVER("BO is not registered?\n");
+ return -EFAULT;
+ }
+
+- /* Another get_user_pages is running at the same time?? */
+- if (WARN_ON(gtt->range))
+- return -EFAULT;
+-
+ if (!mmget_not_zero(mm)) /* Happens during process shutdown */
+ return -ESRCH;
+
+@@ -694,7 +691,7 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
+
+ readonly = amdgpu_ttm_tt_is_readonly(ttm);
+ r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start,
+- ttm->num_pages, >t->range, readonly,
++ ttm->num_pages, range, readonly,
+ true, NULL);
+ out_unlock:
+ mmap_read_unlock(mm);
+@@ -712,30 +709,24 @@ out_unlock:
+ *
+ * Returns: true if pages are still valid
+ */
+-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
++bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range)
+ {
+ struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
+- bool r = false;
+
+- if (!gtt || !gtt->userptr)
++ if (!gtt || !gtt->userptr || !range)
+ return false;
+
+ DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n",
+ gtt->userptr, ttm->num_pages);
+
+- WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns,
+- "No user pages to check\n");
++ WARN_ONCE(!range->hmm_pfns, "No user pages to check\n");
+
+- if (gtt->range) {
+- /*
+- * FIXME: Must always hold notifier_lock for this, and must
+- * not ignore the return code.
+- */
+- r = amdgpu_hmm_range_get_pages_done(gtt->range);
+- gtt->range = NULL;
+- }
+-
+- return !r;
++ /*
++ * FIXME: Must always hold notifier_lock for this, and must
++ * not ignore the return code.
++ */
++ return !amdgpu_hmm_range_get_pages_done(range);
+ }
+ #endif
+
+@@ -812,20 +803,6 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
+ /* unmap the pages mapped to the device */
+ dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
+ sg_free_table(ttm->sg);
+-
+-#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+- if (gtt->range) {
+- unsigned long i;
+-
+- for (i = 0; i < ttm->num_pages; i++) {
+- if (ttm->pages[i] !=
+- hmm_pfn_to_page(gtt->range->hmm_pfns[i]))
+- break;
+- }
+-
+- WARN((i == ttm->num_pages), "Missing get_user_page_done\n");
+- }
+-#endif
+ }
+
+ static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+index 6a70818039dda..a37207011a69a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+@@ -39,6 +39,8 @@
+
+ #define AMDGPU_POISON 0xd0bed0be
+
++struct hmm_range;
++
+ struct amdgpu_gtt_mgr {
+ struct ttm_resource_manager manager;
+ struct drm_mm mm;
+@@ -149,15 +151,19 @@ void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
+ uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
+
+ #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+-int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages);
+-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm);
++int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
++ struct hmm_range **range);
++bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range);
+ #else
+ static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
+- struct page **pages)
++ struct page **pages,
++ struct hmm_range **range)
+ {
+ return -EPERM;
+ }
+-static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
++static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range)
+ {
+ return false;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+index 0b52af415b282..ce64ca1c6e669 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+@@ -156,6 +156,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
+ break;
+ case IP_VERSION(3, 0, 2):
+ fw_name = FIRMWARE_VANGOGH;
++ if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
++ (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
++ adev->vcn.indirect_sram = true;
+ break;
+ case IP_VERSION(3, 0, 16):
+ fw_name = FIRMWARE_DIMGREY_CAVEFISH;
+diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
+index 413d8c6d592ff..220fb332c8e61 100644
+--- a/drivers/gpu/drm/amd/display/Kconfig
++++ b/drivers/gpu/drm/amd/display/Kconfig
+@@ -5,6 +5,7 @@ menu "Display Engine Configuration"
+ config DRM_AMD_DC
+ bool "AMD DC - Enable new display engine"
+ default y
++ depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64
+ select SND_HDA_COMPONENT if SND_HDA_CORE
+ select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128)
+ help
+@@ -12,6 +13,12 @@ config DRM_AMD_DC
+ support for AMDGPU. This adds required support for Vega and
+ Raven ASICs.
+
++ calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || ARM64)
++ architectures built with Clang (all released versions), whereby the stack
++ frame gets blown up to well over 5k. This would cause an immediate kernel
++ panic on most architectures. We'll revert this when the following bug report
++ has been resolved: https://github.com/llvm/llvm-project/issues/41896.
++
+ config DRM_AMD_DC_DCN
+ def_bool n
+ help
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+index 063f4a7376056..b76f0f7e42998 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+@@ -25,7 +25,7 @@
+ #define SMU13_DRIVER_IF_V13_0_0_H
+
+ //Increment this version if SkuTable_t or BoardTable_t change
+-#define PPTABLE_VERSION 0x24
++#define PPTABLE_VERSION 0x26
+
+ #define NUM_GFXCLK_DPM_LEVELS 16
+ #define NUM_SOCCLK_DPM_LEVELS 8
+@@ -109,6 +109,22 @@
+ #define FEATURE_SPARE_63_BIT 63
+ #define NUM_FEATURES 64
+
++#define ALLOWED_FEATURE_CTRL_DEFAULT 0xFFFFFFFFFFFFFFFFULL
++#define ALLOWED_FEATURE_CTRL_SCPM ((1 << FEATURE_DPM_GFXCLK_BIT) | \
++ (1 << FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT) | \
++ (1 << FEATURE_DPM_UCLK_BIT) | \
++ (1 << FEATURE_DPM_FCLK_BIT) | \
++ (1 << FEATURE_DPM_SOCCLK_BIT) | \
++ (1 << FEATURE_DPM_MP0CLK_BIT) | \
++ (1 << FEATURE_DPM_LINK_BIT) | \
++ (1 << FEATURE_DPM_DCN_BIT) | \
++ (1 << FEATURE_DS_GFXCLK_BIT) | \
++ (1 << FEATURE_DS_SOCCLK_BIT) | \
++ (1 << FEATURE_DS_FCLK_BIT) | \
++ (1 << FEATURE_DS_LCLK_BIT) | \
++ (1 << FEATURE_DS_DCFCLK_BIT) | \
++ (1 << FEATURE_DS_UCLK_BIT))
++
+ //For use with feature control messages
+ typedef enum {
+ FEATURE_PWR_ALL,
+@@ -133,6 +149,7 @@ typedef enum {
+ #define DEBUG_OVERRIDE_DISABLE_DFLL 0x00000200
+ #define DEBUG_OVERRIDE_ENABLE_RLC_VF_BRINGUP_MODE 0x00000400
+ #define DEBUG_OVERRIDE_DFLL_MASTER_MODE 0x00000800
++#define DEBUG_OVERRIDE_ENABLE_PROFILING_MODE 0x00001000
+
+ // VR Mapping Bit Defines
+ #define VR_MAPPING_VR_SELECT_MASK 0x01
+@@ -262,15 +279,15 @@ typedef enum {
+ } I2cControllerPort_e;
+
+ typedef enum {
+- I2C_CONTROLLER_NAME_VR_GFX = 0,
+- I2C_CONTROLLER_NAME_VR_SOC,
+- I2C_CONTROLLER_NAME_VR_VMEMP,
+- I2C_CONTROLLER_NAME_VR_VDDIO,
+- I2C_CONTROLLER_NAME_LIQUID0,
+- I2C_CONTROLLER_NAME_LIQUID1,
+- I2C_CONTROLLER_NAME_PLX,
+- I2C_CONTROLLER_NAME_OTHER,
+- I2C_CONTROLLER_NAME_COUNT,
++ I2C_CONTROLLER_NAME_VR_GFX = 0,
++ I2C_CONTROLLER_NAME_VR_SOC,
++ I2C_CONTROLLER_NAME_VR_VMEMP,
++ I2C_CONTROLLER_NAME_VR_VDDIO,
++ I2C_CONTROLLER_NAME_LIQUID0,
++ I2C_CONTROLLER_NAME_LIQUID1,
++ I2C_CONTROLLER_NAME_PLX,
++ I2C_CONTROLLER_NAME_FAN_INTAKE,
++ I2C_CONTROLLER_NAME_COUNT,
+ } I2cControllerName_e;
+
+ typedef enum {
+@@ -282,16 +299,17 @@ typedef enum {
+ I2C_CONTROLLER_THROTTLER_LIQUID0,
+ I2C_CONTROLLER_THROTTLER_LIQUID1,
+ I2C_CONTROLLER_THROTTLER_PLX,
++ I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
+ I2C_CONTROLLER_THROTTLER_INA3221,
+ I2C_CONTROLLER_THROTTLER_COUNT,
+ } I2cControllerThrottler_e;
+
+ typedef enum {
+- I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
+- I2C_CONTROLLER_PROTOCOL_VR_IR35217,
+- I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
+- I2C_CONTROLLER_PROTOCOL_INA3221,
+- I2C_CONTROLLER_PROTOCOL_COUNT,
++ I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
++ I2C_CONTROLLER_PROTOCOL_VR_IR35217,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
++ I2C_CONTROLLER_PROTOCOL_INA3221,
++ I2C_CONTROLLER_PROTOCOL_COUNT,
+ } I2cControllerProtocol_e;
+
+ typedef struct {
+@@ -658,13 +676,20 @@ typedef struct {
+
+ #define PP_NUM_OD_VF_CURVE_POINTS PP_NUM_RTAVFS_PWL_ZONES + 1
+
++typedef enum {
++ FAN_MODE_AUTO = 0,
++ FAN_MODE_MANUAL_LINEAR,
++} FanMode_e;
+
+ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+ //Voltage control
+ int16_t VoltageOffsetPerZoneBoundary[PP_NUM_OD_VF_CURVE_POINTS];
+- uint16_t reserved[2];
++ uint16_t VddGfxVmax; // in mV
++
++ uint8_t IdlePwrSavingFeaturesCtrl;
++ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+ //Frequency changes
+ int16_t GfxclkFmin; // MHz
+@@ -674,7 +699,7 @@ typedef struct {
+
+ //PPT
+ int16_t Ppt; // %
+- int16_t reserved1;
++ int16_t Tdc;
+
+ //Fan control
+ uint8_t FanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS];
+@@ -701,16 +726,19 @@ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+ int16_t VoltageOffsetPerZoneBoundary;
+- uint16_t reserved[2];
++ uint16_t VddGfxVmax; // in mV
++
++ uint8_t IdlePwrSavingFeaturesCtrl;
++ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+- uint16_t GfxclkFmin; // MHz
+- uint16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+ //PPT
+ int16_t Ppt; // %
+- int16_t reserved1;
++ int16_t Tdc;
+
+ uint8_t FanLinearPwmPoints;
+ uint8_t FanLinearTempPoints;
+@@ -857,7 +885,8 @@ typedef struct {
+ uint16_t FanStartTempMin;
+ uint16_t FanStartTempMax;
+
+- uint32_t Spare[12];
++ uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
++ uint32_t Spare[11];
+
+ } MsgLimits_t;
+
+@@ -1041,7 +1070,17 @@ typedef struct {
+ uint32_t GfxoffSpare[15];
+
+ // GFX GPO
+- uint32_t GfxGpoSpare[16];
++ uint32_t DfllBtcMasterScalerM;
++ int32_t DfllBtcMasterScalerB;
++ uint32_t DfllBtcSlaveScalerM;
++ int32_t DfllBtcSlaveScalerB;
++
++ uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
++ uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
++
++ uint32_t DfllL2FrequencyBoostM; //Unitless (float)
++ uint32_t DfllL2FrequencyBoostB; //In MHz (integer)
++ uint32_t GfxGpoSpare[8];
+
+ // GFX DCS
+
+@@ -1114,12 +1153,14 @@ typedef struct {
+ uint16_t IntakeTempHighIntakeAcousticLimit;
+ uint16_t IntakeTempAcouticLimitReleaseRate;
+
+- uint16_t FanStalledTempLimitOffset;
++ int16_t FanAbnormalTempLimitOffset;
+ uint16_t FanStalledTriggerRpm;
+- uint16_t FanAbnormalTriggerRpm;
+- uint16_t FanPadding;
++ uint16_t FanAbnormalTriggerRpmCoeff;
++ uint16_t FanAbnormalDetectionEnable;
+
+- uint32_t FanSpare[14];
++ uint8_t FanIntakeSensorSupport;
++ uint8_t FanIntakePadding[3];
++ uint32_t FanSpare[13];
+
+ // SECTION: VDD_GFX AVFS
+
+@@ -1198,8 +1239,13 @@ typedef struct {
+ int16_t TotalBoardPowerM;
+ int16_t TotalBoardPowerB;
+
++ //PMFW-11158
++ QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
++
+ // SECTION: Sku Reserved
+- uint32_t Spare[61];
++ uint32_t Spare[43];
+
+ // Padding for MMHUB - do not modify this
+ uint32_t MmHubPadding[8];
+@@ -1288,8 +1334,11 @@ typedef struct {
+ uint32_t PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued
+ uint32_t BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS
+
++ uint8_t FuseWritePowerMuxPresent;
++ uint8_t FuseWritePadding[3];
++
+ // SECTION: Board Reserved
+- uint32_t BoardSpare[64];
++ uint32_t BoardSpare[63];
+
+ // SECTION: Structure Padding
+
+@@ -1381,7 +1430,7 @@ typedef struct {
+ uint16_t AverageTotalBoardPower;
+
+ uint16_t AvgTemperature[TEMP_COUNT];
+- uint16_t TempPadding;
++ uint16_t AvgTemperatureFanIntake;
+
+ uint8_t PcieRate ;
+ uint8_t PcieWidth ;
+@@ -1550,5 +1599,7 @@ typedef struct {
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
+ #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
++#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
++#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
+index 25c08f963f499..d6b13933a98fb 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
+@@ -25,10 +25,10 @@
+
+ // *** IMPORTANT ***
+ // PMFW TEAM: Always increment the interface version on any change to this file
+-#define SMU13_DRIVER_IF_VERSION 0x2C
++#define SMU13_DRIVER_IF_VERSION 0x35
+
+ //Increment this version if SkuTable_t or BoardTable_t change
+-#define PPTABLE_VERSION 0x20
++#define PPTABLE_VERSION 0x27
+
+ #define NUM_GFXCLK_DPM_LEVELS 16
+ #define NUM_SOCCLK_DPM_LEVELS 8
+@@ -96,7 +96,7 @@
+ #define FEATURE_MEM_TEMP_READ_BIT 47
+ #define FEATURE_ATHUB_MMHUB_PG_BIT 48
+ #define FEATURE_SOC_PCC_BIT 49
+-#define FEATURE_SPARE_50_BIT 50
++#define FEATURE_EDC_PWRBRK_BIT 50
+ #define FEATURE_SPARE_51_BIT 51
+ #define FEATURE_SPARE_52_BIT 52
+ #define FEATURE_SPARE_53_BIT 53
+@@ -282,15 +282,15 @@ typedef enum {
+ } I2cControllerPort_e;
+
+ typedef enum {
+- I2C_CONTROLLER_NAME_VR_GFX = 0,
+- I2C_CONTROLLER_NAME_VR_SOC,
+- I2C_CONTROLLER_NAME_VR_VMEMP,
+- I2C_CONTROLLER_NAME_VR_VDDIO,
+- I2C_CONTROLLER_NAME_LIQUID0,
+- I2C_CONTROLLER_NAME_LIQUID1,
+- I2C_CONTROLLER_NAME_PLX,
+- I2C_CONTROLLER_NAME_OTHER,
+- I2C_CONTROLLER_NAME_COUNT,
++ I2C_CONTROLLER_NAME_VR_GFX = 0,
++ I2C_CONTROLLER_NAME_VR_SOC,
++ I2C_CONTROLLER_NAME_VR_VMEMP,
++ I2C_CONTROLLER_NAME_VR_VDDIO,
++ I2C_CONTROLLER_NAME_LIQUID0,
++ I2C_CONTROLLER_NAME_LIQUID1,
++ I2C_CONTROLLER_NAME_PLX,
++ I2C_CONTROLLER_NAME_FAN_INTAKE,
++ I2C_CONTROLLER_NAME_COUNT,
+ } I2cControllerName_e;
+
+ typedef enum {
+@@ -302,6 +302,7 @@ typedef enum {
+ I2C_CONTROLLER_THROTTLER_LIQUID0,
+ I2C_CONTROLLER_THROTTLER_LIQUID1,
+ I2C_CONTROLLER_THROTTLER_PLX,
++ I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
+ I2C_CONTROLLER_THROTTLER_INA3221,
+ I2C_CONTROLLER_THROTTLER_COUNT,
+ } I2cControllerThrottler_e;
+@@ -309,8 +310,9 @@ typedef enum {
+ typedef enum {
+ I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
+ I2C_CONTROLLER_PROTOCOL_VR_IR35217,
+- I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
+ I2C_CONTROLLER_PROTOCOL_INA3221,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX6604,
+ I2C_CONTROLLER_PROTOCOL_COUNT,
+ } I2cControllerProtocol_e;
+
+@@ -690,6 +692,9 @@ typedef struct {
+ #define PP_OD_FEATURE_UCLK_BIT 8
+ #define PP_OD_FEATURE_ZERO_FAN_BIT 9
+ #define PP_OD_FEATURE_TEMPERATURE_BIT 10
++#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11
++#define PP_OD_FEATURE_ASIC_TDC_BIT 12
++#define PP_OD_FEATURE_COUNT 13
+
+ typedef enum {
+ PP_OD_POWER_FEATURE_ALWAYS_ENABLED,
+@@ -697,6 +702,11 @@ typedef enum {
+ PP_OD_POWER_FEATURE_ALWAYS_DISABLED,
+ } PP_OD_POWER_FEATURE_e;
+
++typedef enum {
++ FAN_MODE_AUTO = 0,
++ FAN_MODE_MANUAL_LINEAR,
++} FanMode_e;
++
+ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+@@ -708,8 +718,8 @@ typedef struct {
+ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+ //Frequency changes
+- int16_t GfxclkFmin; // MHz
+- int16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+@@ -730,7 +740,12 @@ typedef struct {
+ uint8_t MaxOpTemp;
+ uint8_t Padding[4];
+
+- uint32_t Spare[12];
++ uint16_t GfxVoltageFullCtrlMode;
++ uint16_t GfxclkFullCtrlMode;
++ uint16_t UclkFullCtrlMode;
++ int16_t AsicTdc;
++
++ uint32_t Spare[10];
+ uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround
+ } OverDriveTable_t;
+
+@@ -748,8 +763,8 @@ typedef struct {
+ uint8_t IdlePwrSavingFeaturesCtrl;
+ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+- uint16_t GfxclkFmin; // MHz
+- uint16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+@@ -769,7 +784,12 @@ typedef struct {
+ uint8_t MaxOpTemp;
+ uint8_t Padding[4];
+
+- uint32_t Spare[12];
++ uint16_t GfxVoltageFullCtrlMode;
++ uint16_t GfxclkFullCtrlMode;
++ uint16_t UclkFullCtrlMode;
++ int16_t AsicTdc;
++
++ uint32_t Spare[10];
+
+ } OverDriveLimits_t;
+
+@@ -903,7 +923,8 @@ typedef struct {
+ uint16_t FanStartTempMin;
+ uint16_t FanStartTempMax;
+
+- uint32_t Spare[12];
++ uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
++ uint32_t Spare[11];
+
+ } MsgLimits_t;
+
+@@ -1086,11 +1107,13 @@ typedef struct {
+ uint32_t GfxoffSpare[15];
+
+ // GFX GPO
+- float DfllBtcMasterScalerM;
++ uint32_t DfllBtcMasterScalerM;
+ int32_t DfllBtcMasterScalerB;
+- float DfllBtcSlaveScalerM;
++ uint32_t DfllBtcSlaveScalerM;
+ int32_t DfllBtcSlaveScalerB;
+- uint32_t GfxGpoSpare[12];
++ uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
++ uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
++ uint32_t GfxGpoSpare[10];
+
+ // GFX DCS
+
+@@ -1106,7 +1129,10 @@ typedef struct {
+ uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin.
+
+
+- uint32_t DcsSpare[16];
++ uint32_t DcsSpare[14];
++
++ // UCLK section
++ uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz
+
+ // UCLK section
+ uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations
+@@ -1163,13 +1189,14 @@ typedef struct {
+ uint16_t IntakeTempHighIntakeAcousticLimit;
+ uint16_t IntakeTempAcouticLimitReleaseRate;
+
+- uint16_t FanStalledTempLimitOffset;
++ int16_t FanAbnormalTempLimitOffset;
+ uint16_t FanStalledTriggerRpm;
+- uint16_t FanAbnormalTriggerRpm;
+- uint16_t FanPadding;
+-
+- uint32_t FanSpare[14];
++ uint16_t FanAbnormalTriggerRpmCoeff;
++ uint16_t FanAbnormalDetectionEnable;
+
++ uint8_t FanIntakeSensorSupport;
++ uint8_t FanIntakePadding[3];
++ uint32_t FanSpare[13];
+ // SECTION: VDD_GFX AVFS
+
+ uint8_t OverrideGfxAvfsFuses;
+@@ -1193,7 +1220,6 @@ typedef struct {
+ uint32_t dGbV_dT_vmin;
+ uint32_t dGbV_dT_vmax;
+
+- //Unused: PMFW-9370
+ uint32_t V2F_vmin_range_low;
+ uint32_t V2F_vmin_range_high;
+ uint32_t V2F_vmax_range_low;
+@@ -1238,8 +1264,21 @@ typedef struct {
+ // SECTION: Advanced Options
+ uint32_t DebugOverrides;
+
++ // Section: Total Board Power idle vs active coefficients
++ uint8_t TotalBoardPowerSupport;
++ uint8_t TotalBoardPowerPadding[3];
++
++ int16_t TotalIdleBoardPowerM;
++ int16_t TotalIdleBoardPowerB;
++ int16_t TotalBoardPowerM;
++ int16_t TotalBoardPowerB;
++
++ QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
++
+ // SECTION: Sku Reserved
+- uint32_t Spare[64];
++ uint32_t Spare[43];
+
+ // Padding for MMHUB - do not modify this
+ uint32_t MmHubPadding[8];
+@@ -1304,7 +1343,8 @@ typedef struct {
+ // SECTION: Clock Spread Spectrum
+
+ // UCLK Spread Spectrum
+- uint16_t UclkSpreadPadding;
++ uint8_t UclkTrainingModeSpreadPercent; // Q4.4
++ uint8_t UclkSpreadPadding;
+ uint16_t UclkSpreadFreq; // kHz
+
+ // UCLK Spread Spectrum
+@@ -1317,11 +1357,7 @@ typedef struct {
+
+ // Section: Memory Config
+ uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e
+- uint8_t PaddingMem1[3];
+-
+- // Section: Total Board Power
+- uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power
+- uint16_t BoardPowerPadding;
++ uint8_t PaddingMem1[7];
+
+ // SECTION: UMC feature flags
+ uint8_t HsrEnabled;
+@@ -1423,8 +1459,11 @@ typedef struct {
+ uint16_t Vcn1ActivityPercentage ;
+
+ uint32_t EnergyAccumulator;
+- uint16_t AverageSocketPower ;
++ uint16_t AverageSocketPower;
++ uint16_t AverageTotalBoardPower;
++
+ uint16_t AvgTemperature[TEMP_COUNT];
++ uint16_t AvgTemperatureFanIntake;
+
+ uint8_t PcieRate ;
+ uint8_t PcieWidth ;
+@@ -1592,5 +1631,7 @@ typedef struct {
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
+ #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
++#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
++#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index 3e29fe4cc4ae4..865d6358918d2 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -30,8 +30,9 @@
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
+
+ #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 33710dcf1eb16..1983e0d29e9db 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -288,7 +288,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
+ break;
+ case IP_VERSION(13, 0, 0):
+- smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0;
++ case IP_VERSION(13, 0, 10):
++ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
+ break;
+ case IP_VERSION(13, 0, 7):
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_7;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
+index f158f6a08e757..4b347318847f5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt.c
+@@ -616,8 +616,13 @@ int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
+ return -EINTR;
+ }
+
+- return timeout ? timeout : intel_uc_wait_for_idle(>->uc,
+- remaining_timeout);
++ if (timeout)
++ return timeout;
++
++ if (remaining_timeout < 0)
++ remaining_timeout = 0;
++
++ return intel_uc_wait_for_idle(>->uc, remaining_timeout);
+ }
+
+ int intel_gt_init(struct intel_gt *gt)
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+index edb881d756309..1dfd01668c79c 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+@@ -199,7 +199,7 @@ out_active: spin_lock(&timelines->lock);
+ if (remaining_timeout)
+ *remaining_timeout = timeout;
+
+- return active_count ? timeout : 0;
++ return active_count ? timeout ?: -ETIME : 0;
+ }
+
+ static void retire_work_handler(struct work_struct *work)
+diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
+index 81e688975c6a7..a901e4e33d81d 100644
+--- a/drivers/hwmon/asus-ec-sensors.c
++++ b/drivers/hwmon/asus-ec-sensors.c
+@@ -938,6 +938,8 @@ static int asus_ec_probe(struct platform_device *pdev)
+ ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors);
+ ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors,
+ sizeof(struct ec_sensor), GFP_KERNEL);
++ if (!ec_data->sensors)
++ return -ENOMEM;
+
+ status = setup_lock_data(dev);
+ if (status) {
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index 8bf32c6c85d95..9bee4d33fbdf0 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -242,10 +242,13 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+ */
+ if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) {
+ for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) {
+- if (host_bridge->device == tjmax_pci_table[i].device)
++ if (host_bridge->device == tjmax_pci_table[i].device) {
++ pci_dev_put(host_bridge);
+ return tjmax_pci_table[i].tjmax;
++ }
+ }
+ }
++ pci_dev_put(host_bridge);
+
+ for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) {
+ if (strstr(c->x86_model_id, tjmax_table[i].id))
+@@ -533,6 +536,10 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
+ {
+ struct temp_data *tdata = pdata->core_data[indx];
+
++ /* if we errored on add then this is already gone */
++ if (!tdata)
++ return;
++
+ /* Remove the sysfs attributes */
+ sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group);
+
+diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c
+index 05f68e9c9477e..23b9f94fe0a9b 100644
+--- a/drivers/hwmon/i5500_temp.c
++++ b/drivers/hwmon/i5500_temp.c
+@@ -117,7 +117,7 @@ static int i5500_temp_probe(struct pci_dev *pdev,
+ u32 tstimer;
+ s8 tsfsc;
+
+- err = pci_enable_device(pdev);
++ err = pcim_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to enable device\n");
+ return err;
+diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
+index f6ec165c0fa8b..1837cccd993c8 100644
+--- a/drivers/hwmon/ibmpex.c
++++ b/drivers/hwmon/ibmpex.c
+@@ -502,6 +502,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
+ return;
+
+ out_register:
++ list_del(&data->list);
+ hwmon_device_unregister(data->hwmon_dev);
+ out_user:
+ ipmi_destroy_user(data->user);
+diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
+index 58d3828e2ec0c..14586b2fb17d1 100644
+--- a/drivers/hwmon/ina3221.c
++++ b/drivers/hwmon/ina3221.c
+@@ -228,7 +228,7 @@ static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
+ * Shunt Voltage Sum register has 14-bit value with 1-bit shift
+ * Other Shunt Voltage registers have 12 bits with 3-bit shift
+ */
+- if (reg == INA3221_SHUNT_SUM)
++ if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
+ *val = sign_extend32(regval >> 1, 14);
+ else
+ *val = sign_extend32(regval >> 3, 12);
+@@ -465,7 +465,7 @@ static int ina3221_write_curr(struct device *dev, u32 attr,
+ * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV
+ * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV
+ */
+- if (reg == INA3221_SHUNT_SUM)
++ if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
+ regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe;
+ else
+ regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8;
+diff --git a/drivers/hwmon/ltc2947-core.c b/drivers/hwmon/ltc2947-core.c
+index 5423466de697a..e918490f3ff75 100644
+--- a/drivers/hwmon/ltc2947-core.c
++++ b/drivers/hwmon/ltc2947-core.c
+@@ -396,7 +396,7 @@ static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val,
+ return ret;
+
+ /* in milidegrees celcius, temp is given by: */
+- *val = (__val * 204) + 550;
++ *val = (__val * 204) + 5500;
+
+ return 0;
+ }
+diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
+index 3082183bd66a4..fc70920c4ddab 100644
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -1132,7 +1132,8 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
+ int i, result;
+ unsigned int temp;
+ int block_data = msgs->flags & I2C_M_RECV_LEN;
+- int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
++ int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE &&
++ msgs->len >= DMA_THRESHOLD && !block_data;
+
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> write slave address: addr=0x%x\n",
+@@ -1298,7 +1299,8 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
+ result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
+ } else {
+ if (!atomic &&
+- i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
++ i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD &&
++ msgs[i].flags & I2C_M_DMA_SAFE)
+ result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
+ else
+ result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index 0c365b57d9572..83457359ec450 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -2393,8 +2393,17 @@ static struct platform_driver npcm_i2c_bus_driver = {
+
+ static int __init npcm_i2c_init(void)
+ {
++ int ret;
++
+ npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL);
+- return platform_driver_register(&npcm_i2c_bus_driver);
++
++ ret = platform_driver_register(&npcm_i2c_bus_driver);
++ if (ret) {
++ debugfs_remove_recursive(npcm_i2c_debugfs_dir);
++ return ret;
++ }
++
++ return 0;
+ }
+ module_init(npcm_i2c_init);
+
+diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
+index 84a77512614d9..8fce98bb77ff9 100644
+--- a/drivers/i2c/busses/i2c-qcom-geni.c
++++ b/drivers/i2c/busses/i2c-qcom-geni.c
+@@ -626,7 +626,6 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
+ dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
+ gi2c->cur->flags, gi2c->cur->addr);
+ gi2c->err = -ETIMEDOUT;
+- goto err;
+ }
+
+ if (gi2c->err) {
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index 91007558bcb26..2477ae860acfa 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -467,6 +467,7 @@ static int i2c_device_probe(struct device *dev)
+ {
+ struct i2c_client *client = i2c_verify_client(dev);
+ struct i2c_driver *driver;
++ bool do_power_on;
+ int status;
+
+ if (!client)
+@@ -541,8 +542,8 @@ static int i2c_device_probe(struct device *dev)
+ if (status < 0)
+ goto err_clear_wakeup_irq;
+
+- status = dev_pm_domain_attach(&client->dev,
+- !i2c_acpi_waive_d0_probe(dev));
++ do_power_on = !i2c_acpi_waive_d0_probe(dev);
++ status = dev_pm_domain_attach(&client->dev, do_power_on);
+ if (status)
+ goto err_clear_wakeup_irq;
+
+@@ -581,7 +582,7 @@ static int i2c_device_probe(struct device *dev)
+ err_release_driver_resources:
+ devres_release_group(&client->dev, client->devres_group_id);
+ err_detach_pm_domain:
+- dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
++ dev_pm_domain_detach(&client->dev, do_power_on);
+ err_clear_wakeup_irq:
+ dev_pm_clear_wake_irq(&client->dev);
+ device_init_wakeup(&client->dev, false);
+@@ -610,7 +611,7 @@ static void i2c_device_remove(struct device *dev)
+
+ devres_release_group(&client->dev, client->devres_group_id);
+
+- dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
++ dev_pm_domain_detach(&client->dev, true);
+
+ dev_pm_clear_wake_irq(&client->dev);
+ device_init_wakeup(&client->dev, false);
+diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c
+index 3bb4028c5d747..df3bc5c3d3786 100644
+--- a/drivers/iio/health/afe4403.c
++++ b/drivers/iio/health/afe4403.c
+@@ -245,14 +245,14 @@ static int afe4403_read_raw(struct iio_dev *indio_dev,
+ int *val, int *val2, long mask)
+ {
+ struct afe4403_data *afe = iio_priv(indio_dev);
+- unsigned int reg = afe4403_channel_values[chan->address];
+- unsigned int field = afe4403_channel_leds[chan->address];
++ unsigned int reg, field;
+ int ret;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ reg = afe4403_channel_values[chan->address];
+ ret = afe4403_read(afe, reg, val);
+ if (ret)
+ return ret;
+@@ -262,6 +262,7 @@ static int afe4403_read_raw(struct iio_dev *indio_dev,
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ field = afe4403_channel_leds[chan->address];
+ ret = regmap_field_read(afe->fields[field], val);
+ if (ret)
+ return ret;
+diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c
+index dd7800159051a..f03c466c93854 100644
+--- a/drivers/iio/health/afe4404.c
++++ b/drivers/iio/health/afe4404.c
+@@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
+ int *val, int *val2, long mask)
+ {
+ struct afe4404_data *afe = iio_priv(indio_dev);
+- unsigned int value_reg = afe4404_channel_values[chan->address];
+- unsigned int led_field = afe4404_channel_leds[chan->address];
+- unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
++ unsigned int value_reg, led_field, offdac_field;
+ int ret;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ value_reg = afe4404_channel_values[chan->address];
+ ret = regmap_read(afe->regmap, value_reg, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
++ offdac_field = afe4404_channel_offdacs[chan->address];
+ ret = regmap_field_read(afe->fields[offdac_field], val);
+ if (ret)
+ return ret;
+@@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ led_field = afe4404_channel_leds[chan->address];
+ ret = regmap_field_read(afe->fields[led_field], val);
+ if (ret)
+ return ret;
+@@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev,
+ int val, int val2, long mask)
+ {
+ struct afe4404_data *afe = iio_priv(indio_dev);
+- unsigned int led_field = afe4404_channel_leds[chan->address];
+- unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
++ unsigned int led_field, offdac_field;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_OFFSET:
++ offdac_field = afe4404_channel_offdacs[chan->address];
+ return regmap_field_write(afe->fields[offdac_field], val);
+ }
+ break;
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ led_field = afe4404_channel_leds[chan->address];
+ return regmap_field_write(afe->fields[led_field], val);
+ }
+ break;
+diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
+index 8537e88f02e31..c02393009a2cb 100644
+--- a/drivers/iio/light/Kconfig
++++ b/drivers/iio/light/Kconfig
+@@ -293,6 +293,8 @@ config RPR0521
+ tristate "ROHM RPR0521 ALS and proximity sensor driver"
+ depends on I2C
+ select REGMAP_I2C
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build support for ROHM's RPR0521
+ ambient light and proximity sensor device.
+diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
+index 3a4952935366f..3d9c5758d8a44 100644
+--- a/drivers/input/touchscreen/raydium_i2c_ts.c
++++ b/drivers/input/touchscreen/raydium_i2c_ts.c
+@@ -211,12 +211,14 @@ static int raydium_i2c_send(struct i2c_client *client,
+
+ error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer));
+ if (likely(!error))
+- return 0;
++ goto out;
+
+ msleep(RM_RETRY_DELAY_MS);
+ } while (++tries < RM_MAX_RETRIES);
+
+ dev_err(&client->dev, "%s failed: %d\n", __func__, error);
++out:
++ kfree(tx_buf);
+ return error;
+ }
+
+diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
+index 5a8f780e7ffd8..bc94059a5b870 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -820,6 +820,7 @@ int __init dmar_dev_scope_init(void)
+ info = dmar_alloc_pci_notify_info(dev,
+ BUS_NOTIFY_ADD_DEVICE);
+ if (!info) {
++ pci_dev_put(dev);
+ return dmar_dev_scope_status;
+ } else {
+ dmar_pci_bus_add_dev(info);
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index e47700674978c..412b106d2a398 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -3844,8 +3844,10 @@ static inline bool has_external_pci(void)
+ struct pci_dev *pdev = NULL;
+
+ for_each_pci_dev(pdev)
+- if (pdev->external_facing)
++ if (pdev->external_facing) {
++ pci_dev_put(pdev);
+ return true;
++ }
+
+ return false;
+ }
+diff --git a/drivers/media/common/videobuf2/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c
+index 542dde9d2609b..144027035892a 100644
+--- a/drivers/media/common/videobuf2/frame_vector.c
++++ b/drivers/media/common/videobuf2/frame_vector.c
+@@ -35,11 +35,7 @@
+ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ struct frame_vector *vec)
+ {
+- struct mm_struct *mm = current->mm;
+- struct vm_area_struct *vma;
+- int ret_pin_user_pages_fast = 0;
+- int ret = 0;
+- int err;
++ int ret;
+
+ if (nr_frames == 0)
+ return 0;
+@@ -52,57 +48,17 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ ret = pin_user_pages_fast(start, nr_frames,
+ FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM,
+ (struct page **)(vec->ptrs));
+- if (ret > 0) {
+- vec->got_ref = true;
+- vec->is_pfns = false;
+- goto out_unlocked;
+- }
+- ret_pin_user_pages_fast = ret;
+-
+- mmap_read_lock(mm);
+- vec->got_ref = false;
+- vec->is_pfns = true;
+- ret = 0;
+- do {
+- unsigned long *nums = frame_vector_pfns(vec);
+-
+- vma = vma_lookup(mm, start);
+- if (!vma)
+- break;
+-
+- while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
+- err = follow_pfn(vma, start, &nums[ret]);
+- if (err) {
+- if (ret)
+- goto out;
+- // If follow_pfn() returns -EINVAL, then this
+- // is not an IO mapping or a raw PFN mapping.
+- // In that case, return the original error from
+- // pin_user_pages_fast(). Otherwise this
+- // function would return -EINVAL when
+- // pin_user_pages_fast() returned -ENOMEM,
+- // which makes debugging hard.
+- if (err == -EINVAL && ret_pin_user_pages_fast)
+- ret = ret_pin_user_pages_fast;
+- else
+- ret = err;
+- goto out;
+- }
+- start += PAGE_SIZE;
+- ret++;
+- }
+- /* Bail out if VMA doesn't completely cover the tail page. */
+- if (start < vma->vm_end)
+- break;
+- } while (ret < nr_frames);
+-out:
+- mmap_read_unlock(mm);
+-out_unlocked:
+- if (!ret)
+- ret = -EFAULT;
+- if (ret > 0)
+- vec->nr_frames = ret;
+- return ret;
++ vec->got_ref = true;
++ vec->is_pfns = false;
++ vec->nr_frames = ret;
++
++ if (likely(ret > 0))
++ return ret;
++
++ /* This used to (racily) return non-refcounted pfns. Let people know */
++ WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping");
++ vec->nr_frames = 0;
++ return ret ? ret : -EFAULT;
+ }
+ EXPORT_SYMBOL(get_vaddr_frames);
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 3d96493257257..557a8f406726d 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1484,6 +1484,11 @@ void mmc_init_erase(struct mmc_card *card)
+ card->pref_erase = 0;
+ }
+
++static bool is_trim_arg(unsigned int arg)
++{
++ return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG;
++}
++
+ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
+ unsigned int arg, unsigned int qty)
+ {
+@@ -1766,7 +1771,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN))
+ return -EOPNOTSUPP;
+
+- if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) &&
++ if (mmc_card_mmc(card) && is_trim_arg(arg) &&
+ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN))
+ return -EOPNOTSUPP;
+
+@@ -1796,7 +1801,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+ * identified by the card->eg_boundary flag.
+ */
+ rem = card->erase_size - (from % card->erase_size);
+- if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) {
++ if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) {
+ err = mmc_do_erase(card, from, from + rem - 1, arg);
+ from += rem;
+ if ((err) || (to <= from))
+diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
+index 8d9bceeff9864..155ce2bdfe622 100644
+--- a/drivers/mmc/core/mmc_test.c
++++ b/drivers/mmc/core/mmc_test.c
+@@ -3179,7 +3179,8 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card,
+ struct mmc_test_dbgfs_file *df;
+
+ if (card->debugfs_root)
+- debugfs_create_file(name, mode, card->debugfs_root, card, fops);
++ file = debugfs_create_file(name, mode, card->debugfs_root,
++ card, fops);
+
+ df = kmalloc(sizeof(*df), GFP_KERNEL);
+ if (!df) {
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 69d78604d1fc3..1941ac3c141cf 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -2573,13 +2573,11 @@ static int msdc_of_clock_parse(struct platform_device *pdev,
+ return PTR_ERR(host->src_clk_cg);
+ }
+
+- host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
++ /* If present, always enable for this clock gate */
++ host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg");
+ if (IS_ERR(host->sys_clk_cg))
+ host->sys_clk_cg = NULL;
+
+- /* If present, always enable for this clock gate */
+- clk_prepare_enable(host->sys_clk_cg);
+-
+ host->bulk_clks[0].id = "pclk_cg";
+ host->bulk_clks[1].id = "axi_cg";
+ host->bulk_clks[2].id = "ahb_cg";
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 31ea0a2fce358..ffeb5759830ff 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1512,7 +1512,7 @@ static void esdhc_cqe_enable(struct mmc_host *mmc)
+ * system resume back.
+ */
+ cqhci_writel(cq_host, 0, CQHCI_CTL);
+- if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT)
++ if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT)
+ dev_err(mmc_dev(host->mmc),
+ "failed to exit halt state when enable CQE\n");
+
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 3b88c9d3ddf90..51cb8cfce3236 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -470,7 +470,7 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+ }
+
+ if (IS_ERR(sprd_host->pinctrl))
+- return 0;
++ goto reset;
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_180:
+@@ -498,6 +498,8 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+
+ /* Wait for 300 ~ 500 us for pin state stable */
+ usleep_range(300, 500);
++
++reset:
+ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ return 0;
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 251172890af79..3c52c87ada5d3 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -339,6 +339,7 @@ static void sdhci_init(struct sdhci_host *host, int soft)
+ if (soft) {
+ /* force clock reconfiguration */
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->set_ios(mmc, &mmc->ios);
+ }
+ }
+@@ -2258,11 +2259,46 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
+ }
+ EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
+
++static bool sdhci_timing_has_preset(unsigned char timing)
++{
++ switch (timing) {
++ case MMC_TIMING_UHS_SDR12:
++ case MMC_TIMING_UHS_SDR25:
++ case MMC_TIMING_UHS_SDR50:
++ case MMC_TIMING_UHS_SDR104:
++ case MMC_TIMING_UHS_DDR50:
++ case MMC_TIMING_MMC_DDR52:
++ return true;
++ };
++ return false;
++}
++
++static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing)
++{
++ return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
++ sdhci_timing_has_preset(timing);
++}
++
++static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios)
++{
++ /*
++ * Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK
++ * Frequency. Check if preset values need to be enabled, or the Driver
++ * Strength needs updating. Note, clock changes are handled separately.
++ */
++ return !host->preset_enabled &&
++ (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type);
++}
++
+ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct sdhci_host *host = mmc_priv(mmc);
++ bool reinit_uhs = host->reinit_uhs;
++ bool turning_on_clk = false;
+ u8 ctrl;
+
++ host->reinit_uhs = false;
++
+ if (ios->power_mode == MMC_POWER_UNDEFINED)
+ return;
+
+@@ -2288,6 +2324,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ sdhci_enable_preset_value(host, false);
+
+ if (!ios->clock || ios->clock != host->clock) {
++ turning_on_clk = ios->clock && !host->clock;
++
+ host->ops->set_clock(host, ios->clock);
+ host->clock = ios->clock;
+
+@@ -2314,6 +2352,17 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+
+ host->ops->set_bus_width(host, ios->bus_width);
+
++ /*
++ * Special case to avoid multiple clock changes during voltage
++ * switching.
++ */
++ if (!reinit_uhs &&
++ turning_on_clk &&
++ host->timing == ios->timing &&
++ host->version >= SDHCI_SPEC_300 &&
++ !sdhci_presetable_values_change(host, ios))
++ return;
++
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+
+ if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
+@@ -2357,6 +2406,7 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ }
+
+ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
++ host->drv_type = ios->drv_type;
+ } else {
+ /*
+ * According to SDHC Spec v3.00, if the Preset Value
+@@ -2384,19 +2434,14 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ host->ops->set_uhs_signaling(host, ios->timing);
+ host->timing = ios->timing;
+
+- if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
+- ((ios->timing == MMC_TIMING_UHS_SDR12) ||
+- (ios->timing == MMC_TIMING_UHS_SDR25) ||
+- (ios->timing == MMC_TIMING_UHS_SDR50) ||
+- (ios->timing == MMC_TIMING_UHS_SDR104) ||
+- (ios->timing == MMC_TIMING_UHS_DDR50) ||
+- (ios->timing == MMC_TIMING_MMC_DDR52))) {
++ if (sdhci_preset_needed(host, ios->timing)) {
+ u16 preset;
+
+ sdhci_enable_preset_value(host, true);
+ preset = sdhci_get_preset_value(host);
+ ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK,
+ preset);
++ host->drv_type = ios->drv_type;
+ }
+
+ /* Re-enable SD Clock */
+@@ -3748,6 +3793,7 @@ int sdhci_resume_host(struct sdhci_host *host)
+ sdhci_init(host, 0);
+ host->pwr = 0;
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->set_ios(mmc, &mmc->ios);
+ } else {
+ sdhci_init(host, (mmc->pm_flags & MMC_PM_KEEP_POWER));
+@@ -3810,6 +3856,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
+ /* Force clock and power re-program */
+ host->pwr = 0;
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
+ mmc->ops->set_ios(mmc, &mmc->ios);
+
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 95a08f09df30e..cf900cc93e91a 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -526,6 +526,8 @@ struct sdhci_host {
+
+ unsigned int clock; /* Current clock (MHz) */
+ u8 pwr; /* Current voltage */
++ u8 drv_type; /* Current UHS-I driver type */
++ bool reinit_uhs; /* Force UHS-related re-initialization */
+
+ bool runtime_suspended; /* Host is runtime suspended */
+ bool bus_on; /* Bus power prevents runtime suspend */
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index 0941977807761..ed3d0b8989a07 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -263,8 +263,10 @@ static void can327_feed_frame_to_netdev(struct can327 *elm, struct sk_buff *skb)
+ {
+ lockdep_assert_held(&elm->lock);
+
+- if (!netif_running(elm->dev))
++ if (!netif_running(elm->dev)) {
++ kfree_skb(skb);
+ return;
++ }
+
+ /* Queue for NAPI pickup.
+ * rx-offload will update stats and LEDs for us.
+diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
+index 194c86e0f340f..8f6dccd5a5879 100644
+--- a/drivers/net/can/cc770/cc770_isa.c
++++ b/drivers/net/can/cc770/cc770_isa.c
+@@ -264,22 +264,24 @@ static int cc770_isa_probe(struct platform_device *pdev)
+ if (err) {
+ dev_err(&pdev->dev,
+ "couldn't register device (err=%d)\n", err);
+- goto exit_unmap;
++ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n",
+ priv->reg_base, dev->irq);
+ return 0;
+
+- exit_unmap:
++exit_free:
++ free_cc770dev(dev);
++exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+- exit_release:
++exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+- exit:
++exit:
+ return err;
+ }
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 4dc67fdfcdb9d..153d8fd08bd88 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1910,7 +1910,7 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev)
+ cdev->hclk = devm_clk_get(cdev->dev, "hclk");
+ cdev->cclk = devm_clk_get(cdev->dev, "cclk");
+
+- if (IS_ERR(cdev->cclk)) {
++ if (IS_ERR(cdev->hclk) || IS_ERR(cdev->cclk)) {
+ dev_err(cdev->dev, "no clock found\n");
+ ret = -ENODEV;
+ }
+diff --git a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
+index 8f184a852a0a7..f2219aa2824b3 100644
+--- a/drivers/net/can/m_can/m_can_pci.c
++++ b/drivers/net/can/m_can/m_can_pci.c
+@@ -120,7 +120,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+- return ret;
++ goto err_free_dev;
+
+ mcan_class->dev = &pci->dev;
+ mcan_class->net->irq = pci_irq_vector(pci, 0);
+@@ -132,7 +132,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ ret = m_can_class_register(mcan_class);
+ if (ret)
+- goto err;
++ goto err_free_irq;
+
+ /* Enable interrupt control at CAN wrapper IP */
+ writel(0x1, base + CTL_CSR_INT_CTL_OFFSET);
+@@ -144,8 +144,10 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ return 0;
+
+-err:
++err_free_irq:
+ pci_free_irq_vectors(pci);
++err_free_dev:
++ m_can_class_free_dev(mcan_class->net);
+ return ret;
+ }
+
+@@ -161,6 +163,7 @@ static void m_can_pci_remove(struct pci_dev *pci)
+ writel(0x0, priv->base + CTL_CSR_INT_CTL_OFFSET);
+
+ m_can_class_unregister(mcan_class);
++ m_can_class_free_dev(mcan_class->net);
+ pci_free_irq_vectors(pci);
+ }
+
+diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c
+index d513fac507185..db3e767d5320f 100644
+--- a/drivers/net/can/sja1000/sja1000_isa.c
++++ b/drivers/net/can/sja1000/sja1000_isa.c
+@@ -202,22 +202,24 @@ static int sja1000_isa_probe(struct platform_device *pdev)
+ if (err) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+- goto exit_unmap;
++ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
+ DRV_NAME, priv->reg_base, dev->irq);
+ return 0;
+
+- exit_unmap:
++exit_free:
++ free_sja1000dev(dev);
++exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+- exit_release:
++exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+- exit:
++exit:
+ return err;
+ }
+
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 25f863b4f5f06..ddb7c5735c9ac 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -2091,8 +2091,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
+ netdev->dev_port = channel_idx;
+
+ ret = register_candev(netdev);
+- if (ret)
++ if (ret) {
++ es58x_dev->netdev[channel_idx] = NULL;
++ free_candev(netdev);
+ return ret;
++ }
+
+ netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0),
+ es58x_dev->param->dql_min_limit);
+diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
+index e03ff1f267bba..1de62604434d8 100644
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -959,7 +959,7 @@ static const struct lan9303_mib_desc lan9303_mib[] = {
+ { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", },
+ { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", },
+ { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", },
+- { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", },
++ { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "RxShort", },
+ { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", },
+ { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", },
+ { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", },
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+index 1daecd483b8d6..9c1378c22a8ed 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+@@ -13,6 +13,7 @@
+ #include "aq_ptp.h"
+ #include "aq_filters.h"
+ #include "aq_macsec.h"
++#include "aq_main.h"
+
+ #include <linux/ptp_clock_kernel.h>
+
+@@ -858,7 +859,7 @@ static int aq_set_ringparam(struct net_device *ndev,
+
+ if (netif_running(ndev)) {
+ ndev_running = true;
+- dev_close(ndev);
++ aq_ndev_close(ndev);
+ }
+
+ cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
+@@ -874,7 +875,7 @@ static int aq_set_ringparam(struct net_device *ndev,
+ goto err_exit;
+
+ if (ndev_running)
+- err = dev_open(ndev, NULL);
++ err = aq_ndev_open(ndev);
+
+ err_exit:
+ return err;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+index 8a0af371e7dc7..77609dc0a08d6 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+@@ -58,7 +58,7 @@ struct net_device *aq_ndev_alloc(void)
+ return ndev;
+ }
+
+-static int aq_ndev_open(struct net_device *ndev)
++int aq_ndev_open(struct net_device *ndev)
+ {
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+ int err = 0;
+@@ -88,7 +88,7 @@ err_exit:
+ return err;
+ }
+
+-static int aq_ndev_close(struct net_device *ndev)
++int aq_ndev_close(struct net_device *ndev)
+ {
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+ int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.h b/drivers/net/ethernet/aquantia/atlantic/aq_main.h
+index 99870865f66db..a78c1a168d8ef 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.h
+@@ -16,5 +16,7 @@ DECLARE_STATIC_KEY_FALSE(aq_xdp_locking_key);
+
+ void aq_ndev_schedule_work(struct work_struct *work);
+ struct net_device *aq_ndev_alloc(void);
++int aq_ndev_open(struct net_device *ndev);
++int aq_ndev_close(struct net_device *ndev);
+
+ #endif /* AQ_MAIN_H */
+diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
+index 11a884aa5082c..90a2ba20e902b 100644
+--- a/drivers/net/ethernet/intel/e100.c
++++ b/drivers/net/ethernet/intel/e100.c
+@@ -1741,11 +1741,8 @@ static int e100_xmit_prepare(struct nic *nic, struct cb *cb,
+ dma_addr = dma_map_single(&nic->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ /* If we can't map the skb, have the upper layer try later */
+- if (dma_mapping_error(&nic->pdev->dev, dma_addr)) {
+- dev_kfree_skb_any(skb);
+- skb = NULL;
++ if (dma_mapping_error(&nic->pdev->dev, dma_addr))
+ return -ENOMEM;
+- }
+
+ /*
+ * Use the last 4 bytes of the SKB payload packet as the CRC, used for
+diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+index 3362f26d7f999..1b273446621c5 100644
+--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+@@ -32,6 +32,8 @@ struct workqueue_struct *fm10k_workqueue;
+ **/
+ static int __init fm10k_init_module(void)
+ {
++ int ret;
++
+ pr_info("%s\n", fm10k_driver_string);
+ pr_info("%s\n", fm10k_copyright);
+
+@@ -43,7 +45,13 @@ static int __init fm10k_init_module(void)
+
+ fm10k_dbg_init();
+
+- return fm10k_register_pci_driver();
++ ret = fm10k_register_pci_driver();
++ if (ret) {
++ fm10k_dbg_exit();
++ destroy_workqueue(fm10k_workqueue);
++ }
++
++ return ret;
+ }
+ module_init(fm10k_init_module);
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index b3336d31f8a9d..023685cca2c1c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -16652,6 +16652,8 @@ static struct pci_driver i40e_driver = {
+ **/
+ static int __init i40e_init_module(void)
+ {
++ int err;
++
+ pr_info("%s: %s\n", i40e_driver_name, i40e_driver_string);
+ pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
+
+@@ -16669,7 +16671,14 @@ static int __init i40e_init_module(void)
+ }
+
+ i40e_dbg_init();
+- return pci_register_driver(&i40e_driver);
++ err = pci_register_driver(&i40e_driver);
++ if (err) {
++ destroy_workqueue(i40e_wq);
++ i40e_dbg_exit();
++ return err;
++ }
++
++ return 0;
+ }
+ module_init(i40e_init_module);
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index cff03723f4f9f..4e03712726f2f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -5196,6 +5196,8 @@ static struct pci_driver iavf_driver = {
+ **/
+ static int __init iavf_init_module(void)
+ {
++ int ret;
++
+ pr_info("iavf: %s\n", iavf_driver_string);
+
+ pr_info("%s\n", iavf_copyright);
+@@ -5206,7 +5208,12 @@ static int __init iavf_init_module(void)
+ pr_err("%s: Failed to create workqueue\n", iavf_driver_name);
+ return -ENOMEM;
+ }
+- return pci_register_driver(&iavf_driver);
++
++ ret = pci_register_driver(&iavf_driver);
++ if (ret)
++ destroy_workqueue(iavf_wq);
++
++ return ret;
+ }
+
+ module_init(iavf_init_module);
+diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+index 2f12fbe229c15..624b8aa4508c6 100644
+--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+@@ -4869,6 +4869,8 @@ static struct pci_driver ixgbevf_driver = {
+ **/
+ static int __init ixgbevf_init_module(void)
+ {
++ int err;
++
+ pr_info("%s\n", ixgbevf_driver_string);
+ pr_info("%s\n", ixgbevf_copyright);
+ ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name);
+@@ -4877,7 +4879,13 @@ static int __init ixgbevf_init_module(void)
+ return -ENOMEM;
+ }
+
+- return pci_register_driver(&ixgbevf_driver);
++ err = pci_register_driver(&ixgbevf_driver);
++ if (err) {
++ destroy_workqueue(ixgbevf_wq);
++ return err;
++ }
++
++ return 0;
+ }
+
+ module_init(ixgbevf_init_module);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 74bd05e5dda23..e7a894ba5c3ea 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -1497,8 +1497,8 @@ static ssize_t outlen_write(struct file *filp, const char __user *buf,
+ return -EFAULT;
+
+ err = sscanf(outlen_str, "%d", &outlen);
+- if (err < 0)
+- return err;
++ if (err != 1)
++ return -EINVAL;
+
+ ptr = kzalloc(outlen, GFP_KERNEL);
+ if (!ptr)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 4d8b8f6143cc9..59cffa49e4b58 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -1363,6 +1363,9 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
+ esw_offloads_del_send_to_vport_meta_rules(esw);
+ devl_rate_nodes_destroy(devlink);
+ }
++ /* Destroy legacy fdb when disabling sriov in legacy mode. */
++ if (esw->mode == MLX5_ESWITCH_LEGACY)
++ mlx5_eswitch_disable_locked(esw);
+
+ esw->esw_funcs.num_vfs = 0;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 87ce5a208cb52..5ceed4e6c6581 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -731,6 +731,14 @@ void mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
+ struct mlx5_eswitch *slave_esw);
+ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
+
++static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
++{
++ if (mlx5_esw_allowed(esw))
++ return esw->esw_funcs.num_vfs;
++
++ return 0;
++}
++
+ #else /* CONFIG_MLX5_ESWITCH */
+ /* eswitch API stubs */
+ static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 061ac87993546..11cb7d28e1f89 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -3270,6 +3270,13 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,
+ int err;
+
+ esw->mode = MLX5_ESWITCH_LEGACY;
++
++ /* If changing from switchdev to legacy mode without sriov enabled,
++ * no need to create legacy fdb.
++ */
++ if (!mlx5_sriov_is_enabled(esw->dev))
++ return 0;
++
+ err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+index 108a3503f413c..edd9102583144 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+@@ -312,6 +312,8 @@ revert_changes:
+ for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) {
+ struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl;
+
++ attr->dests[curr_dest].termtbl = NULL;
++
+ /* search for the destination associated with the
+ * current term table
+ */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 065102278cb80..48f86e12f5c05 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -648,10 +648,13 @@ static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
+ return false;
+
+ #ifdef CONFIG_MLX5_ESWITCH
+- dev = ldev->pf[MLX5_LAG_P1].dev;
+- if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev))
+- return false;
++ for (i = 0; i < ldev->ports; i++) {
++ dev = ldev->pf[i].dev;
++ if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
++ return false;
++ }
+
++ dev = ldev->pf[MLX5_LAG_P1].dev;
+ mode = mlx5_eswitch_mode(dev);
+ for (i = 0; i < ldev->ports; i++)
+ if (mlx5_eswitch_mode(ldev->pf[i].dev) != mode)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
+index 31d443dd83862..f68461b133912 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
+@@ -46,7 +46,7 @@ static int dr_table_set_miss_action_nic(struct mlx5dr_domain *dmn,
+ int mlx5dr_table_set_miss_action(struct mlx5dr_table *tbl,
+ struct mlx5dr_action *action)
+ {
+- int ret;
++ int ret = -EOPNOTSUPP;
+
+ if (action && action->action_type != DR_ACTION_TYP_FT)
+ return -EOPNOTSUPP;
+@@ -67,6 +67,9 @@ int mlx5dr_table_set_miss_action(struct mlx5dr_table *tbl,
+ goto out;
+ }
+
++ if (ret)
++ goto out;
++
+ /* Release old action */
+ if (tbl->miss_action)
+ refcount_dec(&tbl->miss_action->refcount);
+diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
+index 4fc279a175629..bef3f05064876 100644
+--- a/drivers/net/ethernet/ni/nixge.c
++++ b/drivers/net/ethernet/ni/nixge.c
+@@ -249,25 +249,26 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev)
+ struct sk_buff *skb;
+ int i;
+
+- for (i = 0; i < RX_BD_NUM; i++) {
+- phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+- phys);
+-
+- dma_unmap_single(ndev->dev.parent, phys_addr,
+- NIXGE_MAX_JUMBO_FRAME_SIZE,
+- DMA_FROM_DEVICE);
+-
+- skb = (struct sk_buff *)(uintptr_t)
+- nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+- sw_id_offset);
+- dev_kfree_skb(skb);
+- }
++ if (priv->rx_bd_v) {
++ for (i = 0; i < RX_BD_NUM; i++) {
++ phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
++ phys);
++
++ dma_unmap_single(ndev->dev.parent, phys_addr,
++ NIXGE_MAX_JUMBO_FRAME_SIZE,
++ DMA_FROM_DEVICE);
++
++ skb = (struct sk_buff *)(uintptr_t)
++ nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
++ sw_id_offset);
++ dev_kfree_skb(skb);
++ }
+
+- if (priv->rx_bd_v)
+ dma_free_coherent(ndev->dev.parent,
+ sizeof(*priv->rx_bd_v) * RX_BD_NUM,
+ priv->rx_bd_v,
+ priv->rx_bd_p);
++ }
+
+ if (priv->tx_skb)
+ devm_kfree(ndev->dev.parent, priv->tx_skb);
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+index bd06076803295..2fd5c6fdb5003 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+@@ -2991,7 +2991,7 @@ static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
+ QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
+ dev_info(&adapter->pdev->dev,
+ "%s: lock recovery initiated\n", __func__);
+- msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
++ mdelay(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
+ val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
+ id = ((val >> 2) & 0xF);
+ if (id == adapter->portnum) {
+@@ -3027,7 +3027,7 @@ int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
+ if (status)
+ break;
+
+- msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
++ mdelay(QLC_83XX_DRV_LOCK_WAIT_DELAY);
+ i++;
+
+ if (i == 1)
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 7e32b04eb0c75..44f9b31f8b99b 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -3013,6 +3013,7 @@ static int __maybe_unused ravb_resume(struct device *dev)
+ ret = ravb_open(ndev);
+ if (ret < 0)
+ return ret;
++ ravb_set_rx_mode(ndev);
+ netif_device_attach(ndev);
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index d8f1fbc25bdd3..3d171cbc31b6e 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -749,6 +749,8 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
+ if (fc & FLOW_RX) {
+ pr_debug("\tReceive Flow-Control ON\n");
+ flow |= GMAC_RX_FLOW_CTRL_RFE;
++ } else {
++ pr_debug("\tReceive Flow-Control OFF\n");
+ }
+ writel(flow, ioaddr + GMAC_RX_FLOW_CTRL);
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 02827829463f6..0f080bfe8b176 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1061,8 +1061,16 @@ static void stmmac_mac_link_up(struct phylink_config *config,
+ ctrl |= priv->hw->link.duplex;
+
+ /* Flow Control operation */
+- if (tx_pause && rx_pause)
+- stmmac_mac_flow_ctrl(priv, duplex);
++ if (rx_pause && tx_pause)
++ priv->flow_ctrl = FLOW_AUTO;
++ else if (rx_pause && !tx_pause)
++ priv->flow_ctrl = FLOW_RX;
++ else if (!rx_pause && tx_pause)
++ priv->flow_ctrl = FLOW_TX;
++ else
++ priv->flow_ctrl = FLOW_OFF;
++
++ stmmac_mac_flow_ctrl(priv, duplex);
+
+ if (ctrl != old_ctrl)
+ writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 348201e10d497..95baacd6c7610 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -2061,7 +2061,7 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common)
+
+ for (i = 0; i < common->port_num; i++) {
+ port = &common->ports[i];
+- if (port->ndev)
++ if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(port->ndev);
+ }
+ }
+diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
+index 1c1584fca6327..40e745a1d1854 100644
+--- a/drivers/net/mdio/fwnode_mdio.c
++++ b/drivers/net/mdio/fwnode_mdio.c
+@@ -120,7 +120,7 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ /* Associate the fwnode with the device structure so it
+ * can be looked up later.
+ */
+- phy->mdio.dev.fwnode = child;
++ phy->mdio.dev.fwnode = fwnode_handle_get(child);
+
+ /* All data is now stored in the phy struct, so register it */
+ rc = phy_device_register(phy);
+diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
+index 80bdc07f2cd33..dd7e273c90cbd 100644
+--- a/drivers/net/ntb_netdev.c
++++ b/drivers/net/ntb_netdev.c
+@@ -484,7 +484,14 @@ static int __init ntb_netdev_init_module(void)
+ rc = ntb_transport_register_client_dev(KBUILD_MODNAME);
+ if (rc)
+ return rc;
+- return ntb_transport_register_client(&ntb_netdev_client);
++
++ rc = ntb_transport_register_client(&ntb_netdev_client);
++ if (rc) {
++ ntb_transport_unregister_client_dev(KBUILD_MODNAME);
++ return rc;
++ }
++
++ return 0;
+ }
+ module_init(ntb_netdev_init_module);
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 4df8c337221bd..3607077cf86f8 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -216,6 +216,7 @@ static void phy_mdio_device_free(struct mdio_device *mdiodev)
+
+ static void phy_device_release(struct device *dev)
+ {
++ fwnode_handle_put(dev->fwnode);
+ kfree(to_phy_device(dev));
+ }
+
+@@ -1518,6 +1519,7 @@ error:
+
+ error_module_put:
+ module_put(d->driver->owner);
++ d->driver = NULL;
+ error_put_device:
+ put_device(d);
+ if (ndev_owner != bus->owner)
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 3387074a2bdb8..167e6a3784ca1 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -686,7 +686,6 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
+ if (tun)
+ xdp_rxq_info_unreg(&tfile->xdp_rxq);
+ ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free);
+- sock_put(&tfile->sk);
+ }
+ }
+
+@@ -702,6 +701,9 @@ static void tun_detach(struct tun_file *tfile, bool clean)
+ if (dev)
+ netdev_state_change(dev);
+ rtnl_unlock();
++
++ if (clean)
++ sock_put(&tfile->sk);
+ }
+
+ static void tun_detach_all(struct net_device *dev)
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+index d41e373f9c0ad..d6b166fc5c0ef 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+@@ -365,7 +365,8 @@ static void ipc_mux_dl_cmd_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
+ /* Pass the DL packet to the netif layer. */
+ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
+ struct iosm_wwan *wwan, u32 offset,
+- u8 service_class, struct sk_buff *skb)
++ u8 service_class, struct sk_buff *skb,
++ u32 pkt_len)
+ {
+ struct sk_buff *dest_skb = skb_clone(skb, GFP_ATOMIC);
+
+@@ -373,7 +374,7 @@ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
+ return -ENOMEM;
+
+ skb_pull(dest_skb, offset);
+- skb_set_tail_pointer(dest_skb, dest_skb->len);
++ skb_trim(dest_skb, pkt_len);
+ /* Pass the packet to the netif layer. */
+ dest_skb->priority = service_class;
+
+@@ -429,7 +430,7 @@ static void ipc_mux_dl_fcth_decode(struct iosm_mux *ipc_mux,
+ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
+ struct sk_buff *skb)
+ {
+- u32 pad_len, packet_offset;
++ u32 pad_len, packet_offset, adgh_len;
+ struct iosm_wwan *wwan;
+ struct mux_adgh *adgh;
+ u8 *block = skb->data;
+@@ -470,10 +471,12 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
+ packet_offset = sizeof(*adgh) + pad_len;
+
+ if_id += ipc_mux->wwan_q_offset;
++ adgh_len = le16_to_cpu(adgh->length);
+
+ /* Pass the packet to the netif layer */
+ rc = ipc_mux_net_receive(ipc_mux, if_id, wwan, packet_offset,
+- adgh->service_class, skb);
++ adgh->service_class, skb,
++ adgh_len - packet_offset);
+ if (rc) {
+ dev_err(ipc_mux->dev, "mux adgh decoding error");
+ return;
+@@ -547,7 +550,7 @@ static int mux_dl_process_dg(struct iosm_mux *ipc_mux, struct mux_adbh *adbh,
+ int if_id, int nr_of_dg)
+ {
+ u32 dl_head_pad_len = ipc_mux->session[if_id].dl_head_pad_len;
+- u32 packet_offset, i, rc;
++ u32 packet_offset, i, rc, dg_len;
+
+ for (i = 0; i < nr_of_dg; i++, dg++) {
+ if (le32_to_cpu(dg->datagram_index)
+@@ -562,11 +565,12 @@ static int mux_dl_process_dg(struct iosm_mux *ipc_mux, struct mux_adbh *adbh,
+ packet_offset =
+ le32_to_cpu(dg->datagram_index) +
+ dl_head_pad_len;
++ dg_len = le16_to_cpu(dg->datagram_length);
+ /* Pass the packet to the netif layer. */
+ rc = ipc_mux_net_receive(ipc_mux, if_id, ipc_mux->wwan,
+ packet_offset,
+- dg->service_class,
+- skb);
++ dg->service_class, skb,
++ dg_len - dl_head_pad_len);
+ if (rc)
+ goto dg_error;
+ }
+@@ -1207,10 +1211,9 @@ static int mux_ul_dg_update_tbl_index(struct iosm_mux *ipc_mux,
+ qlth_n_ql_size, ul_list);
+ ipc_mux_ul_adb_finish(ipc_mux);
+ if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed,
+- IOSM_AGGR_MUX_SIG_ADBH)) {
+- dev_kfree_skb(src_skb);
++ IOSM_AGGR_MUX_SIG_ADBH))
+ return -ENOMEM;
+- }
++
+ ipc_mux->size_needed = le32_to_cpu(adb->adbh->block_length);
+
+ ipc_mux->size_needed += offsetof(struct mux_adth, dg);
+@@ -1471,8 +1474,7 @@ void ipc_mux_ul_encoded_process(struct iosm_mux *ipc_mux, struct sk_buff *skb)
+ ipc_mux->ul_data_pend_bytes);
+
+ /* Reset the skb settings. */
+- skb->tail = 0;
+- skb->len = 0;
++ skb_trim(skb, 0);
+
+ /* Add the consumed ADB to the free list. */
+ skb_queue_tail((&ipc_mux->ul_adb.free_list), skb);
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol.h b/drivers/net/wwan/iosm/iosm_ipc_protocol.h
+index 9b3a6d86ece7a..289397c4ea6ce 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_protocol.h
++++ b/drivers/net/wwan/iosm/iosm_ipc_protocol.h
+@@ -122,7 +122,7 @@ struct iosm_protocol {
+ struct iosm_imem *imem;
+ struct ipc_rsp *rsp_ring[IPC_MEM_MSG_ENTRIES];
+ struct device *dev;
+- phys_addr_t phy_ap_shm;
++ dma_addr_t phy_ap_shm;
+ u32 old_msg_tail;
+ };
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 01c36284e5428..f612a0ba64d00 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -4297,7 +4297,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
+ mutex_unlock(&ns->ctrl->subsys->lock);
+
+ /* guarantee not available in head->list */
+- synchronize_rcu();
++ synchronize_srcu(&ns->head->srcu);
+
+ if (!nvme_ns_head_multipath(ns->head))
+ nvme_cdev_del(&ns->cdev, &ns->cdev_device);
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index b9cf17cbbbd5d..114e2b9359f83 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -174,11 +174,14 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
+ struct nvme_ns_head *head = ns->head;
+ sector_t capacity = get_capacity(head->disk);
+ int node;
++ int srcu_idx;
+
++ srcu_idx = srcu_read_lock(&head->srcu);
+ list_for_each_entry_rcu(ns, &head->list, siblings) {
+ if (capacity != get_capacity(ns->disk))
+ clear_bit(NVME_NS_READY, &ns->flags);
+ }
++ srcu_read_unlock(&head->srcu, srcu_idx);
+
+ for_each_node(node)
+ rcu_assign_pointer(head->current_path[node], NULL);
+diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c
+index b11c3c974b3d6..80cb187f14817 100644
+--- a/drivers/nvmem/rmem.c
++++ b/drivers/nvmem/rmem.c
+@@ -37,9 +37,9 @@ static int rmem_read(void *context, unsigned int offset,
+ * but as of Dec 2020 this isn't possible on arm64.
+ */
+ addr = memremap(priv->mem->base, available, MEMREMAP_WB);
+- if (IS_ERR(addr)) {
++ if (!addr) {
+ dev_err(priv->dev, "Failed to remap memory region\n");
+- return PTR_ERR(addr);
++ return -ENOMEM;
+ }
+
+ count = memory_read_from_buffer(val, bytes, &off, addr, available);
+diff --git a/drivers/of/property.c b/drivers/of/property.c
+index 967f79b590165..134cfc980b70b 100644
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -993,8 +993,10 @@ of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
+ nargs, index, &of_args);
+ if (ret < 0)
+ return ret;
+- if (!args)
++ if (!args) {
++ of_node_put(of_args.np);
+ return 0;
++ }
+
+ args->nargs = of_args.args_count;
+ args->fwnode = of_fwnode_handle(of_args.np);
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index 52ecd66ce357f..047a8374b4fdc 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -436,9 +436,14 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
+ writel(value, padcfg0);
+ }
+
++static int __intel_gpio_get_gpio_mode(u32 value)
++{
++ return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
++}
++
+ static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
+ {
+- return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
++ return __intel_gpio_get_gpio_mode(readl(padcfg0));
+ }
+
+ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
+@@ -1674,6 +1679,7 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
+ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
+ {
+ const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
++ u32 value;
+
+ if (!pd || !intel_pad_usable(pctrl, pin))
+ return false;
+@@ -1688,6 +1694,25 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
+ gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
+ return true;
+
++ /*
++ * The firmware on some systems may configure GPIO pins to be
++ * an interrupt source in so called "direct IRQ" mode. In such
++ * cases the GPIO controller driver has no idea if those pins
++ * are being used or not. At the same time, there is a known bug
++ * in the firmwares that don't restore the pin settings correctly
++ * after suspend, i.e. by an unknown reason the Rx value becomes
++ * inverted.
++ *
++ * Hence, let's save and restore the pins that are configured
++ * as GPIOs in the input mode with GPIROUTIOXAPIC bit set.
++ *
++ * See https://bugzilla.kernel.org/show_bug.cgi?id=214749.
++ */
++ value = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
++ if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
++ (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO))
++ return true;
++
+ return false;
+ }
+
+diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
+index 67bec7ea0f8b0..414ee6bb8ac98 100644
+--- a/drivers/pinctrl/pinctrl-single.c
++++ b/drivers/pinctrl/pinctrl-single.c
+@@ -727,7 +727,7 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)
+
+ mux_bytes = pcs->width / BITS_PER_BYTE;
+
+- if (pcs->bits_per_mux) {
++ if (pcs->bits_per_mux && pcs->fmask) {
+ pcs->bits_per_pin = fls(pcs->fmask);
+ nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin;
+ } else {
+diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c
+index c0031a3ab42f5..3ac5fcf98d0d6 100644
+--- a/fs/afs/fs_probe.c
++++ b/fs/afs/fs_probe.c
+@@ -167,8 +167,8 @@ responded:
+ clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags);
+ }
+
+- if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) &&
+- rtt_us < server->probe.rtt) {
++ rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us);
++ if (rtt_us < server->probe.rtt) {
+ server->probe.rtt = rtt_us;
+ server->rtt = rtt_us;
+ alist->preferred = index;
+diff --git a/fs/afs/server.c b/fs/afs/server.c
+index 4981baf97835c..b5237206eac3e 100644
+--- a/fs/afs/server.c
++++ b/fs/afs/server.c
+@@ -406,7 +406,7 @@ void afs_put_server(struct afs_net *net, struct afs_server *server,
+ if (!server)
+ return;
+
+- a = atomic_inc_return(&server->active);
++ a = atomic_read(&server->active);
+ zero = __refcount_dec_and_test(&server->ref, &r);
+ trace_afs_server(debug_id, r - 1, a, reason);
+ if (unlikely(zero))
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index ba323dcb0a0b8..db56e0c0e9acc 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -2920,14 +2920,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
+ dstgroup->rsv_rfer = inherit->lim.rsv_rfer;
+ dstgroup->rsv_excl = inherit->lim.rsv_excl;
+
+- ret = update_qgroup_limit_item(trans, dstgroup);
+- if (ret) {
+- fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+- btrfs_info(fs_info,
+- "unable to update quota limit for %llu",
+- dstgroup->qgroupid);
+- goto unlock;
+- }
++ qgroup_dirty(fs_info, dstgroup);
+ }
+
+ if (srcid) {
+diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
+index 78d01033604c6..c5c801e38b63c 100644
+--- a/fs/ksmbd/vfs.c
++++ b/fs/ksmbd/vfs.c
+@@ -1784,9 +1784,9 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
+ ret = vfs_copy_file_range(src_fp->filp, src_off,
+ dst_fp->filp, dst_off, len, 0);
+ if (ret == -EOPNOTSUPP || ret == -EXDEV)
+- ret = generic_copy_file_range(src_fp->filp, src_off,
+- dst_fp->filp, dst_off,
+- len, 0);
++ ret = vfs_copy_file_range(src_fp->filp, src_off,
++ dst_fp->filp, dst_off, len,
++ COPY_FILE_SPLICE);
+ if (ret < 0)
+ return ret;
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index f3cd614e1f1e9..dc24d67d0ca4e 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -572,8 +572,8 @@ ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
+ ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count, 0);
+
+ if (ret == -EOPNOTSUPP || ret == -EXDEV)
+- ret = generic_copy_file_range(src, src_pos, dst, dst_pos,
+- count, 0);
++ ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count,
++ COPY_FILE_SPLICE);
+ return ret;
+ }
+
+diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
+index 3b55e239705f4..9930fa901039f 100644
+--- a/fs/nilfs2/dat.c
++++ b/fs/nilfs2/dat.c
+@@ -111,6 +111,13 @@ static void nilfs_dat_commit_free(struct inode *dat,
+ kunmap_atomic(kaddr);
+
+ nilfs_dat_commit_entry(dat, req);
++
++ if (unlikely(req->pr_desc_bh == NULL || req->pr_bitmap_bh == NULL)) {
++ nilfs_error(dat->i_sb,
++ "state inconsistency probably due to duplicate use of vblocknr = %llu",
++ (unsigned long long)req->pr_entry_nr);
++ return;
++ }
+ nilfs_palloc_commit_free_entry(dat, req);
+ }
+
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 328ce8cf9a85e..24b9668d63770 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -1388,6 +1388,8 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
+ struct file *file_out, loff_t pos_out,
+ size_t len, unsigned int flags)
+ {
++ lockdep_assert(sb_write_started(file_inode(file_out)->i_sb));
++
+ return do_splice_direct(file_in, &pos_in, file_out, &pos_out,
+ len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
+ }
+@@ -1424,7 +1426,9 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
+ * and several different sets of file_operations, but they all end up
+ * using the same ->copy_file_range() function pointer.
+ */
+- if (file_out->f_op->copy_file_range) {
++ if (flags & COPY_FILE_SPLICE) {
++ /* cross sb splice is allowed */
++ } else if (file_out->f_op->copy_file_range) {
+ if (file_in->f_op->copy_file_range !=
+ file_out->f_op->copy_file_range)
+ return -EXDEV;
+@@ -1474,8 +1478,9 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ size_t len, unsigned int flags)
+ {
+ ssize_t ret;
++ bool splice = flags & COPY_FILE_SPLICE;
+
+- if (flags != 0)
++ if (flags & ~COPY_FILE_SPLICE)
+ return -EINVAL;
+
+ ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len,
+@@ -1501,14 +1506,14 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ * same sb using clone, but for filesystems where both clone and copy
+ * are supported (e.g. nfs,cifs), we only call the copy method.
+ */
+- if (file_out->f_op->copy_file_range) {
++ if (!splice && file_out->f_op->copy_file_range) {
+ ret = file_out->f_op->copy_file_range(file_in, pos_in,
+ file_out, pos_out,
+ len, flags);
+ goto done;
+ }
+
+- if (file_in->f_op->remap_file_range &&
++ if (!splice && file_in->f_op->remap_file_range &&
+ file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) {
+ ret = file_in->f_op->remap_file_range(file_in, pos_in,
+ file_out, pos_out,
+@@ -1528,6 +1533,8 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ * consistent story about which filesystems support copy_file_range()
+ * and which filesystems do not, that will allow userspace tools to
+ * make consistent desicions w.r.t using copy_file_range().
++ *
++ * We also get here if caller (e.g. nfsd) requested COPY_FILE_SPLICE.
+ */
+ ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
+ flags);
+@@ -1582,6 +1589,10 @@ SYSCALL_DEFINE6(copy_file_range, int, fd_in, loff_t __user *, off_in,
+ pos_out = f_out.file->f_pos;
+ }
+
++ ret = -EINVAL;
++ if (flags != 0)
++ goto out;
++
+ ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len,
+ flags);
+ if (ret > 0) {
+diff --git a/include/linux/damon.h b/include/linux/damon.h
+index 7b1f4a4882308..98e622c34d44f 100644
+--- a/include/linux/damon.h
++++ b/include/linux/damon.h
+@@ -216,13 +216,26 @@ struct damos_stat {
+ };
+
+ /**
+- * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
++ * struct damos_access_pattern - Target access pattern of the given scheme.
+ * @min_sz_region: Minimum size of target regions.
+ * @max_sz_region: Maximum size of target regions.
+ * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions.
+ * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions.
+ * @min_age_region: Minimum age of target regions.
+ * @max_age_region: Maximum age of target regions.
++ */
++struct damos_access_pattern {
++ unsigned long min_sz_region;
++ unsigned long max_sz_region;
++ unsigned int min_nr_accesses;
++ unsigned int max_nr_accesses;
++ unsigned int min_age_region;
++ unsigned int max_age_region;
++};
++
++/**
++ * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
++ * @pattern: Access pattern of target regions.
+ * @action: &damo_action to be applied to the target regions.
+ * @quota: Control the aggressiveness of this scheme.
+ * @wmarks: Watermarks for automated (in)activation of this scheme.
+@@ -230,10 +243,8 @@ struct damos_stat {
+ * @list: List head for siblings.
+ *
+ * For each aggregation interval, DAMON finds regions which fit in the
+- * condition (&min_sz_region, &max_sz_region, &min_nr_accesses,
+- * &max_nr_accesses, &min_age_region, &max_age_region) and applies &action to
+- * those. To avoid consuming too much CPU time or IO resources for the
+- * &action, "a is used.
++ * &pattern and applies &action to those. To avoid consuming too much
++ * CPU time or IO resources for the &action, "a is used.
+ *
+ * To do the work only when needed, schemes can be activated for specific
+ * system situations using &wmarks. If all schemes that registered to the
+@@ -248,12 +259,7 @@ struct damos_stat {
+ * &action is applied.
+ */
+ struct damos {
+- unsigned long min_sz_region;
+- unsigned long max_sz_region;
+- unsigned int min_nr_accesses;
+- unsigned int max_nr_accesses;
+- unsigned int min_age_region;
+- unsigned int max_age_region;
++ struct damos_access_pattern pattern;
+ enum damos_action action;
+ struct damos_quota quota;
+ struct damos_watermarks wmarks;
+@@ -501,12 +507,9 @@ void damon_destroy_region(struct damon_region *r, struct damon_target *t);
+ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
+ unsigned int nr_ranges);
+
+-struct damos *damon_new_scheme(
+- unsigned long min_sz_region, unsigned long max_sz_region,
+- unsigned int min_nr_accesses, unsigned int max_nr_accesses,
+- unsigned int min_age_region, unsigned int max_age_region,
+- enum damos_action action, struct damos_quota *quota,
+- struct damos_watermarks *wmarks);
++struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
++ enum damos_action action, struct damos_quota *quota,
++ struct damos_watermarks *wmarks);
+ void damon_add_scheme(struct damon_ctx *ctx, struct damos *s);
+ void damon_destroy_scheme(struct damos *s);
+
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 7203f5582fd44..be074b6895b97 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2087,6 +2087,14 @@ struct dir_context {
+ */
+ #define REMAP_FILE_ADVISORY (REMAP_FILE_CAN_SHORTEN)
+
++/*
++ * These flags control the behavior of vfs_copy_file_range().
++ * They are not available to the user via syscall.
++ *
++ * COPY_FILE_SPLICE: call splice direct instead of fs clone/copy ops
++ */
++#define COPY_FILE_SPLICE (1 << 0)
++
+ struct iov_iter;
+ struct io_uring_cmd;
+
+diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
+index 9c50bc40f8ff3..6f7993803ee78 100644
+--- a/include/linux/mmc/mmc.h
++++ b/include/linux/mmc/mmc.h
+@@ -451,7 +451,7 @@ static inline bool mmc_ready_for_data(u32 status)
+ #define MMC_SECURE_TRIM1_ARG 0x80000001
+ #define MMC_SECURE_TRIM2_ARG 0x80008000
+ #define MMC_SECURE_ARGS 0x80000000
+-#define MMC_TRIM_ARGS 0x00008001
++#define MMC_TRIM_OR_DISCARD_ARGS 0x00008003
+
+ #define mmc_driver_type_mask(n) (1 << (n))
+
+diff --git a/include/net/sctp/stream_sched.h b/include/net/sctp/stream_sched.h
+index 01a70b27e026b..65058faea4db1 100644
+--- a/include/net/sctp/stream_sched.h
++++ b/include/net/sctp/stream_sched.h
+@@ -26,6 +26,8 @@ struct sctp_sched_ops {
+ int (*init)(struct sctp_stream *stream);
+ /* Init a stream */
+ int (*init_sid)(struct sctp_stream *stream, __u16 sid, gfp_t gfp);
++ /* free a stream */
++ void (*free_sid)(struct sctp_stream *stream, __u16 sid);
+ /* Frees the entire thing */
+ void (*free)(struct sctp_stream *stream);
+
+diff --git a/ipc/sem.c b/ipc/sem.c
+index c8496f98b1391..00f88aa01ac5a 100644
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -2179,14 +2179,15 @@ long __do_semtimedop(int semid, struct sembuf *sops,
+ * scenarios where we were awakened externally, during the
+ * window between wake_q_add() and wake_up_q().
+ */
++ rcu_read_lock();
+ error = READ_ONCE(queue.status);
+ if (error != -EINTR) {
+ /* see SEM_BARRIER_2 for purpose/pairing */
+ smp_acquire__after_ctrl_dep();
++ rcu_read_unlock();
+ goto out;
+ }
+
+- rcu_read_lock();
+ locknum = sem_lock(sma, sops, nsops);
+
+ if (!ipc_valid_object(&sma->sem_perm))
+diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
+index d13ffb00e9813..cbe918ba9035d 100644
+--- a/kernel/bpf/bpf_local_storage.c
++++ b/kernel/bpf/bpf_local_storage.c
+@@ -74,7 +74,7 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
+ gfp_flags | __GFP_NOWARN);
+ if (selem) {
+ if (value)
+- memcpy(SDATA(selem)->data, value, smap->map.value_size);
++ copy_map_value(&smap->map, SDATA(selem)->data, value);
+ return selem;
+ }
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index bec18d81b1161..8dcbefd90b7f6 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -9006,7 +9006,7 @@ static void perf_event_bpf_emit_ksymbols(struct bpf_prog *prog,
+ PERF_RECORD_KSYMBOL_TYPE_BPF,
+ (u64)(unsigned long)subprog->bpf_func,
+ subprog->jited_len, unregister,
+- prog->aux->ksym.name);
++ subprog->aux->ksym.name);
+ }
+ }
+ }
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 205d605cacc5b..e9a3094c52e57 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -265,13 +265,14 @@ int proc_dostring(struct ctl_table *table, int write,
+ ppos);
+ }
+
+-static size_t proc_skip_spaces(char **buf)
++static void proc_skip_spaces(char **buf, size_t *size)
+ {
+- size_t ret;
+- char *tmp = skip_spaces(*buf);
+- ret = tmp - *buf;
+- *buf = tmp;
+- return ret;
++ while (*size) {
++ if (!isspace(**buf))
++ break;
++ (*size)--;
++ (*buf)++;
++ }
+ }
+
+ static void proc_skip_char(char **buf, size_t *size, const char v)
+@@ -340,13 +341,12 @@ static int proc_get_long(char **buf, size_t *size,
+ unsigned long *val, bool *neg,
+ const char *perm_tr, unsigned perm_tr_len, char *tr)
+ {
+- int len;
+ char *p, tmp[TMPBUFLEN];
++ ssize_t len = *size;
+
+- if (!*size)
++ if (len <= 0)
+ return -EINVAL;
+
+- len = *size;
+ if (len > TMPBUFLEN - 1)
+ len = TMPBUFLEN - 1;
+
+@@ -519,7 +519,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ bool neg;
+
+ if (write) {
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ if (!left)
+ break;
+@@ -546,7 +546,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
+@@ -588,7 +588,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ if (left > PAGE_SIZE - 1)
+ left = PAGE_SIZE - 1;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left) {
+ err = -EINVAL;
+ goto out_free;
+@@ -608,7 +608,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ }
+
+ if (!err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ out_free:
+ if (err)
+@@ -1073,7 +1073,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (write) {
+ bool neg;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left)
+ break;
+
+@@ -1102,7 +1102,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
+diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c
+index 154996684fb54..4376887e0d8aa 100644
+--- a/kernel/trace/trace_dynevent.c
++++ b/kernel/trace/trace_dynevent.c
+@@ -118,6 +118,7 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type
+ if (ret)
+ break;
+ }
++ tracing_reset_all_online_cpus();
+ mutex_unlock(&event_mutex);
+ out:
+ argv_free(argv);
+@@ -214,6 +215,7 @@ int dyn_events_release_all(struct dyn_event_operations *type)
+ break;
+ }
+ out:
++ tracing_reset_all_online_cpus();
+ mutex_unlock(&event_mutex);
+
+ return ret;
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index 0356cae0cf74e..bf18b13495713 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -2880,7 +2880,10 @@ static int probe_remove_event_call(struct trace_event_call *call)
+ * TRACE_REG_UNREGISTER.
+ */
+ if (file->flags & EVENT_FILE_FL_ENABLED)
+- return -EBUSY;
++ goto busy;
++
++ if (file->flags & EVENT_FILE_FL_WAS_ENABLED)
++ tr->clear_trace = true;
+ /*
+ * The do_for_each_event_file_safe() is
+ * a double loop. After finding the call for this
+@@ -2893,6 +2896,12 @@ static int probe_remove_event_call(struct trace_event_call *call)
+ __trace_remove_event_call(call);
+
+ return 0;
++ busy:
++ /* No need to clear the trace now */
++ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
++ tr->clear_trace = false;
++ }
++ return -EBUSY;
+ }
+
+ /* Remove an event_call */
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index fdf784620c283..49243e8617148 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5051,6 +5051,9 @@ static void event_hist_trigger(struct event_trigger_data *data,
+ void *key = NULL;
+ unsigned int i;
+
++ if (unlikely(!rbe))
++ return;
++
+ memset(compound_key, 0, hist_data->key_size);
+
+ for_each_hist_key_field(i, hist_data) {
+diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
+index 78d536d3ff3db..4300c5dc4e5db 100644
+--- a/kernel/trace/trace_osnoise.c
++++ b/kernel/trace/trace_osnoise.c
+@@ -917,7 +917,7 @@ void osnoise_trace_irq_entry(int id)
+ void osnoise_trace_irq_exit(int id, const char *desc)
+ {
+ struct osnoise_variables *osn_var = this_cpu_osn_var();
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+@@ -1048,7 +1048,7 @@ static void trace_softirq_entry_callback(void *data, unsigned int vec_nr)
+ static void trace_softirq_exit_callback(void *data, unsigned int vec_nr)
+ {
+ struct osnoise_variables *osn_var = this_cpu_osn_var();
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+@@ -1144,7 +1144,7 @@ thread_entry(struct osnoise_variables *osn_var, struct task_struct *t)
+ static void
+ thread_exit(struct osnoise_variables *osn_var, struct task_struct *t)
+ {
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 997d23641448a..88f34cdeef023 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -398,6 +398,7 @@ config FRAME_WARN
+ default 2048 if GCC_PLUGIN_LATENT_ENTROPY
+ default 2048 if PARISC
+ default 1536 if (!64BIT && XTENSA)
++ default 1280 if KASAN && !64BIT
+ default 1024 if !64BIT
+ default 2048 if 64BIT
+ help
+@@ -1862,8 +1863,14 @@ config NETDEV_NOTIFIER_ERROR_INJECT
+ If unsure, say N.
+
+ config FUNCTION_ERROR_INJECTION
+- def_bool y
++ bool "Fault-injections of functions"
+ depends on HAVE_FUNCTION_ERROR_INJECTION && KPROBES
++ help
++ Add fault injections into various functions that are annotated with
++ ALLOW_ERROR_INJECTION() in the kernel. BPF may also modify the return
++ value of theses functions. This is useful to test error paths of code.
++
++ If unsure, say N
+
+ config FAULT_INJECTION
+ bool "Fault-injection framework"
+diff --git a/mm/compaction.c b/mm/compaction.c
+index 640fa76228dd9..88fea74c3a86b 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -986,29 +986,29 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
+ goto isolate_fail;
+ }
+
++ /*
++ * Be careful not to clear PageLRU until after we're
++ * sure the page is not being freed elsewhere -- the
++ * page release code relies on it.
++ */
++ if (unlikely(!get_page_unless_zero(page)))
++ goto isolate_fail;
++
+ /*
+ * Migration will fail if an anonymous page is pinned in memory,
+ * so avoid taking lru_lock and isolating it unnecessarily in an
+ * admittedly racy check.
+ */
+ mapping = page_mapping(page);
+- if (!mapping && page_count(page) > page_mapcount(page))
+- goto isolate_fail;
++ if (!mapping && (page_count(page) - 1) > total_mapcount(page))
++ goto isolate_fail_put;
+
+ /*
+ * Only allow to migrate anonymous pages in GFP_NOFS context
+ * because those do not depend on fs locks.
+ */
+ if (!(cc->gfp_mask & __GFP_FS) && mapping)
+- goto isolate_fail;
+-
+- /*
+- * Be careful not to clear PageLRU until after we're
+- * sure the page is not being freed elsewhere -- the
+- * page release code relies on it.
+- */
+- if (unlikely(!get_page_unless_zero(page)))
+- goto isolate_fail;
++ goto isolate_fail_put;
+
+ /* Only take pages on LRU: a check now makes later tests safe */
+ if (!PageLRU(page))
+diff --git a/mm/damon/core.c b/mm/damon/core.c
+index 7d25dc582fe34..7d5a9ae6f4ac9 100644
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -230,24 +230,21 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
+ return 0;
+ }
+
+-struct damos *damon_new_scheme(
+- unsigned long min_sz_region, unsigned long max_sz_region,
+- unsigned int min_nr_accesses, unsigned int max_nr_accesses,
+- unsigned int min_age_region, unsigned int max_age_region,
+- enum damos_action action, struct damos_quota *quota,
+- struct damos_watermarks *wmarks)
++struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
++ enum damos_action action, struct damos_quota *quota,
++ struct damos_watermarks *wmarks)
+ {
+ struct damos *scheme;
+
+ scheme = kmalloc(sizeof(*scheme), GFP_KERNEL);
+ if (!scheme)
+ return NULL;
+- scheme->min_sz_region = min_sz_region;
+- scheme->max_sz_region = max_sz_region;
+- scheme->min_nr_accesses = min_nr_accesses;
+- scheme->max_nr_accesses = max_nr_accesses;
+- scheme->min_age_region = min_age_region;
+- scheme->max_age_region = max_age_region;
++ scheme->pattern.min_sz_region = pattern->min_sz_region;
++ scheme->pattern.max_sz_region = pattern->max_sz_region;
++ scheme->pattern.min_nr_accesses = pattern->min_nr_accesses;
++ scheme->pattern.max_nr_accesses = pattern->max_nr_accesses;
++ scheme->pattern.min_age_region = pattern->min_age_region;
++ scheme->pattern.max_age_region = pattern->max_age_region;
+ scheme->action = action;
+ scheme->stat = (struct damos_stat){};
+ INIT_LIST_HEAD(&scheme->list);
+@@ -667,10 +664,12 @@ static bool __damos_valid_target(struct damon_region *r, struct damos *s)
+ unsigned long sz;
+
+ sz = r->ar.end - r->ar.start;
+- return s->min_sz_region <= sz && sz <= s->max_sz_region &&
+- s->min_nr_accesses <= r->nr_accesses &&
+- r->nr_accesses <= s->max_nr_accesses &&
+- s->min_age_region <= r->age && r->age <= s->max_age_region;
++ return s->pattern.min_sz_region <= sz &&
++ sz <= s->pattern.max_sz_region &&
++ s->pattern.min_nr_accesses <= r->nr_accesses &&
++ r->nr_accesses <= s->pattern.max_nr_accesses &&
++ s->pattern.min_age_region <= r->age &&
++ r->age <= s->pattern.max_age_region;
+ }
+
+ static bool damos_valid_target(struct damon_ctx *c, struct damon_target *t,
+diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
+index dafe7e71329b8..61214cb9a5d3c 100644
+--- a/mm/damon/dbgfs.c
++++ b/mm/damon/dbgfs.c
+@@ -131,9 +131,12 @@ static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len)
+ damon_for_each_scheme(s, c) {
+ rc = scnprintf(&buf[written], len - written,
+ "%lu %lu %u %u %u %u %d %lu %lu %lu %u %u %u %d %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+- s->min_sz_region, s->max_sz_region,
+- s->min_nr_accesses, s->max_nr_accesses,
+- s->min_age_region, s->max_age_region,
++ s->pattern.min_sz_region,
++ s->pattern.max_sz_region,
++ s->pattern.min_nr_accesses,
++ s->pattern.max_nr_accesses,
++ s->pattern.min_age_region,
++ s->pattern.max_age_region,
+ damos_action_to_dbgfs_scheme_action(s->action),
+ s->quota.ms, s->quota.sz,
+ s->quota.reset_interval,
+@@ -221,8 +224,6 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ struct damos *scheme, **schemes;
+ const int max_nr_schemes = 256;
+ int pos = 0, parsed, ret;
+- unsigned long min_sz, max_sz;
+- unsigned int min_nr_a, max_nr_a, min_age, max_age;
+ unsigned int action_input;
+ enum damos_action action;
+
+@@ -233,13 +234,18 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+
+ *nr_schemes = 0;
+ while (pos < len && *nr_schemes < max_nr_schemes) {
++ struct damos_access_pattern pattern = {};
+ struct damos_quota quota = {};
+ struct damos_watermarks wmarks;
+
+ ret = sscanf(&str[pos],
+ "%lu %lu %u %u %u %u %u %lu %lu %lu %u %u %u %u %lu %lu %lu %lu%n",
+- &min_sz, &max_sz, &min_nr_a, &max_nr_a,
+- &min_age, &max_age, &action_input, "a.ms,
++ &pattern.min_sz_region, &pattern.max_sz_region,
++ &pattern.min_nr_accesses,
++ &pattern.max_nr_accesses,
++ &pattern.min_age_region,
++ &pattern.max_age_region,
++ &action_input, "a.ms,
+ "a.sz, "a.reset_interval,
+ "a.weight_sz, "a.weight_nr_accesses,
+ "a.weight_age, &wmarks.metric,
+@@ -251,7 +257,9 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ if ((int)action < 0)
+ goto fail;
+
+- if (min_sz > max_sz || min_nr_a > max_nr_a || min_age > max_age)
++ if (pattern.min_sz_region > pattern.max_sz_region ||
++ pattern.min_nr_accesses > pattern.max_nr_accesses ||
++ pattern.min_age_region > pattern.max_age_region)
+ goto fail;
+
+ if (wmarks.high < wmarks.mid || wmarks.high < wmarks.low ||
+@@ -259,8 +267,7 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ goto fail;
+
+ pos += parsed;
+- scheme = damon_new_scheme(min_sz, max_sz, min_nr_a, max_nr_a,
+- min_age, max_age, action, "a, &wmarks);
++ scheme = damon_new_scheme(&pattern, action, "a, &wmarks);
+ if (!scheme)
+ goto fail;
+
+diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
+index 9de6f00a71c5d..0184ed4828b7e 100644
+--- a/mm/damon/lru_sort.c
++++ b/mm/damon/lru_sort.c
+@@ -293,6 +293,17 @@ static bool get_monitoring_region(unsigned long *start, unsigned long *end)
+ /* Create a DAMON-based operation scheme for hot memory regions */
+ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and accessed for more than the threshold */
++ .min_nr_accesses = hot_thres,
++ .max_nr_accesses = UINT_MAX,
++ /* no matter its age */
++ .min_age_region = 0,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -313,26 +324,31 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
+ .weight_nr_accesses = 1,
+ .weight_age = 0,
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and accessed for more than the threshold */
+- hot_thres, UINT_MAX,
+- /* no matter its age */
+- 0, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* prioritize those on LRU lists, as soon as found */
+ DAMOS_LRU_PRIO,
+ /* under the quota. */
+ "a,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ /* Create a DAMON-based operation scheme for cold memory regions */
+ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and not accessed at all */
++ .min_nr_accesses = 0,
++ .max_nr_accesses = 0,
++ /* for min_age or more micro-seconds */
++ .min_age_region = cold_thres,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -354,21 +370,15 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
+ .weight_nr_accesses = 0,
+ .weight_age = 1,
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and not accessed at all */
+- 0, 0,
+- /* for cold_thres or more micro-seconds, and */
+- cold_thres, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* mark those as not accessed, as soon as found */
+ DAMOS_LRU_DEPRIO,
+ /* under the quota. */
+ "a,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ static int damon_lru_sort_apply_parameters(void)
+diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
+index a7faf51b4bd4a..5aeca0b9e88ec 100644
+--- a/mm/damon/reclaim.c
++++ b/mm/damon/reclaim.c
+@@ -264,6 +264,17 @@ static bool get_monitoring_region(unsigned long *start, unsigned long *end)
+
+ static struct damos *damon_reclaim_new_scheme(void)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and not accessed at all */
++ .min_nr_accesses = 0,
++ .max_nr_accesses = 0,
++ /* for min_age or more micro-seconds */
++ .min_age_region = min_age / aggr_interval,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -284,21 +295,15 @@ static struct damos *damon_reclaim_new_scheme(void)
+ .weight_nr_accesses = 0,
+ .weight_age = 1
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and not accessed at all */
+- 0, 0,
+- /* for min_age or more micro-seconds, and */
+- min_age / aggr_interval, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* page out those, as soon as found */
+ DAMOS_PAGEOUT,
+ /* under the quota. */
+ "a,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ static int damon_reclaim_apply_parameters(void)
+diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
+index b4b9614eecbed..1b782ca413965 100644
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -2259,11 +2259,20 @@ static int damon_sysfs_set_targets(struct damon_ctx *ctx,
+ static struct damos *damon_sysfs_mk_scheme(
+ struct damon_sysfs_scheme *sysfs_scheme)
+ {
+- struct damon_sysfs_access_pattern *pattern =
++ struct damon_sysfs_access_pattern *access_pattern =
+ sysfs_scheme->access_pattern;
+ struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
+ struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
+ struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
++
++ struct damos_access_pattern pattern = {
++ .min_sz_region = access_pattern->sz->min,
++ .max_sz_region = access_pattern->sz->max,
++ .min_nr_accesses = access_pattern->nr_accesses->min,
++ .max_nr_accesses = access_pattern->nr_accesses->max,
++ .min_age_region = access_pattern->age->min,
++ .max_age_region = access_pattern->age->max,
++ };
+ struct damos_quota quota = {
+ .ms = sysfs_quotas->ms,
+ .sz = sysfs_quotas->sz,
+@@ -2280,18 +2289,58 @@ static struct damos *damon_sysfs_mk_scheme(
+ .low = sysfs_wmarks->low,
+ };
+
+- return damon_new_scheme(pattern->sz->min, pattern->sz->max,
+- pattern->nr_accesses->min, pattern->nr_accesses->max,
+- pattern->age->min, pattern->age->max,
+- sysfs_scheme->action, "a, &wmarks);
++ return damon_new_scheme(&pattern, sysfs_scheme->action, "a,
++ &wmarks);
++}
++
++static void damon_sysfs_update_scheme(struct damos *scheme,
++ struct damon_sysfs_scheme *sysfs_scheme)
++{
++ struct damon_sysfs_access_pattern *access_pattern =
++ sysfs_scheme->access_pattern;
++ struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
++ struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
++ struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
++
++ scheme->pattern.min_sz_region = access_pattern->sz->min;
++ scheme->pattern.max_sz_region = access_pattern->sz->max;
++ scheme->pattern.min_nr_accesses = access_pattern->nr_accesses->min;
++ scheme->pattern.max_nr_accesses = access_pattern->nr_accesses->max;
++ scheme->pattern.min_age_region = access_pattern->age->min;
++ scheme->pattern.max_age_region = access_pattern->age->max;
++
++ scheme->action = sysfs_scheme->action;
++
++ scheme->quota.ms = sysfs_quotas->ms;
++ scheme->quota.sz = sysfs_quotas->sz;
++ scheme->quota.reset_interval = sysfs_quotas->reset_interval_ms;
++ scheme->quota.weight_sz = sysfs_weights->sz;
++ scheme->quota.weight_nr_accesses = sysfs_weights->nr_accesses;
++ scheme->quota.weight_age = sysfs_weights->age;
++
++ scheme->wmarks.metric = sysfs_wmarks->metric;
++ scheme->wmarks.interval = sysfs_wmarks->interval_us;
++ scheme->wmarks.high = sysfs_wmarks->high;
++ scheme->wmarks.mid = sysfs_wmarks->mid;
++ scheme->wmarks.low = sysfs_wmarks->low;
+ }
+
+ static int damon_sysfs_set_schemes(struct damon_ctx *ctx,
+ struct damon_sysfs_schemes *sysfs_schemes)
+ {
+- int i;
++ struct damos *scheme, *next;
++ int i = 0;
++
++ damon_for_each_scheme_safe(scheme, next, ctx) {
++ if (i < sysfs_schemes->nr)
++ damon_sysfs_update_scheme(scheme,
++ sysfs_schemes->schemes_arr[i]);
++ else
++ damon_destroy_scheme(scheme);
++ i++;
++ }
+
+- for (i = 0; i < sysfs_schemes->nr; i++) {
++ for (; i < sysfs_schemes->nr; i++) {
+ struct damos *scheme, *next;
+
+ scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 8487321c1fc78..3e056fb043bb1 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -862,8 +862,10 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
+ struct file *file;
+
+ p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
+- if (!p)
++ if (!p) {
++ sock_release(csocket);
+ return -ENOMEM;
++ }
+
+ csocket->sk->sk_allocation = GFP_NOIO;
+ file = sock_alloc_file(csocket, 0, NULL);
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index a50429a62f744..56bb27d67a2ee 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -351,17 +351,18 @@ static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev,
+ struct hsr_node *node_src)
+ {
+ bool was_multicast_frame;
+- int res;
++ int res, recv_len;
+
+ was_multicast_frame = (skb->pkt_type == PACKET_MULTICAST);
+ hsr_addr_subst_source(node_src, skb);
+ skb_pull(skb, ETH_HLEN);
++ recv_len = skb->len;
+ res = netif_rx(skb);
+ if (res == NET_RX_DROP) {
+ dev->stats.rx_dropped++;
+ } else {
+ dev->stats.rx_packets++;
+- dev->stats.rx_bytes += skb->len;
++ dev->stats.rx_bytes += recv_len;
+ if (was_multicast_frame)
+ dev->stats.multicast++;
+ }
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 2dc97583d2790..cb24260692e10 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -888,13 +888,15 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
+ return 1;
+ }
+
++ if (fi->nh) {
++ if (cfg->fc_oif || cfg->fc_gw_family || cfg->fc_mp)
++ return 1;
++ return 0;
++ }
++
+ if (cfg->fc_oif || cfg->fc_gw_family) {
+ struct fib_nh *nh;
+
+- /* cannot match on nexthop object attributes */
+- if (fi->nh)
+- return 1;
+-
+ nh = fib_info_nh(fi, 0);
+ if (cfg->fc_encap) {
+ if (fib_encap_match(net, cfg->fc_encap_type,
+diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
+index 2e66598fac791..e8ebd343e2bff 100644
+--- a/net/mac80211/airtime.c
++++ b/net/mac80211/airtime.c
+@@ -452,6 +452,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
+ (status->encoding == RX_ENC_HE && streams > 8)))
+ return 0;
+
++ if (idx >= MCS_GROUP_RATES)
++ return 0;
++
+ duration = airtime_mcs_groups[group].duration[idx];
+ duration <<= airtime_mcs_groups[group].shift;
+ *overhead = 36 + (streams << 2);
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index b568f55998f3c..42d5e0a7952ae 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2297,12 +2297,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ goto out;
+ }
+
+- /* if we are invoked by the msk cleanup code, the subflow is
+- * already orphaned
+- */
+- if (ssk->sk_socket)
+- sock_orphan(ssk);
+-
++ sock_orphan(ssk);
+ subflow->disposable = 1;
+
+ /* if ssk hit tcp_done(), tcp_cleanup_ulp() cleared the related ops
+@@ -2833,7 +2828,11 @@ cleanup:
+ if (ssk == msk->first)
+ subflow->fail_tout = 0;
+
+- sock_orphan(ssk);
++ /* detach from the parent socket, but allow data_ready to
++ * push incoming data into the mptcp stack, to properly ack it
++ */
++ ssk->sk_socket = NULL;
++ ssk->sk_wq = NULL;
+ unlock_sock_fast(ssk, slow);
+ }
+ sock_orphan(sk);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 02a54d59697b5..2159b5f9988f8 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1745,16 +1745,16 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
+
+ for (msk = head; msk; msk = next) {
+ struct sock *sk = (struct sock *)msk;
+- bool slow, do_cancel_work;
++ bool do_cancel_work;
+
+ sock_hold(sk);
+- slow = lock_sock_fast_nested(sk);
++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+ next = msk->dl_next;
+ msk->first = NULL;
+ msk->dl_next = NULL;
+
+ do_cancel_work = __mptcp_close(sk, 0);
+- unlock_sock_fast(sk, slow);
++ release_sock(sk);
+ if (do_cancel_work)
+ mptcp_cancel_work(sk);
+ sock_put(sk);
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 5cbe07116e04e..5727cb7ec1747 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2293,8 +2293,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ status |= TP_STATUS_CSUMNOTREADY;
+ else if (skb->pkt_type != PACKET_OUTGOING &&
+- (skb->ip_summed == CHECKSUM_COMPLETE ||
+- skb_csum_unnecessary(skb)))
++ skb_csum_unnecessary(skb))
+ status |= TP_STATUS_CSUM_VALID;
+
+ if (snaplen > res)
+@@ -3520,8 +3519,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ aux.tp_status |= TP_STATUS_CSUMNOTREADY;
+ else if (skb->pkt_type != PACKET_OUTGOING &&
+- (skb->ip_summed == CHECKSUM_COMPLETE ||
+- skb_csum_unnecessary(skb)))
++ skb_csum_unnecessary(skb))
+ aux.tp_status |= TP_STATUS_CSUM_VALID;
+
+ aux.tp_len = origlen;
+diff --git a/net/sctp/stream.c b/net/sctp/stream.c
+index ef9fceadef8d5..ee6514af830f7 100644
+--- a/net/sctp/stream.c
++++ b/net/sctp/stream.c
+@@ -52,6 +52,19 @@ static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt)
+ }
+ }
+
++static void sctp_stream_free_ext(struct sctp_stream *stream, __u16 sid)
++{
++ struct sctp_sched_ops *sched;
++
++ if (!SCTP_SO(stream, sid)->ext)
++ return;
++
++ sched = sctp_sched_ops_from_stream(stream);
++ sched->free_sid(stream, sid);
++ kfree(SCTP_SO(stream, sid)->ext);
++ SCTP_SO(stream, sid)->ext = NULL;
++}
++
+ /* Migrates chunks from stream queues to new stream queues if needed,
+ * but not across associations. Also, removes those chunks to streams
+ * higher than the new max.
+@@ -70,16 +83,14 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream,
+ * sctp_stream_update will swap ->out pointers.
+ */
+ for (i = 0; i < outcnt; i++) {
+- kfree(SCTP_SO(new, i)->ext);
++ sctp_stream_free_ext(new, i);
+ SCTP_SO(new, i)->ext = SCTP_SO(stream, i)->ext;
+ SCTP_SO(stream, i)->ext = NULL;
+ }
+ }
+
+- for (i = outcnt; i < stream->outcnt; i++) {
+- kfree(SCTP_SO(stream, i)->ext);
+- SCTP_SO(stream, i)->ext = NULL;
+- }
++ for (i = outcnt; i < stream->outcnt; i++)
++ sctp_stream_free_ext(stream, i);
+ }
+
+ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
+@@ -174,9 +185,9 @@ void sctp_stream_free(struct sctp_stream *stream)
+ struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
+ int i;
+
+- sched->free(stream);
++ sched->unsched_all(stream);
+ for (i = 0; i < stream->outcnt; i++)
+- kfree(SCTP_SO(stream, i)->ext);
++ sctp_stream_free_ext(stream, i);
+ genradix_free(&stream->out);
+ genradix_free(&stream->in);
+ }
+diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c
+index 1ad565ed56273..7c8f9d89e16a8 100644
+--- a/net/sctp/stream_sched.c
++++ b/net/sctp/stream_sched.c
+@@ -46,6 +46,10 @@ static int sctp_sched_fcfs_init_sid(struct sctp_stream *stream, __u16 sid,
+ return 0;
+ }
+
++static void sctp_sched_fcfs_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++}
++
+ static void sctp_sched_fcfs_free(struct sctp_stream *stream)
+ {
+ }
+@@ -96,6 +100,7 @@ static struct sctp_sched_ops sctp_sched_fcfs = {
+ .get = sctp_sched_fcfs_get,
+ .init = sctp_sched_fcfs_init,
+ .init_sid = sctp_sched_fcfs_init_sid,
++ .free_sid = sctp_sched_fcfs_free_sid,
+ .free = sctp_sched_fcfs_free,
+ .enqueue = sctp_sched_fcfs_enqueue,
+ .dequeue = sctp_sched_fcfs_dequeue,
+diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c
+index 80b5a2c4cbc7b..4fc9f2923ed11 100644
+--- a/net/sctp/stream_sched_prio.c
++++ b/net/sctp/stream_sched_prio.c
+@@ -204,6 +204,24 @@ static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid,
+ return sctp_sched_prio_set(stream, sid, 0, gfp);
+ }
+
++static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++ struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head;
++ int i;
++
++ if (!prio)
++ return;
++
++ SCTP_SO(stream, sid)->ext->prio_head = NULL;
++ for (i = 0; i < stream->outcnt; i++) {
++ if (SCTP_SO(stream, i)->ext &&
++ SCTP_SO(stream, i)->ext->prio_head == prio)
++ return;
++ }
++
++ kfree(prio);
++}
++
+ static void sctp_sched_prio_free(struct sctp_stream *stream)
+ {
+ struct sctp_stream_priorities *prio, *n;
+@@ -323,6 +341,7 @@ static struct sctp_sched_ops sctp_sched_prio = {
+ .get = sctp_sched_prio_get,
+ .init = sctp_sched_prio_init,
+ .init_sid = sctp_sched_prio_init_sid,
++ .free_sid = sctp_sched_prio_free_sid,
+ .free = sctp_sched_prio_free,
+ .enqueue = sctp_sched_prio_enqueue,
+ .dequeue = sctp_sched_prio_dequeue,
+diff --git a/net/sctp/stream_sched_rr.c b/net/sctp/stream_sched_rr.c
+index ff425aed62c7f..cc444fe0d67c2 100644
+--- a/net/sctp/stream_sched_rr.c
++++ b/net/sctp/stream_sched_rr.c
+@@ -90,6 +90,10 @@ static int sctp_sched_rr_init_sid(struct sctp_stream *stream, __u16 sid,
+ return 0;
+ }
+
++static void sctp_sched_rr_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++}
++
+ static void sctp_sched_rr_free(struct sctp_stream *stream)
+ {
+ sctp_sched_rr_unsched_all(stream);
+@@ -177,6 +181,7 @@ static struct sctp_sched_ops sctp_sched_rr = {
+ .get = sctp_sched_rr_get,
+ .init = sctp_sched_rr_init,
+ .init_sid = sctp_sched_rr_init_sid,
++ .free_sid = sctp_sched_rr_free_sid,
+ .free = sctp_sched_rr_free,
+ .enqueue = sctp_sched_rr_enqueue,
+ .dequeue = sctp_sched_rr_dequeue,
+diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
+index f09316a9035f4..d67440de011e7 100644
+--- a/net/tipc/crypto.c
++++ b/net/tipc/crypto.c
+@@ -1971,6 +1971,9 @@ rcv:
+ /* Ok, everything's fine, try to synch own keys according to peers' */
+ tipc_crypto_key_synch(rx, *skb);
+
++ /* Re-fetch skb cb as skb might be changed in tipc_msg_validate */
++ skb_cb = TIPC_SKB_CB(*skb);
++
+ /* Mark skb decrypted */
+ skb_cb->decrypted = 1;
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 9067e4b70855a..b4d7885729924 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -330,7 +330,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ * determine if they are the same ie.
+ */
+ if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+- if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
++ if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
++ !memcmp(tmp_old + 2, tmp + 2, 5)) {
+ /* same vendor ie, copy from
+ * subelement
+ */
+@@ -2526,10 +2527,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ const struct cfg80211_bss_ies *ies1, *ies2;
+ size_t ielen = len - offsetof(struct ieee80211_mgmt,
+ u.probe_resp.variable);
+- struct cfg80211_non_tx_bss non_tx_data;
++ struct cfg80211_non_tx_bss non_tx_data = {};
+
+ res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
+ len, gfp);
++
++ /* don't do any further MBSSID handling for S1G */
++ if (ieee80211_is_s1g_beacon(mgmt->frame_control))
++ return res;
++
+ if (!res || !wiphy->support_mbssid ||
+ !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
+ return res;
+diff --git a/scripts/faddr2line b/scripts/faddr2line
+index 5514c23f45c24..0e73aca4f9089 100755
+--- a/scripts/faddr2line
++++ b/scripts/faddr2line
+@@ -74,7 +74,8 @@ command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed"
+ find_dir_prefix() {
+ local objfile=$1
+
+- local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}')
++ local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' |
++ ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}')
+ [[ -z $start_kernel_addr ]] && return
+
+ local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr)
+@@ -178,7 +179,7 @@ __faddr2line() {
+ found=2
+ break
+ fi
+- done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)
++ done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)
+
+ if [[ $found = 0 ]]; then
+ warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size"
+@@ -259,7 +260,7 @@ __faddr2line() {
+
+ DONE=1
+
+- done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn')
++ done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn')
+ }
+
+ [[ $# -lt 2 ]] && usage
+diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
+index f99e00083141e..4c677c8546c71 100644
+--- a/sound/firewire/dice/dice-stream.c
++++ b/sound/firewire/dice/dice-stream.c
+@@ -59,7 +59,7 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
+
+ static int select_clock(struct snd_dice *dice, unsigned int rate)
+ {
+- __be32 reg;
++ __be32 reg, new;
+ u32 data;
+ int i;
+ int err;
+@@ -83,15 +83,17 @@ static int select_clock(struct snd_dice *dice, unsigned int rate)
+ if (completion_done(&dice->clock_accepted))
+ reinit_completion(&dice->clock_accepted);
+
+- reg = cpu_to_be32(data);
++ new = cpu_to_be32(data);
+ err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
+- ®, sizeof(reg));
++ &new, sizeof(new));
+ if (err < 0)
+ return err;
+
+ if (wait_for_completion_timeout(&dice->clock_accepted,
+- msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
+- return -ETIMEDOUT;
++ msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) {
++ if (reg != new)
++ return -ETIMEDOUT;
++ }
+
+ return 0;
+ }
+diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c
+index 8a0965cd3e667..297c458c4d8b0 100644
+--- a/sound/soc/codecs/tlv320adc3xxx.c
++++ b/sound/soc/codecs/tlv320adc3xxx.c
+@@ -14,6 +14,7 @@
+
+ #include <dt-bindings/sound/tlv320adc3xxx.h>
+ #include <linux/clk.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/io.h>
+@@ -1025,7 +1026,9 @@ static const struct gpio_chip adc3xxx_gpio_chip = {
+
+ static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx)
+ {
++#ifdef CONFIG_GPIOLIB
+ gpiochip_remove(&adc3xxx->gpio_chip);
++#endif
+ }
+
+ static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx)
+diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
+index bd88de0563583..47691119306fb 100644
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -452,7 +452,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+ val = ucontrol->value.integer.value[0];
+ if (mc->platform_max && val > mc->platform_max)
+ return -EINVAL;
+- if (val > max - min)
++ if (val > max)
+ return -EINVAL;
+ val_mask = mask << shift;
+ val = (val + min) & mask;
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index e36c44090720e..79ea83be21ce9 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -11143,7 +11143,7 @@ static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf
+ }
+
+ *link = bpf_program__attach_raw_tracepoint(prog, tp_name);
+- return libbpf_get_error(link);
++ return libbpf_get_error(*link);
+ }
+
+ /* Common logic for all BPF program types that attach to a btf_id */
+diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
+index 8bc117bcc7bcd..c42ba9358d8ce 100644
+--- a/tools/lib/bpf/ringbuf.c
++++ b/tools/lib/bpf/ringbuf.c
+@@ -59,6 +59,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ __u32 len = sizeof(info);
+ struct epoll_event *e;
+ struct ring *r;
++ __u64 mmap_sz;
+ void *tmp;
+ int err;
+
+@@ -97,8 +98,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ r->mask = info.max_entries - 1;
+
+ /* Map writable consumer page */
+- tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+- map_fd, 0);
++ tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
+ if (tmp == MAP_FAILED) {
+ err = -errno;
+ pr_warn("ringbuf: failed to mmap consumer page for map fd=%d: %d\n",
+@@ -111,8 +111,12 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ * data size to allow simple reading of samples that wrap around the
+ * end of a ring buffer. See kernel implementation for details.
+ * */
+- tmp = mmap(NULL, rb->page_size + 2 * info.max_entries, PROT_READ,
+- MAP_SHARED, map_fd, rb->page_size);
++ mmap_sz = rb->page_size + 2 * (__u64)info.max_entries;
++ if (mmap_sz != (__u64)(size_t)mmap_sz) {
++ pr_warn("ringbuf: ring buffer size (%u) is too big\n", info.max_entries);
++ return libbpf_err(-E2BIG);
++ }
++ tmp = mmap(NULL, (size_t)mmap_sz, PROT_READ, MAP_SHARED, map_fd, rb->page_size);
+ if (tmp == MAP_FAILED) {
+ err = -errno;
+ ringbuf_unmap_ring(rb, r);
+diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
+index d5a0dd548989b..a47b26ab48f23 100755
+--- a/tools/testing/selftests/net/fib_nexthops.sh
++++ b/tools/testing/selftests/net/fib_nexthops.sh
+@@ -1223,6 +1223,22 @@ ipv4_fcnal()
+ log_test $rc 0 "Delete nexthop route warning"
+ run_cmd "$IP route delete 172.16.101.1/32 nhid 12"
+ run_cmd "$IP nexthop del id 12"
++
++ run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1"
++ run_cmd "$IP ro add 172.16.101.0/24 nhid 21"
++ run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1"
++ log_test $? 2 "Delete multipath route with only nh id based entry"
++
++ run_cmd "$IP nexthop add id 22 via 172.16.1.6 dev veth1"
++ run_cmd "$IP ro add 172.16.102.0/24 nhid 22"
++ run_cmd "$IP ro del 172.16.102.0/24 dev veth1"
++ log_test $? 2 "Delete route when specifying only nexthop device"
++
++ run_cmd "$IP ro del 172.16.102.0/24 via 172.16.1.6"
++ log_test $? 2 "Delete route when specifying only gateway"
++
++ run_cmd "$IP ro del 172.16.102.0/24"
++ log_test $? 0 "Delete route when not specifying nexthop attributes"
+ }
+
+ ipv4_grp_fcnal()
+diff --git a/tools/vm/slabinfo-gnuplot.sh b/tools/vm/slabinfo-gnuplot.sh
+index 26e193ffd2a2f..873a892147e57 100644
+--- a/tools/vm/slabinfo-gnuplot.sh
++++ b/tools/vm/slabinfo-gnuplot.sh
+@@ -150,7 +150,7 @@ do_preprocess()
+ let lines=3
+ out=`basename "$in"`"-slabs-by-loss"
+ `cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\
+- egrep -iv '\-\-|Name|Slabs'\
++ grep -E -iv '\-\-|Name|Slabs'\
+ | awk '{print $1" "$4+$2*$3" "$4}' > "$out"`
+ if [ $? -eq 0 ]; then
+ do_slabs_plotting "$out"
+@@ -159,7 +159,7 @@ do_preprocess()
+ let lines=3
+ out=`basename "$in"`"-slabs-by-size"
+ `cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\
+- egrep -iv '\-\-|Name|Slabs'\
++ grep -E -iv '\-\-|Name|Slabs'\
+ | awk '{print $1" "$4" "$4-$2*$3}' > "$out"`
+ if [ $? -eq 0 ]; then
+ do_slabs_plotting "$out"
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-14 12:13 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-14 12:13 UTC (permalink / raw
To: gentoo-commits
commit: 458c78b0fda8c58e1930d06f4e7b5747ee0e7284
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 14 12:12:56 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Dec 14 12:12:56 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=458c78b0
Linux patch 6.0.13
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1012_linux-6.0.13.patch | 5882 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 5886 insertions(+)
diff --git a/0000_README b/0000_README
index 37d6ef5a..a5d5308b 100644
--- a/0000_README
+++ b/0000_README
@@ -91,6 +91,10 @@ Patch: 1011_linux-6.0.12.patch
From: http://www.kernel.org
Desc: Linux 6.0.12
+Patch: 1012_linux-6.0.13.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.13
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1012_linux-6.0.13.patch b/1012_linux-6.0.13.patch
new file mode 100644
index 00000000..d636e963
--- /dev/null
+++ b/1012_linux-6.0.13.patch
@@ -0,0 +1,5882 @@
+diff --git a/.clang-format b/.clang-format
+index 1247d54f9e49f..8d01225bfcb7d 100644
+--- a/.clang-format
++++ b/.clang-format
+@@ -535,6 +535,7 @@ ForEachMacros:
+ - 'perf_hpp_list__for_each_sort_list_safe'
+ - 'perf_pmu__for_each_hybrid_pmu'
+ - 'ping_portaddr_for_each_entry'
++ - 'ping_portaddr_for_each_entry_rcu'
+ - 'plist_for_each'
+ - 'plist_for_each_continue'
+ - 'plist_for_each_entry'
+diff --git a/Makefile b/Makefile
+index 46c6eb57b354d..bf00f3240b3a3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 12
++SUBLEVEL = 13
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 1dc3bfac30b68..29148285f9fc8 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -1270,10 +1270,10 @@
+ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+ };
+
+- gpmi: nand-controller@33002000 {
++ gpmi: nand-controller@33002000{
+ compatible = "fsl,imx7d-gpmi-nand";
+ #address-cells = <1>;
+- #size-cells = <0>;
++ #size-cells = <1>;
+ reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
+index 2a7e6624efb93..94216f870b57c 100644
+--- a/arch/arm/boot/dts/rk3036-evb.dts
++++ b/arch/arm/boot/dts/rk3036-evb.dts
+@@ -31,11 +31,10 @@
+ &i2c1 {
+ status = "okay";
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+ };
+diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
+index cfa318a506eb0..2db5ba7062086 100644
+--- a/arch/arm/boot/dts/rk3066a-mk808.dts
++++ b/arch/arm/boot/dts/rk3066a-mk808.dts
+@@ -32,7 +32,7 @@
+ keyup-threshold-microvolt = <2500000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <0>;
+diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
+index a9ed3cd2c2da6..239d2ec37fdc4 100644
+--- a/arch/arm/boot/dts/rk3188-radxarock.dts
++++ b/arch/arm/boot/dts/rk3188-radxarock.dts
+@@ -71,7 +71,7 @@
+ #sound-dai-cells = <0>;
+ };
+
+- ir_recv: gpio-ir-receiver {
++ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
+index cdd4a0bd5133d..44b54af0bbf9f 100644
+--- a/arch/arm/boot/dts/rk3188.dtsi
++++ b/arch/arm/boot/dts/rk3188.dtsi
+@@ -379,7 +379,7 @@
+ rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>;
+ };
+
+- lcdc1_rgb24: ldcd1-rgb24 {
++ lcdc1_rgb24: lcdc1-rgb24 {
+ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>,
+ <2 RK_PA1 1 &pcfg_pull_none>,
+ <2 RK_PA2 1 &pcfg_pull_none>,
+@@ -607,7 +607,6 @@
+
+ &global_timer {
+ interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+- status = "disabled";
+ };
+
+ &local_timer {
+diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+index be695b8c1f672..8a635c2431274 100644
+--- a/arch/arm/boot/dts/rk3288-evb-act8846.dts
++++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+@@ -54,7 +54,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563@51 {
++ rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+
+diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
+index 399d6b9c5fd4b..382d2839cf472 100644
+--- a/arch/arm/boot/dts/rk3288-evb.dtsi
++++ b/arch/arm/boot/dts/rk3288-evb.dtsi
+@@ -28,19 +28,19 @@
+ press-threshold-microvolt = <300000>;
+ };
+
+- menu {
++ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <640000>;
+ };
+
+- esc {
++ button-esc {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1000000>;
+ };
+
+- home {
++ button-home {
+ label = "Home";
+ linux,code = <KEY_HOME>;
+ press-threshold-microvolt = <1300000>;
+diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
+index 052afe5543e2a..3836c61cfb761 100644
+--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
++++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
+@@ -233,11 +233,10 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio7>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts
+index 713f55e143c69..db1eb648e0e1a 100644
+--- a/arch/arm/boot/dts/rk3288-miqi.dts
++++ b/arch/arm/boot/dts/rk3288-miqi.dts
+@@ -162,11 +162,10 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+
+diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
+index 80e0f07c8e878..13cfdaa95cc7d 100644
+--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
++++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
+@@ -165,11 +165,10 @@
+ };
+
+ &i2c0 {
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+index 0ae2bd150e372..793951655b73b 100644
+--- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
++++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+@@ -241,7 +241,6 @@
+ interrupt-parent = <&gpio5>;
+ interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
+index 616a828e0c6e4..17e89d30de781 100644
+--- a/arch/arm/boot/dts/rk3xxx.dtsi
++++ b/arch/arm/boot/dts/rk3xxx.dtsi
+@@ -76,6 +76,13 @@
+ reg = <0x1013c200 0x20>;
+ interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
+ clocks = <&cru CORE_PERI>;
++ status = "disabled";
++ /* The clock source and the sched_clock provided by the arm_global_timer
++ * on Rockchip rk3066a/rk3188 are quite unstable because their rates
++ * depend on the CPU frequency.
++ * Keep the arm_global_timer disabled in order to have the
++ * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default.
++ */
+ };
+
+ local_timer: local-timer@1013c600 {
+diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
+index fe87397c3d8c6..bdbc1e590891e 100644
+--- a/arch/arm/include/asm/perf_event.h
++++ b/arch/arm/include/asm/perf_event.h
+@@ -17,7 +17,7 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs);
+
+ #define perf_arch_fetch_caller_regs(regs, __ip) { \
+ (regs)->ARM_pc = (__ip); \
+- (regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \
++ frame_pointer((regs)) = (unsigned long) __builtin_frame_address(0); \
+ (regs)->ARM_sp = current_stack_pointer; \
+ (regs)->ARM_cpsr = SVC_MODE; \
+ }
+diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
+index d16aba48fa0a4..090011394477f 100644
+--- a/arch/arm/include/asm/pgtable-nommu.h
++++ b/arch/arm/include/asm/pgtable-nommu.h
+@@ -44,12 +44,6 @@
+
+ typedef pte_t *pte_addr_t;
+
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-#define ZERO_PAGE(vaddr) (virt_to_page(0))
+-
+ /*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index 78a532068fec2..ef48a55e9af83 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -10,6 +10,15 @@
+ #include <linux/const.h>
+ #include <asm/proc-fns.h>
+
++#ifndef __ASSEMBLY__
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used
++ * for zero-mapped memory areas etc..
++ */
++extern struct page *empty_zero_page;
++#define ZERO_PAGE(vaddr) (empty_zero_page)
++#endif
++
+ #ifndef CONFIG_MMU
+
+ #include <asm-generic/pgtable-nopud.h>
+@@ -139,13 +148,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ */
+
+ #ifndef __ASSEMBLY__
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-extern struct page *empty_zero_page;
+-#define ZERO_PAGE(vaddr) (empty_zero_page)
+-
+
+ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
+index 67ed68fbe3a55..bf2b5c6a18c6a 100644
+--- a/arch/arm/mach-at91/sama5.c
++++ b/arch/arm/mach-at91/sama5.c
+@@ -26,7 +26,7 @@ static void sama5_l2c310_write_sec(unsigned long val, unsigned reg)
+ static void __init sama5_secure_cache_init(void)
+ {
+ sam_secure_init();
+- if (sam_linux_is_optee_available())
++ if (IS_ENABLED(CONFIG_OUTER_CACHE) && sam_linux_is_optee_available())
+ outer_cache.write_sec = sama5_l2c310_write_sec;
+ }
+
+diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
+index 46cccd6bf705a..de988cba9a4b1 100644
+--- a/arch/arm/mm/fault.c
++++ b/arch/arm/mm/fault.c
+@@ -105,6 +105,19 @@ static inline bool is_write_fault(unsigned int fsr)
+ return (fsr & FSR_WRITE) && !(fsr & FSR_CM);
+ }
+
++static inline bool is_translation_fault(unsigned int fsr)
++{
++ int fs = fsr_fs(fsr);
++#ifdef CONFIG_ARM_LPAE
++ if ((fs & FS_MMU_NOLL_MASK) == FS_TRANS_NOLL)
++ return true;
++#else
++ if (fs == FS_L1_TRANS || fs == FS_L2_TRANS)
++ return true;
++#endif
++ return false;
++}
++
+ static void die_kernel_fault(const char *msg, struct mm_struct *mm,
+ unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+@@ -140,7 +153,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+ if (addr < PAGE_SIZE) {
+ msg = "NULL pointer dereference";
+ } else {
+- if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
++ if (is_translation_fault(fsr) &&
++ kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
+ return;
+
+ msg = "paging request";
+@@ -208,7 +222,7 @@ static inline bool is_permission_fault(unsigned int fsr)
+ {
+ int fs = fsr_fs(fsr);
+ #ifdef CONFIG_ARM_LPAE
+- if ((fs & FS_PERM_NOLL_MASK) == FS_PERM_NOLL)
++ if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL)
+ return true;
+ #else
+ if (fs == FS_L1_PERM || fs == FS_L2_PERM)
+diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
+index 83b5ab32d7a48..54927ba1fa6ed 100644
+--- a/arch/arm/mm/fault.h
++++ b/arch/arm/mm/fault.h
+@@ -14,8 +14,9 @@
+
+ #ifdef CONFIG_ARM_LPAE
+ #define FSR_FS_AEA 17
++#define FS_TRANS_NOLL 0x4
+ #define FS_PERM_NOLL 0xC
+-#define FS_PERM_NOLL_MASK 0x3C
++#define FS_MMU_NOLL_MASK 0x3C
+
+ static inline int fsr_fs(unsigned int fsr)
+ {
+@@ -23,8 +24,10 @@ static inline int fsr_fs(unsigned int fsr)
+ }
+ #else
+ #define FSR_FS_AEA 22
+-#define FS_L1_PERM 0xD
+-#define FS_L2_PERM 0xF
++#define FS_L1_TRANS 0x5
++#define FS_L2_TRANS 0x7
++#define FS_L1_PERM 0xD
++#define FS_L2_PERM 0xF
+
+ static inline int fsr_fs(unsigned int fsr)
+ {
+diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
+index c42debaded95c..c1494a4dee25b 100644
+--- a/arch/arm/mm/nommu.c
++++ b/arch/arm/mm/nommu.c
+@@ -26,6 +26,13 @@
+
+ unsigned long vectors_base;
+
++/*
++ * empty_zero_page is a special page that is used for
++ * zero-initialized data and COW.
++ */
++struct page *empty_zero_page;
++EXPORT_SYMBOL(empty_zero_page);
++
+ #ifdef CONFIG_ARM_MPU
+ struct mpu_rgn_info mpu_rgn_info;
+ #endif
+@@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void)
+ */
+ void __init paging_init(const struct machine_desc *mdesc)
+ {
++ void *zero_page;
++
+ early_trap_init((void *)vectors_base);
+ mpu_setup();
++
++ /* allocate the zero page. */
++ zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
++ if (!zero_page)
++ panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
++ __func__, PAGE_SIZE, PAGE_SIZE);
++
+ bootmem_init();
++
++ empty_zero_page = virt_to_page(zero_page);
++ flush_dcache_page(empty_zero_page);
+ }
+
+ /*
+diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts
+index 848bc39cf86ac..4249b42843dae 100644
+--- a/arch/arm64/boot/dts/rockchip/px30-evb.dts
++++ b/arch/arm64/boot/dts/rockchip/px30-evb.dts
+@@ -30,31 +30,31 @@
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+- esc-key {
++ button-esc {
+ label = "esc";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1310000>;
+ };
+
+- home-key {
++ button-home {
+ label = "home";
+ linux,code = <KEY_HOME>;
+ press-threshold-microvolt = <624000>;
+ };
+
+- menu-key {
++ button-menu {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <987000>;
+ };
+
+- vol-down-key {
++ button-down {
+ label = "volume down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <300000>;
+ };
+
+- vol-up-key {
++ button-up {
+ label = "volume up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
+index 9fe9b0d11003a..184b84fdde075 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
+@@ -23,7 +23,7 @@
+ poll-interval = <100>;
+ keyup-threshold-microvolt = <1800000>;
+
+- func-key {
++ button-func {
+ linux,code = <KEY_FN>;
+ label = "function";
+ press-threshold-microvolt = <18000>;
+@@ -37,31 +37,31 @@
+ poll-interval = <100>;
+ keyup-threshold-microvolt = <1800000>;
+
+- esc-key {
++ button-esc {
+ linux,code = <KEY_MICMUTE>;
+ label = "micmute";
+ press-threshold-microvolt = <1130000>;
+ };
+
+- home-key {
++ button-home {
+ linux,code = <KEY_MODE>;
+ label = "mode";
+ press-threshold-microvolt = <901000>;
+ };
+
+- menu-key {
++ button-menu {
+ linux,code = <KEY_PLAY>;
+ label = "play";
+ press-threshold-microvolt = <624000>;
+ };
+
+- vol-down-key {
++ button-down {
+ linux,code = <KEY_VOLUMEDOWN>;
+ label = "volume down";
+ press-threshold-microvolt = <300000>;
+ };
+
+- vol-up-key {
++ button-up {
+ linux,code = <KEY_VOLUMEUP>;
+ label = "volume up";
+ press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+index ea6820902ede0..7ea48167747c6 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+@@ -19,7 +19,7 @@
+ stdout-path = "serial2:1500000n8";
+ };
+
+- ir_rx {
++ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+index 43c928ac98f0f..1deef53a4c940 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+@@ -25,7 +25,7 @@
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <17000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+index 7f5bba0c60014..0e88e9592c1cb 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+@@ -208,7 +208,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+index 38d757c005488..e147d6f8b43ee 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+@@ -192,7 +192,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
+index 2a332763c35cd..9d9297bc5f04a 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
+@@ -123,7 +123,7 @@
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+index 452728b82e42c..3bf8f959e42c4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+@@ -39,7 +39,7 @@
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
+index 72182c58cc46a..65cb21837b0ca 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
+@@ -19,7 +19,7 @@
+ keyup-threshold-microvolt = <1500000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+index 9e2e246e0bab7..dba4d03bfc2b8 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+@@ -52,13 +52,13 @@
+ press-threshold-microvolt = <300000>;
+ };
+
+- back {
++ button-back {
+ label = "Back";
+ linux,code = <KEY_BACK>;
+ press-threshold-microvolt = <985000>;
+ };
+
+- menu {
++ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <1314000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
+index 5a2661ae0131c..18b5050c6cd3b 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
+@@ -98,7 +98,7 @@
+ };
+
+ &i2c0 {
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+index acb174d3a8c5f..4f3dd107e83eb 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+@@ -41,7 +41,7 @@
+ keyup-threshold-microvolt = <1500000>;
+ poll-interval = <100>;
+
+- recovery {
++ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+index 401e1ae9d9443..b045f74071e45 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+@@ -491,7 +491,6 @@
+ &i2s1 {
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+- status = "okay";
+ };
+
+ &i2s2 {
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+index 13927e7d0724e..dbec2b7173a0b 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+@@ -33,13 +33,13 @@
+ press-threshold-microvolt = <300000>;
+ };
+
+- back {
++ button-back {
+ label = "Back";
+ linux,code = <KEY_BACK>;
+ press-threshold-microvolt = <985000>;
+ };
+
+- menu {
++ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <1314000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+index 935b8c68a71d6..6c168566321ba 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+@@ -297,7 +297,7 @@
+ clock-frequency = <400000>;
+ status = "okay";
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+index 0d45868132b9d..8d61f824c12dc 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+@@ -23,7 +23,7 @@
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1750000>;
+
+- recovery {
++ button-recovery {
+ label = "recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+index 57759b66d44d0..ab1abf0bb7493 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+@@ -130,7 +130,7 @@
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>;
+ clock_in_out = "input";
+- phy-mode = "rgmii-id";
++ phy-mode = "rgmii";
+ phy-supply = <&vcc_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m0_miim
+@@ -397,11 +397,7 @@
+
+ &i2c3 {
+ pinctrl-names = "default";
+- pinctrl-0 = <&i2c3m1_xfer>;
+- status = "okay";
+-};
+-
+-&i2c5 {
++ pinctrl-0 = <&i2c3m0_xfer>;
+ status = "okay";
+ };
+
+diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
+index ec3de61912765..9123feb69854f 100644
+--- a/arch/loongarch/Makefile
++++ b/arch/loongarch/Makefile
+@@ -68,7 +68,7 @@ KBUILD_LDFLAGS += -m $(ld-emul)
+
+ ifdef CONFIG_LOONGARCH
+ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
+- egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
++ grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
+ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
+ endif
+
+diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
+index cc0674d1b8f0f..645e24ebec68d 100644
+--- a/arch/loongarch/include/asm/pgtable.h
++++ b/arch/loongarch/include/asm/pgtable.h
+@@ -357,7 +357,9 @@ static inline pte_t pte_mkdirty(pte_t pte)
+
+ static inline pte_t pte_mkwrite(pte_t pte)
+ {
+- pte_val(pte) |= (_PAGE_WRITE | _PAGE_DIRTY);
++ pte_val(pte) |= _PAGE_WRITE;
++ if (pte_val(pte) & _PAGE_MODIFIED)
++ pte_val(pte) |= _PAGE_DIRTY;
+ return pte;
+ }
+
+@@ -454,7 +456,9 @@ static inline int pmd_write(pmd_t pmd)
+
+ static inline pmd_t pmd_mkwrite(pmd_t pmd)
+ {
+- pmd_val(pmd) |= (_PAGE_WRITE | _PAGE_DIRTY);
++ pmd_val(pmd) |= _PAGE_WRITE;
++ if (pmd_val(pmd) & _PAGE_MODIFIED)
++ pmd_val(pmd) |= _PAGE_DIRTY;
+ return pmd;
+ }
+
+diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
+index 3353984820388..8319cc4090090 100644
+--- a/arch/loongarch/kernel/acpi.c
++++ b/arch/loongarch/kernel/acpi.c
+@@ -56,23 +56,6 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+ return ioremap_cache(phys, size);
+ }
+
+-void __init acpi_boot_table_init(void)
+-{
+- /*
+- * If acpi_disabled, bail out
+- */
+- if (acpi_disabled)
+- return;
+-
+- /*
+- * Initialize the ACPI boot-time table parser.
+- */
+- if (acpi_table_init()) {
+- disable_acpi();
+- return;
+- }
+-}
+-
+ #ifdef CONFIG_SMP
+ static int set_processor_mask(u32 id, u32 flags)
+ {
+@@ -156,13 +139,21 @@ static void __init acpi_process_madt(void)
+ loongson_sysconf.nr_cpus = num_processors;
+ }
+
+-int __init acpi_boot_init(void)
++void __init acpi_boot_table_init(void)
+ {
+ /*
+ * If acpi_disabled, bail out
+ */
+ if (acpi_disabled)
+- return -1;
++ return;
++
++ /*
++ * Initialize the ACPI boot-time table parser.
++ */
++ if (acpi_table_init()) {
++ disable_acpi();
++ return;
++ }
+
+ loongson_sysconf.boot_cpu_id = read_csr_cpuid();
+
+@@ -173,8 +164,6 @@ int __init acpi_boot_init(void)
+
+ /* Do not enable ACPI SPCR console by default */
+ acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_ACPI_NUMA
+diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
+index 8f5c2f9a1a835..574647e3483d3 100644
+--- a/arch/loongarch/kernel/setup.c
++++ b/arch/loongarch/kernel/setup.c
+@@ -203,7 +203,6 @@ void __init platform_init(void)
+ #ifdef CONFIG_ACPI
+ acpi_gbl_use_default_register_widths = false;
+ acpi_boot_table_init();
+- acpi_boot_init();
+ #endif
+
+ #ifdef CONFIG_NUMA
+diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
+index b206d91592051..4571c3c87cd4c 100644
+--- a/arch/loongarch/kernel/unwind_prologue.c
++++ b/arch/loongarch/kernel/unwind_prologue.c
+@@ -43,7 +43,8 @@ static bool unwind_by_prologue(struct unwind_state *state)
+ {
+ struct stack_info *info = &state->stack_info;
+ union loongarch_instruction *ip, *ip_end;
+- unsigned long frame_size = 0, frame_ra = -1;
++ long frame_ra = -1;
++ unsigned long frame_size = 0;
+ unsigned long size, offset, pc = state->pc;
+
+ if (state->sp >= info->end || state->sp < info->begin)
+diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
+index 94138f8f0c1c3..ace2541ababd3 100644
+--- a/arch/s390/kvm/vsie.c
++++ b/arch/s390/kvm/vsie.c
+@@ -546,8 +546,10 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
+ if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_CEI))
+ scb_s->eca |= scb_o->eca & ECA_CEI;
+ /* Epoch Extension */
+- if (test_kvm_facility(vcpu->kvm, 139))
++ if (test_kvm_facility(vcpu->kvm, 139)) {
+ scb_s->ecd |= scb_o->ecd & ECD_MEF;
++ scb_s->epdx = scb_o->epdx;
++ }
+
+ /* etoken */
+ if (test_kvm_facility(vcpu->kvm, 156))
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1bb46cbff0fac..882b5893f9108 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2042,6 +2042,11 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+
+ rp = (struct hci_rp_read_local_version *)skb->data;
+
++ bt_dev_info(hdev, "CSR: Setting up dongle with HCI ver=%u rev=%04x; LMP ver=%u subver=%04x; manufacturer=%u",
++ le16_to_cpu(rp->hci_ver), le16_to_cpu(rp->hci_rev),
++ le16_to_cpu(rp->lmp_ver), le16_to_cpu(rp->lmp_subver),
++ le16_to_cpu(rp->manufacturer));
++
+ /* Detect a wide host of Chinese controllers that aren't CSR.
+ *
+ * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
+@@ -2104,6 +2109,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+ * without these the controller will lock up.
+ */
+ set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
++ set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+ set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+ set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 6c49e6d06114f..034a74196a823 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -748,6 +748,11 @@ static int sev_update_firmware(struct device *dev)
+ struct page *p;
+ u64 data_size;
+
++ if (!sev_version_greater_or_equal(0, 15)) {
++ dev_dbg(dev, "DOWNLOAD_FIRMWARE not supported\n");
++ return -1;
++ }
++
+ if (sev_get_firmware(dev, &firmware) == -ENOENT) {
+ dev_dbg(dev, "No SEV firmware file present\n");
+ return -1;
+@@ -780,6 +785,14 @@ static int sev_update_firmware(struct device *dev)
+ data->len = firmware->size;
+
+ ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
++
++ /*
++ * A quirk for fixing the committed TCB version, when upgrading from
++ * earlier firmware version than 1.50.
++ */
++ if (!ret && !sev_version_greater_or_equal(1, 50))
++ ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
++
+ if (ret)
+ dev_dbg(dev, "Failed to update SEV firmware: %#x\n", error);
+ else
+@@ -1289,8 +1302,7 @@ void sev_pci_init(void)
+ if (sev_get_api_version())
+ goto err;
+
+- if (sev_version_greater_or_equal(0, 15) &&
+- sev_update_firmware(sev->dev) == 0)
++ if (sev_update_firmware(sev->dev) == 0)
+ sev_get_api_version();
+
+ /* If an init_ex_path is provided rely on INIT_EX for PSP initialization
+diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c
+index 14e6b3e64add5..6f3ded619c8b2 100644
+--- a/drivers/gpio/gpio-amd8111.c
++++ b/drivers/gpio/gpio-amd8111.c
+@@ -226,7 +226,10 @@ found:
+ ioport_unmap(gp.pm);
+ goto out;
+ }
++ return 0;
++
+ out:
++ pci_dev_put(pdev);
+ return err;
+ }
+
+@@ -234,6 +237,7 @@ static void __exit amd_gpio_exit(void)
+ {
+ gpiochip_remove(&gp.chip);
+ ioport_unmap(gp.pm);
++ pci_dev_put(gp.pdev);
+ }
+
+ module_init(amd_gpio_init);
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 9c976ad7208ef..09cfb49ed998d 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -621,6 +621,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
+ return -ENODATA;
+
+ pctldev = of_pinctrl_get(pctlnp);
++ of_node_put(pctlnp);
+ if (!pctldev)
+ return -ENODEV;
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index cc9c0a12259e1..eb7d00608c7fb 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -526,12 +526,13 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
+ if (ret)
+ return ret;
+
++ /* From this point, the .release() function cleans up gpio_device */
++ gdev->dev.release = gpiodevice_release;
++
+ ret = gpiochip_sysfs_register(gdev);
+ if (ret)
+ goto err_remove_device;
+
+- /* From this point, the .release() function cleans up gpio_device */
+- gdev->dev.release = gpiodevice_release;
+ dev_dbg(&gdev->dev, "registered GPIOs %d to %d on %s\n", gdev->base,
+ gdev->base + gdev->ngpio - 1, gdev->chip->label ? : "generic");
+
+@@ -597,10 +598,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ struct fwnode_handle *fwnode = NULL;
+ struct gpio_device *gdev;
+ unsigned long flags;
+- int base = gc->base;
+ unsigned int i;
++ u32 ngpios = 0;
++ int base = 0;
+ int ret = 0;
+- u32 ngpios;
+
+ if (gc->fwnode)
+ fwnode = gc->fwnode;
+@@ -647,17 +648,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ else
+ gdev->owner = THIS_MODULE;
+
+- gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
+- if (!gdev->descs) {
+- ret = -ENOMEM;
+- goto err_free_dev_name;
+- }
+-
+ /*
+ * Try the device properties if the driver didn't supply the number
+ * of GPIO lines.
+ */
+- if (gc->ngpio == 0) {
++ ngpios = gc->ngpio;
++ if (ngpios == 0) {
+ ret = device_property_read_u32(&gdev->dev, "ngpios", &ngpios);
+ if (ret == -ENODATA)
+ /*
+@@ -668,7 +664,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ */
+ ngpios = 0;
+ else if (ret)
+- goto err_free_descs;
++ goto err_free_dev_name;
+
+ gc->ngpio = ngpios;
+ }
+@@ -676,13 +672,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ if (gc->ngpio == 0) {
+ chip_err(gc, "tried to insert a GPIO chip with zero lines\n");
+ ret = -EINVAL;
+- goto err_free_descs;
++ goto err_free_dev_name;
+ }
+
+ if (gc->ngpio > FASTPATH_NGPIO)
+ chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n",
+ gc->ngpio, FASTPATH_NGPIO);
+
++ gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
++ if (!gdev->descs) {
++ ret = -ENOMEM;
++ goto err_free_dev_name;
++ }
++
+ gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
+ if (!gdev->label) {
+ ret = -ENOMEM;
+@@ -701,11 +703,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ * it may be a pipe dream. It will not happen before we get rid
+ * of the sysfs interface anyways.
+ */
++ base = gc->base;
+ if (base < 0) {
+ base = gpiochip_find_base(gc->ngpio);
+ if (base < 0) {
+- ret = base;
+ spin_unlock_irqrestore(&gpio_lock, flags);
++ ret = base;
++ base = 0;
+ goto err_free_label;
+ }
+ /*
+@@ -816,6 +820,11 @@ err_remove_of_chip:
+ err_free_gpiochip_mask:
+ gpiochip_remove_pin_ranges(gc);
+ gpiochip_free_valid_mask(gc);
++ if (gdev->dev.release) {
++ /* release() has been registered by gpiochip_setup_dev() */
++ put_device(&gdev->dev);
++ goto err_print_message;
++ }
+ err_remove_from_list:
+ spin_lock_irqsave(&gpio_lock, flags);
+ list_del(&gdev->list);
+@@ -829,13 +838,14 @@ err_free_dev_name:
+ err_free_ida:
+ ida_free(&gpio_ida, gdev->id);
+ err_free_gdev:
++ kfree(gdev);
++err_print_message:
+ /* failures here can mean systems won't boot... */
+ if (ret != -EPROBE_DEFER) {
+ pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
+- gdev->base, gdev->base + gdev->ngpio - 1,
++ base, base + (int)ngpios - 1,
+ gc->label ? : "generic", ret);
+ }
+- kfree(gdev);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_add_data_with_key);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index 3b025aace2831..eb4c0523e42d5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -167,7 +167,11 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
+ amdgpu_sync_free(&job->sync);
+ amdgpu_sync_free(&job->sched_sync);
+
+- dma_fence_put(&job->hw_fence);
++ /* only put the hw fence if has embedded fence */
++ if (!job->hw_fence.ops)
++ kfree(job);
++ else
++ dma_fence_put(&job->hw_fence);
+ }
+
+ void amdgpu_job_free(struct amdgpu_job *job)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+index 60c608144480a..ecb8db731081b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+@@ -161,6 +161,7 @@
+ #define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
+ #define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10)
+ #define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG (1 << 11)
+
+ #define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001
+ #define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001
+@@ -170,6 +171,9 @@
+ #define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2)
+ #define VCN_CODEC_DISABLE_MASK_H264 (1 << 3)
+
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU (0)
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_APU (1)
++
+ enum fw_queue_mode {
+ FW_QUEUE_RING_RESET = 1,
+ FW_QUEUE_DPG_HOLD_OFF = 2,
+@@ -323,6 +327,9 @@ struct amdgpu_vcn4_fw_shared {
+ struct amdgpu_fw_shared_unified_queue_struct sq;
+ uint8_t pad1[8];
+ struct amdgpu_fw_shared_fw_logging fw_log;
++ uint8_t pad2[20];
++ uint32_t pad3[13];
++ struct amdgpu_fw_shared_smu_interface_info smu_dpm_interface;
+ };
+
+ struct amdgpu_vcn_fwlog {
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 65181efba50ec..408b0f399cfc4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -980,13 +980,13 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
+
+
+ /**
+- * sdma_v4_0_gfx_stop - stop the gfx async dma engines
++ * sdma_v4_0_gfx_enable - enable the gfx async dma engines
+ *
+ * @adev: amdgpu_device pointer
+- *
+- * Stop the gfx async dma ring buffers (VEGA10).
++ * @enable: enable SDMA RB/IB
++ * control the gfx async dma ring buffers (VEGA10).
+ */
+-static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
++static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable)
+ {
+ struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
+ u32 rb_cntl, ib_cntl;
+@@ -1001,10 +1001,10 @@ static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
+ }
+
+ rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL);
+- rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
++ rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, enable ? 1 : 0);
+ WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl);
+ ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL);
+- ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
++ ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, enable ? 1 : 0);
+ WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl);
+ }
+ }
+@@ -1131,7 +1131,7 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
+ int i;
+
+ if (!enable) {
+- sdma_v4_0_gfx_stop(adev);
++ sdma_v4_0_gfx_enable(adev, enable);
+ sdma_v4_0_rlc_stop(adev);
+ if (adev->sdma.has_page_queue)
+ sdma_v4_0_page_stop(adev);
+@@ -2043,8 +2043,10 @@ static int sdma_v4_0_suspend(void *handle)
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ /* SMU saves SDMA state for us */
+- if (adev->in_s0ix)
++ if (adev->in_s0ix) {
++ sdma_v4_0_gfx_enable(adev, false);
+ return 0;
++ }
+
+ return sdma_v4_0_hw_fini(adev);
+ }
+@@ -2054,8 +2056,12 @@ static int sdma_v4_0_resume(void *handle)
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ /* SMU restores SDMA state for us */
+- if (adev->in_s0ix)
++ if (adev->in_s0ix) {
++ sdma_v4_0_enable(adev, true);
++ sdma_v4_0_gfx_enable(adev, true);
++ amdgpu_ttm_set_buffer_funcs_status(adev, true);
+ return 0;
++ }
+
+ return sdma_v4_0_hw_init(adev);
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+index fb2d74f304481..c5afb5bc9eb60 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+@@ -132,6 +132,10 @@ static int vcn_v4_0_sw_init(void *handle)
+ fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
+ fw_shared->sq.is_enabled = 1;
+
++ fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
++ fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
++ AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
++
+ if (amdgpu_vcnfw_log)
+ amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+index fb729674953b2..de9fa534b77af 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+ enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
+
++ // Don't program 0xF into the register field. Not valid since
++ // K1 / K2 field is only 1 / 2 bits wide
++ if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
++
+ dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
+ if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2))
+ return;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+index f4d1b83979fe0..a0741794db62a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+@@ -349,6 +349,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
+ odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+
+ if (is_dp_128b_132b_signal(pipe_ctx)) {
++ *k1_div = PIXEL_RATE_DIV_BY_1;
+ *k2_div = PIXEL_RATE_DIV_BY_1;
+ } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+ *k1_div = PIXEL_RATE_DIV_BY_1;
+@@ -356,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
+ *k2_div = PIXEL_RATE_DIV_BY_2;
+ else
+ *k2_div = PIXEL_RATE_DIV_BY_4;
+- } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
++ } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
+ if (two_pix_per_container) {
+ *k1_div = PIXEL_RATE_DIV_BY_1;
+ *k2_div = PIXEL_RATE_DIV_BY_2;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+index 6640d0ac43040..6dd8dadd68a5d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
+
+ // Don't program 0xF into the register field. Not valid since
+ // K1 / K2 field is only 1 / 2 bits wide
+- if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
++ if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
++ BREAK_TO_DEBUGGER();
+ return;
++ }
+
+ dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
+ if (k1 == cur_k1 && k2 == cur_k2)
+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 bbc0bfbec6c42..3128c111c6198 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -1171,6 +1171,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
+ odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+
+ if (is_dp_128b_132b_signal(pipe_ctx)) {
++ *k1_div = PIXEL_RATE_DIV_BY_1;
+ *k2_div = PIXEL_RATE_DIV_BY_1;
+ } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+ *k1_div = PIXEL_RATE_DIV_BY_1;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 7c37575d69c73..0ef11fb338e9f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -103,7 +103,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ mall_alloc_width_blk_aligned = full_vp_width_blk_aligned;
+
+ /* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */
+- mall_alloc_height_blk_aligned = (pipe->stream->timing.v_addressable - 1 + mblk_height - 1) /
++ mall_alloc_height_blk_aligned = (pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) /
+ mblk_height * mblk_height + mblk_height;
+
+ /* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c;
+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 2f996fdaa70dd..07c56e231b045 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
+@@ -1803,7 +1803,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+
+ if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
+ dm_dram_clock_change_unsupported) {
+- int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1;
++ int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1;
+
+ min_dram_speed_mts =
+ dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+index 2051ddaa641a7..6ec0947ace9cb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+@@ -1152,7 +1152,7 @@ struct vba_vars_st {
+ double UrgBurstFactorLumaPre[DC__NUM_DPP__MAX];
+ double UrgBurstFactorChromaPre[DC__NUM_DPP__MAX];
+ bool NotUrgentLatencyHidingPre[DC__NUM_DPP__MAX];
+- bool LinkCapacitySupport[DC__NUM_DPP__MAX];
++ bool LinkCapacitySupport[DC__VOLTAGE_STATES];
+ bool VREADY_AT_OR_AFTER_VSYNC[DC__NUM_DPP__MAX];
+ unsigned int MIN_DST_Y_NEXT_START[DC__NUM_DPP__MAX];
+ unsigned int VFrontPorch[DC__NUM_DPP__MAX];
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 40d8ca37f5bc8..aa51c61a78c71 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -2720,6 +2720,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ * if supported. In any case the default RGB888 format is added
+ */
+
++ /* Default 8bit RGB fallback */
++ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
++
+ if (max_bpc >= 16 && info->bpc == 16) {
+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+@@ -2753,9 +2756,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+
+- /* Default 8bit RGB fallback */
+- output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+-
+ *num_output_fmts = i;
+
+ return output_fmts;
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+index d6dd4d99a229a..d72bd1392c849 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+@@ -906,9 +906,9 @@ static void ti_sn_bridge_set_video_timings(struct ti_sn65dsi86 *pdata)
+ &pdata->bridge.encoder->crtc->state->adjusted_mode;
+ u8 hsync_polarity = 0, vsync_polarity = 0;
+
+- if (mode->flags & DRM_MODE_FLAG_PHSYNC)
++ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ hsync_polarity = CHA_HSYNC_POLARITY;
+- if (mode->flags & DRM_MODE_FLAG_PVSYNC)
++ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ vsync_polarity = CHA_VSYNC_POLARITY;
+
+ ti_sn65dsi86_write_u16(pdata, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG,
+diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
+index 904fc893c905b..eb9e722a865b7 100644
+--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
+@@ -571,12 +571,20 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
+ {
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+- int ret;
+
+ WARN_ON(shmem->base.import_attach);
+
+- ret = drm_gem_shmem_get_pages(shmem);
+- WARN_ON_ONCE(ret != 0);
++ mutex_lock(&shmem->pages_lock);
++
++ /*
++ * We should have already pinned the pages when the buffer was first
++ * mmap'd, vm_open() just grabs an additional reference for the new
++ * mm the vma is getting copied into (ie. on fork()).
++ */
++ if (!WARN_ON_ONCE(!shmem->pages_use_count))
++ shmem->pages_use_count++;
++
++ mutex_unlock(&shmem->pages_lock);
+
+ drm_gem_vm_open(vma);
+ }
+@@ -622,10 +630,8 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct
+ }
+
+ ret = drm_gem_shmem_get_pages(shmem);
+- if (ret) {
+- drm_gem_vm_close(vma);
++ if (ret)
+ return ret;
+- }
+
+ vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
+index fc5d94862ef32..d0f20bd0e51ae 100644
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -3717,12 +3717,16 @@ out:
+
+ static u8 bigjoiner_pipes(struct drm_i915_private *i915)
+ {
++ u8 pipes;
++
+ if (DISPLAY_VER(i915) >= 12)
+- return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
++ pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
+ else if (DISPLAY_VER(i915) >= 11)
+- return BIT(PIPE_B) | BIT(PIPE_C);
++ pipes = BIT(PIPE_B) | BIT(PIPE_C);
+ else
+- return 0;
++ pipes = 0;
++
++ return pipes & INTEL_INFO(i915)->display.pipe_mask;
+ }
+
+ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+index 089046fa21bea..50fa3df0bc0ca 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+@@ -1085,21 +1085,21 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
+ reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
+
+ /* Pin mksGuestStat user pages and store those in the instance descriptor */
+- nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, FOLL_LONGTERM, pages_stat, NULL);
++ nr_pinned_stat = pin_user_pages_fast(arg->stat, num_pages_stat, FOLL_LONGTERM, pages_stat);
+ if (num_pages_stat != nr_pinned_stat)
+ goto err_pin_stat;
+
+ for (i = 0; i < num_pages_stat; ++i)
+ pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
+
+- nr_pinned_info = pin_user_pages(arg->info, num_pages_info, FOLL_LONGTERM, pages_info, NULL);
++ nr_pinned_info = pin_user_pages_fast(arg->info, num_pages_info, FOLL_LONGTERM, pages_info);
+ if (num_pages_info != nr_pinned_info)
+ goto err_pin_info;
+
+ for (i = 0; i < num_pages_info; ++i)
+ pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
+
+- nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, FOLL_LONGTERM, pages_strs, NULL);
++ nr_pinned_strs = pin_user_pages_fast(arg->strs, num_pages_strs, FOLL_LONGTERM, pages_strs);
+ if (num_pages_strs != nr_pinned_strs)
+ goto err_pin_strs;
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+index c89ad3a2d141c..753d421a27ad8 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+@@ -950,6 +950,10 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
+ struct drm_device *dev = &dev_priv->drm;
+ int i, ret;
+
++ /* Screen objects won't work if GMR's aren't available */
++ if (!dev_priv->has_gmr)
++ return -ENOSYS;
++
+ if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
+ return -ENOSYS;
+ }
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index b7f5566e338d7..e4974c27ca3d8 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1315,6 +1315,9 @@ static s32 snto32(__u32 value, unsigned n)
+ if (!value || !n)
+ return 0;
+
++ if (n > 32)
++ n = 32;
++
+ switch (n) {
+ case 8: return ((__s8)value);
+ case 16: return ((__s16)value);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 256795ed6247e..86e754b9400ff 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -274,6 +274,7 @@
+ #define USB_DEVICE_ID_CH_AXIS_295 0x001c
+
+ #define USB_VENDOR_ID_CHERRY 0x046a
++#define USB_DEVICE_ID_CHERRY_MOUSE_000C 0x000c
+ #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
+ #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027
+
+@@ -917,6 +918,7 @@
+ #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
+ #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
+ #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0
++#define USB_DEVICE_ID_MS_MOUSE_0783 0x0783
+
+ #define USB_VENDOR_ID_MOJO 0x8282
+ #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
+@@ -1215,6 +1217,7 @@
+ #define USB_DEVICE_ID_SYNAPTICS_DELL_K15A 0x6e21
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002 0x73f4
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5
++#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017 0x73f6
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7
+
+ #define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
+@@ -1379,6 +1382,7 @@
+
+ #define USB_VENDOR_ID_PRIMAX 0x0461
+ #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22
++#define USB_DEVICE_ID_PRIMAX_MOUSE_4E2A 0x4e2a
+ #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
+ #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72
+ #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f
+diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c
+index 430fa4f52ed3b..75ebfcf318896 100644
+--- a/drivers/hid/hid-ite.c
++++ b/drivers/hid/hid-ite.c
+@@ -121,6 +121,11 @@ static const struct hid_device_id ite_devices[] = {
+ USB_VENDOR_ID_SYNAPTICS,
+ USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003),
+ .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
++ /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
++ USB_VENDOR_ID_SYNAPTICS,
++ USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017),
++ .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, ite_devices);
+diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
+index 5e6a0cef2a06d..e3fcf1353fb3b 100644
+--- a/drivers/hid/hid-lg4ff.c
++++ b/drivers/hid/hid-lg4ff.c
+@@ -872,6 +872,12 @@ static ssize_t lg4ff_alternate_modes_store(struct device *dev, struct device_att
+ return -ENOMEM;
+
+ i = strlen(lbuf);
++
++ if (i == 0) {
++ kfree(lbuf);
++ return -EINVAL;
++ }
++
+ if (lbuf[i-1] == '\n') {
+ if (i == 1) {
+ kfree(lbuf);
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 50e1c717fc0a3..0e9702c7f7d6c 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -54,6 +54,7 @@ static const struct hid_device_id hid_quirks[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
++ { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
+@@ -122,6 +123,7 @@ static const struct hid_device_id hid_quirks[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
++ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
+@@ -146,6 +148,7 @@ static const struct hid_device_id hid_quirks[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
+diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
+index ff46604ef1d8c..683350596ea62 100644
+--- a/drivers/hid/hid-uclogic-core.c
++++ b/drivers/hid/hid-uclogic-core.c
+@@ -192,6 +192,7 @@ static int uclogic_probe(struct hid_device *hdev,
+ * than the pen, so use QUIRK_MULTI_INPUT for all tablets.
+ */
+ hdev->quirks |= HID_QUIRK_MULTI_INPUT;
++ hdev->quirks |= HID_QUIRK_HIDINPUT_FORCE;
+
+ /* Allocate and assign driver data */
+ drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
+index 81ca22398ed55..ce6cf6b18ae6c 100644
+--- a/drivers/hid/hid-uclogic-rdesc.c
++++ b/drivers/hid/hid-uclogic-rdesc.c
+@@ -1119,7 +1119,7 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
+ p[sizeof(btn_head)] < param_num) {
+ v = param_list[p[sizeof(btn_head)]];
+ put_unaligned((__u8)0x2A, p); /* Usage Maximum */
+- put_unaligned_le16((__force u16)cpu_to_le16(v), p + 1);
++ put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1));
+ p += sizeof(btn_head) + 1;
+ } else {
+ p++;
+diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
+index 5273ee2bb1343..d65abe65ce739 100644
+--- a/drivers/hid/i2c-hid/Kconfig
++++ b/drivers/hid/i2c-hid/Kconfig
+@@ -66,6 +66,6 @@ endmenu
+
+ config I2C_HID_CORE
+ tristate
+- default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_GOODIX=y
+- default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_GOODIX=m
++ default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_ELAN=y || I2C_HID_OF_GOODIX=y
++ default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_ELAN=m || I2C_HID_OF_GOODIX=m
+ select HID
+diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
+index b203c1e26353e..4eac35c4ea3b7 100644
+--- a/drivers/media/common/videobuf2/videobuf2-core.c
++++ b/drivers/media/common/videobuf2/videobuf2-core.c
+@@ -813,7 +813,13 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
+ num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
+ memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++ /*
++ * Set this now to ensure that drivers see the correct q->memory value
++ * in the queue_setup op.
++ */
++ mutex_lock(&q->mmap_lock);
+ q->memory = memory;
++ mutex_unlock(&q->mmap_lock);
+ set_queue_coherency(q, non_coherent_mem);
+
+ /*
+@@ -823,22 +829,27 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
+ plane_sizes, q->alloc_devs);
+ if (ret)
+- return ret;
++ goto error;
+
+ /* Check that driver has set sane values */
+- if (WARN_ON(!num_planes))
+- return -EINVAL;
++ if (WARN_ON(!num_planes)) {
++ ret = -EINVAL;
++ goto error;
++ }
+
+ for (i = 0; i < num_planes; i++)
+- if (WARN_ON(!plane_sizes[i]))
+- return -EINVAL;
++ if (WARN_ON(!plane_sizes[i])) {
++ ret = -EINVAL;
++ goto error;
++ }
+
+ /* Finally, allocate buffers and video memory */
+ allocated_buffers =
+ __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
+ if (allocated_buffers == 0) {
+ dprintk(q, 1, "memory allocation failed\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto error;
+ }
+
+ /*
+@@ -879,7 +890,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ if (ret < 0) {
+ /*
+ * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+- * from q->num_buffers.
++ * from q->num_buffers and it will reset q->memory to
++ * VB2_MEMORY_UNKNOWN.
+ */
+ __vb2_queue_free(q, allocated_buffers);
+ mutex_unlock(&q->mmap_lock);
+@@ -895,6 +907,12 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ q->waiting_for_buffers = !q->is_output;
+
+ return 0;
++
++error:
++ mutex_lock(&q->mmap_lock);
++ q->memory = VB2_MEMORY_UNKNOWN;
++ mutex_unlock(&q->mmap_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
+
+@@ -906,6 +924,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ unsigned int num_planes = 0, num_buffers, allocated_buffers;
+ unsigned plane_sizes[VB2_MAX_PLANES] = { };
+ bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
++ bool no_previous_buffers = !q->num_buffers;
+ int ret;
+
+ if (q->num_buffers == VB2_MAX_FRAME) {
+@@ -913,13 +932,19 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ return -ENOBUFS;
+ }
+
+- if (!q->num_buffers) {
++ if (no_previous_buffers) {
+ if (q->waiting_in_dqbuf && *count) {
+ dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
+ return -EBUSY;
+ }
+ memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++ /*
++ * Set this now to ensure that drivers see the correct q->memory
++ * value in the queue_setup op.
++ */
++ mutex_lock(&q->mmap_lock);
+ q->memory = memory;
++ mutex_unlock(&q->mmap_lock);
+ q->waiting_for_buffers = !q->is_output;
+ set_queue_coherency(q, non_coherent_mem);
+ } else {
+@@ -945,14 +970,15 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ ret = call_qop(q, queue_setup, q, &num_buffers,
+ &num_planes, plane_sizes, q->alloc_devs);
+ if (ret)
+- return ret;
++ goto error;
+
+ /* Finally, allocate buffers and video memory */
+ allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
+ num_planes, plane_sizes);
+ if (allocated_buffers == 0) {
+ dprintk(q, 1, "memory allocation failed\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto error;
+ }
+
+ /*
+@@ -983,7 +1009,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ if (ret < 0) {
+ /*
+ * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+- * from q->num_buffers.
++ * from q->num_buffers and it will reset q->memory to
++ * VB2_MEMORY_UNKNOWN.
+ */
+ __vb2_queue_free(q, allocated_buffers);
+ mutex_unlock(&q->mmap_lock);
+@@ -998,6 +1025,14 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ *count = allocated_buffers;
+
+ return 0;
++
++error:
++ if (no_previous_buffers) {
++ mutex_lock(&q->mmap_lock);
++ q->memory = VB2_MEMORY_UNKNOWN;
++ mutex_unlock(&q->mmap_lock);
++ }
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_create_bufs);
+
+@@ -2164,6 +2199,22 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+ struct vb2_buffer *vb;
+ unsigned int buffer, plane;
+
++ /*
++ * Sanity checks to ensure the lock is held, MEMORY_MMAP is
++ * used and fileio isn't active.
++ */
++ lockdep_assert_held(&q->mmap_lock);
++
++ if (q->memory != VB2_MEMORY_MMAP) {
++ dprintk(q, 1, "queue is not currently set up for mmap\n");
++ return -EINVAL;
++ }
++
++ if (vb2_fileio_is_active(q)) {
++ dprintk(q, 1, "file io in progress\n");
++ return -EBUSY;
++ }
++
+ /*
+ * Go over all buffers and their planes, comparing the given offset
+ * with an offset assigned to each plane. If a match is found,
+@@ -2265,11 +2316,6 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+ int ret;
+ unsigned long length;
+
+- if (q->memory != VB2_MEMORY_MMAP) {
+- dprintk(q, 1, "queue is not currently set up for mmap\n");
+- return -EINVAL;
+- }
+-
+ /*
+ * Check memory area access mode.
+ */
+@@ -2291,14 +2337,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+
+ mutex_lock(&q->mmap_lock);
+
+- if (vb2_fileio_is_active(q)) {
+- dprintk(q, 1, "mmap: file io in progress\n");
+- ret = -EBUSY;
+- goto unlock;
+- }
+-
+ /*
+- * Find the plane corresponding to the offset passed by userspace.
++ * Find the plane corresponding to the offset passed by userspace. This
++ * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ */
+ ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ if (ret)
+@@ -2351,22 +2392,25 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+ void *vaddr;
+ int ret;
+
+- if (q->memory != VB2_MEMORY_MMAP) {
+- dprintk(q, 1, "queue is not currently set up for mmap\n");
+- return -EINVAL;
+- }
++ mutex_lock(&q->mmap_lock);
+
+ /*
+- * Find the plane corresponding to the offset passed by userspace.
++ * Find the plane corresponding to the offset passed by userspace. This
++ * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ */
+ ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ if (ret)
+- return ret;
++ goto unlock;
+
+ vb = q->bufs[buffer];
+
+ vaddr = vb2_plane_vaddr(vb, plane);
++ mutex_unlock(&q->mmap_lock);
+ return vaddr ? (unsigned long)vaddr : -EINVAL;
++
++unlock:
++ mutex_unlock(&q->mmap_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
+ #endif
+diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
+index 003c32fed3f75..942d0005c55e8 100644
+--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
++++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
+@@ -145,6 +145,8 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ const struct v4l2_bt_timings *bt = &t->bt;
+ const struct v4l2_bt_timings_cap *cap = &dvcap->bt;
+ u32 caps = cap->capabilities;
++ const u32 max_vert = 10240;
++ u32 max_hor = 3 * bt->width;
+
+ if (t->type != V4L2_DV_BT_656_1120)
+ return false;
+@@ -166,14 +168,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ if (!bt->interlaced &&
+ (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
+ return false;
+- if (bt->hfrontporch > 2 * bt->width ||
+- bt->hsync > 1024 || bt->hbackporch > 1024)
++ /*
++ * Some video receivers cannot properly separate the frontporch,
++ * backporch and sync values, and instead they only have the total
++ * blanking. That can be assigned to any of these three fields.
++ * So just check that none of these are way out of range.
++ */
++ if (bt->hfrontporch > max_hor ||
++ bt->hsync > max_hor || bt->hbackporch > max_hor)
+ return false;
+- if (bt->vfrontporch > 4096 ||
+- bt->vsync > 128 || bt->vbackporch > 4096)
++ if (bt->vfrontporch > max_vert ||
++ bt->vsync > max_vert || bt->vbackporch > max_vert)
+ return false;
+- if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
+- bt->il_vsync > 128 || bt->il_vbackporch > 4096))
++ if (bt->interlaced && (bt->il_vfrontporch > max_vert ||
++ bt->il_vsync > max_vert || bt->il_vbackporch > max_vert))
+ return false;
+ return fnc == NULL || fnc(t, fnc_handle);
+ }
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 76dd5ff1d99d5..c2939621b683c 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3247,7 +3247,7 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
+ goto out;
+
+ saddr = &combined->ip6.saddr;
+- daddr = &combined->ip6.saddr;
++ daddr = &combined->ip6.daddr;
+
+ slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
+ __func__, slave->dev->name, bond_slave_state(slave),
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index ed3d0b8989a07..dc7192ecb001f 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -796,9 +796,9 @@ static int can327_netdev_close(struct net_device *dev)
+
+ netif_stop_queue(dev);
+
+- /* Give UART one final chance to flush. */
+- clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
+- flush_work(&elm->tx_work);
++ /* We don't flush the UART TX queue here, as we want final stop
++ * commands (like the above dummy char) to be flushed out.
++ */
+
+ can_rx_offload_disable(&elm->offload);
+ elm->can.state = CAN_STATE_STOPPED;
+@@ -1069,12 +1069,15 @@ static void can327_ldisc_close(struct tty_struct *tty)
+ {
+ struct can327 *elm = (struct can327 *)tty->disc_data;
+
+- /* unregister_netdev() calls .ndo_stop() so we don't have to.
+- * Our .ndo_stop() also flushes the TTY write wakeup handler,
+- * so we can safely set elm->tty = NULL after this.
+- */
++ /* unregister_netdev() calls .ndo_stop() so we don't have to. */
+ unregister_candev(elm->dev);
+
++ /* Give UART one final chance to flush.
++ * No need to clear TTY_DO_WRITE_WAKEUP since .write_wakeup() is
++ * serialised against .close() and will not be called once we return.
++ */
++ flush_work(&elm->tx_work);
++
+ /* Mark channel as dead */
+ spin_lock_bh(&elm->lock);
+ tty->disc_data = NULL;
+diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
+index fbb34139daa1a..f4db77007c134 100644
+--- a/drivers/net/can/slcan/slcan-core.c
++++ b/drivers/net/can/slcan/slcan-core.c
+@@ -864,12 +864,14 @@ static void slcan_close(struct tty_struct *tty)
+ {
+ struct slcan *sl = (struct slcan *)tty->disc_data;
+
+- /* unregister_netdev() calls .ndo_stop() so we don't have to.
+- * Our .ndo_stop() also flushes the TTY write wakeup handler,
+- * so we can safely set sl->tty = NULL after this.
+- */
+ unregister_candev(sl->dev);
+
++ /*
++ * The netdev needn't be UP (so .ndo_stop() is not called). Hence make
++ * sure this is not running before freeing it up.
++ */
++ flush_work(&sl->tx_work);
++
+ /* Mark channel as dead */
+ spin_lock_bh(&sl->lock);
+ tty->disc_data = NULL;
+diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
+index 81b88e9e5bdc0..42323f5e6f3a0 100644
+--- a/drivers/net/can/usb/esd_usb.c
++++ b/drivers/net/can/usb/esd_usb.c
+@@ -234,6 +234,10 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
+ u8 rxerr = msg->msg.rx.data[2];
+ u8 txerr = msg->msg.rx.data[3];
+
++ netdev_dbg(priv->netdev,
++ "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
++ msg->msg.rx.dlc, state, ecc, rxerr, txerr);
++
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (skb == NULL) {
+ stats->rx_dropped++;
+@@ -260,6 +264,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
+ break;
+ default:
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
++ txerr = 0;
++ rxerr = 0;
+ break;
+ }
+ } else {
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 07e9a4da924c5..546d90dae9331 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -825,10 +825,13 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
+
+ chip->info->ops->phylink_get_caps(chip, port, config);
+
+- /* Internal ports need GMII for PHYLIB */
+- if (mv88e6xxx_phy_is_internal(ds, port))
++ if (mv88e6xxx_phy_is_internal(ds, port)) {
++ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++ config->supported_interfaces);
++ /* Internal ports with no phy-mode need GMII for PHYLIB */
+ __set_bit(PHY_INTERFACE_MODE_GMII,
+ config->supported_interfaces);
++ }
+ }
+
+ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
+diff --git a/drivers/net/dsa/sja1105/sja1105_devlink.c b/drivers/net/dsa/sja1105/sja1105_devlink.c
+index 10c6fea1227fa..bdbbff2a79095 100644
+--- a/drivers/net/dsa/sja1105/sja1105_devlink.c
++++ b/drivers/net/dsa/sja1105/sja1105_devlink.c
+@@ -95,6 +95,8 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds)
+ if (IS_ERR(region)) {
+ while (--i >= 0)
+ dsa_devlink_region_destroy(priv->regions[i]);
++
++ kfree(priv->regions);
+ return PTR_ERR(region);
+ }
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index b03d0d0c3dbf5..2cb8fa2494cbe 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1038,7 +1038,7 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)
+
+ policing[bcast].sharindx = port;
+ /* Only SJA1110 has multicast policers */
+- if (mcast <= table->ops->max_entry_count)
++ if (mcast < table->ops->max_entry_count)
+ policing[mcast].sharindx = port;
+ }
+
+diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
+index 447dc64a17e5d..4ce8367bb81c2 100644
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -258,6 +258,7 @@ static int greth_init_rings(struct greth_private *greth)
+ if (dma_mapping_error(greth->dev, dma_addr)) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Could not create initial DMA mapping\n");
++ dev_kfree_skb(skb);
+ goto cleanup;
+ }
+ greth->rx_skbuff[i] = skb;
+diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
+index 1cd3c289f49be..cd1706909044d 100644
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -71,13 +71,14 @@ config BCM63XX_ENET
+ config BCMGENET
+ tristate "Broadcom GENET internal MAC support"
+ depends on HAS_IOMEM
++ depends on PTP_1588_CLOCK_OPTIONAL || !ARCH_BCM2835
+ select MII
+ select PHYLIB
+ select FIXED_PHY
+ select BCM7XXX_PHY
+ select MDIO_BCM_UNIMAC
+ select DIMLIB
+- select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL)
++ select BROADCOM_PHY if ARCH_BCM2835
+ help
+ This driver supports the built-in Ethernet MACs found in the
+ Broadcom BCM7xxx Set Top Box family chipset.
+diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+index 768ea426d49f4..745bd2dfb7429 100644
+--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
++++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+@@ -2240,7 +2240,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(dev, "Failed to register netdevice\n");
+- goto err_unregister_interrupts;
++ goto err_destroy_workqueue;
+ }
+
+ nic->msg_enable = debug;
+@@ -2249,6 +2249,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ return 0;
+
++err_destroy_workqueue:
++ destroy_workqueue(nic->nicvf_rx_mode_wq);
+ err_unregister_interrupts:
+ nicvf_unregister_interrupts(nic);
+ err_free_netdev:
+diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
+index cacd454ac696c..c39b866e2582d 100644
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
+@@ -132,6 +132,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
+ dev_err(dev, "DMA mapping failed\n");
++ kfree(cmd_buff);
+ return -EFAULT;
+ }
+
+@@ -142,6 +143,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
+ DMA_TO_DEVICE);
+ if (err) {
+ dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err);
++ kfree(cmd_buff);
+ return err;
+ }
+
+@@ -172,6 +174,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
+ dev_err(dev, "DMA mapping failed\n");
++ kfree(cmd_buff);
+ return -EFAULT;
+ }
+
+@@ -182,6 +185,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
+ DMA_TO_DEVICE);
+ if (err) {
+ dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err);
++ kfree(cmd_buff);
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/hisilicon/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi_femac.c
+index 93846bace0285..ce2571c16e431 100644
+--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
++++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
+@@ -283,7 +283,7 @@ static int hisi_femac_rx(struct net_device *dev, int limit)
+ skb->protocol = eth_type_trans(skb, dev);
+ napi_gro_receive(&priv->napi, skb);
+ dev->stats.rx_packets++;
+- dev->stats.rx_bytes += skb->len;
++ dev->stats.rx_bytes += len;
+ next:
+ pos = (pos + 1) % rxq->num;
+ if (rx_pkts_num >= limit)
+diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+index d7e62eca050f4..b981b6cbe6fff 100644
+--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
++++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+@@ -550,7 +550,7 @@ static int hix5hd2_rx(struct net_device *dev, int limit)
+ skb->protocol = eth_type_trans(skb, dev);
+ napi_gro_receive(&priv->napi, skb);
+ dev->stats.rx_packets++;
+- dev->stats.rx_bytes += skb->len;
++ dev->stats.rx_bytes += len;
+ next:
+ pos = dma_ring_incr(pos, RX_DESC_NUM);
+ }
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index 321f2a95ae3ab..da113f5011e99 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -5936,9 +5936,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+ e1000_tx_queue(tx_ring, tx_flags, count);
+ /* Make sure there is space in the ring for the next send. */
+ e1000_maybe_stop_tx(tx_ring,
+- (MAX_SKB_FRAGS *
++ ((MAX_SKB_FRAGS + 1) *
+ DIV_ROUND_UP(PAGE_SIZE,
+- adapter->tx_fifo_limit) + 2));
++ adapter->tx_fifo_limit) + 4));
+
+ if (!netdev_xmit_more() ||
+ netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index 6f0d4160ff82f..d9368f7669aab 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -4464,11 +4464,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
+ return -EOPNOTSUPP;
+
+ /* First 4 bytes of L4 header */
+- if (usr_ip4_spec->l4_4_bytes == htonl(0xFFFFFFFF))
+- new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
+- else if (!usr_ip4_spec->l4_4_bytes)
+- new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
+- else
++ if (usr_ip4_spec->l4_4_bytes)
+ return -EOPNOTSUPP;
+
+ /* Filtering on Type of Service is not supported. */
+@@ -4507,11 +4503,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
+ else
+ return -EOPNOTSUPP;
+
+- if (usr_ip6_spec->l4_4_bytes == htonl(0xFFFFFFFF))
+- new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
+- else if (!usr_ip6_spec->l4_4_bytes)
+- new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
+- else
++ if (usr_ip6_spec->l4_4_bytes)
+ return -EOPNOTSUPP;
+
+ /* Filtering on Traffic class is not supported. */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 023685cca2c1c..e53ea7ed0b1d2 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -10661,6 +10661,21 @@ static int i40e_rebuild_channels(struct i40e_vsi *vsi)
+ return 0;
+ }
+
++/**
++ * i40e_clean_xps_state - clean xps state for every tx_ring
++ * @vsi: ptr to the VSI
++ **/
++static void i40e_clean_xps_state(struct i40e_vsi *vsi)
++{
++ int i;
++
++ if (vsi->tx_rings)
++ for (i = 0; i < vsi->num_queue_pairs; i++)
++ if (vsi->tx_rings[i])
++ clear_bit(__I40E_TX_XPS_INIT_DONE,
++ vsi->tx_rings[i]->state);
++}
++
+ /**
+ * i40e_prep_for_reset - prep for the core to reset
+ * @pf: board private structure
+@@ -10685,8 +10700,10 @@ static void i40e_prep_for_reset(struct i40e_pf *pf)
+ i40e_pf_quiesce_all_vsi(pf);
+
+ for (v = 0; v < pf->num_alloc_vsi; v++) {
+- if (pf->vsi[v])
++ if (pf->vsi[v]) {
++ i40e_clean_xps_state(pf->vsi[v]);
+ pf->vsi[v]->seid = 0;
++ }
+ }
+
+ i40e_shutdown_adminq(&pf->hw);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 72ddcefc45b1e..635f93d603186 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1578,6 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ i40e_cleanup_reset_vf(vf);
+
+ i40e_flush(hw);
++ usleep_range(20000, 40000);
+ clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
+
+ return true;
+@@ -1701,6 +1702,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ }
+
+ i40e_flush(hw);
++ usleep_range(20000, 40000);
+ clear_bit(__I40E_VF_DISABLE, pf->state);
+
+ return true;
+diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+index c14fc871dd417..677893f891edd 100644
+--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+@@ -1413,6 +1413,8 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
+ *data = 1;
+ return -1;
+ }
++ wr32(E1000_IVAR_MISC, E1000_IVAR_VALID << 8);
++ wr32(E1000_EIMS, BIT(0));
+ } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
+ shared_int = false;
+ if (request_irq(irq,
+diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
+index 0caa2df87c044..85c93ba6a82b7 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4271,7 +4271,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
+ /* Use the cpu associated to the rxq when it is online, in all
+ * the other cases, use the cpu 0 which can't be offline.
+ */
+- if (cpu_online(pp->rxq_def))
++ if (pp->rxq_def < nr_cpu_ids && cpu_online(pp->rxq_def))
+ elected_cpu = pp->rxq_def;
+
+ max_cpu = num_present_cpus();
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+index e64318c110fdd..6a01ab1a6e6f3 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+@@ -1134,7 +1134,12 @@ int otx2_init_tc(struct otx2_nic *nic)
+ return err;
+
+ tc->flow_ht_params = tc_flow_ht_params;
+- return rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
++ err = rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
++ if (err) {
++ kfree(tc->tc_entries_bitmap);
++ tc->tc_entries_bitmap = NULL;
++ }
++ return err;
+ }
+ EXPORT_SYMBOL(otx2_init_tc);
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 48f86e12f5c05..bbe810f3b373a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -201,9 +201,8 @@ static void mlx5_ldev_free(struct kref *ref)
+ if (ldev->nb.notifier_call)
+ unregister_netdevice_notifier_net(&init_net, &ldev->nb);
+ mlx5_lag_mp_cleanup(ldev);
+- mlx5_lag_mpesw_cleanup(ldev);
+- cancel_work_sync(&ldev->mpesw_work);
+ destroy_workqueue(ldev->wq);
++ mlx5_lag_mpesw_cleanup(ldev);
+ mutex_destroy(&ldev->lock);
+ kfree(ldev);
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+index ce2ce8ccbd70e..f30ac2de639f9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+@@ -50,6 +50,19 @@ struct lag_tracker {
+ enum netdev_lag_hash hash_type;
+ };
+
++enum mpesw_op {
++ MLX5_MPESW_OP_ENABLE,
++ MLX5_MPESW_OP_DISABLE,
++};
++
++struct mlx5_mpesw_work_st {
++ struct work_struct work;
++ struct mlx5_lag *lag;
++ enum mpesw_op op;
++ struct completion comp;
++ int result;
++};
++
+ /* LAG data of a ConnectX card.
+ * It serves both its phys functions.
+ */
+@@ -66,7 +79,6 @@ struct mlx5_lag {
+ struct lag_tracker tracker;
+ struct workqueue_struct *wq;
+ struct delayed_work bond_work;
+- struct work_struct mpesw_work;
+ struct notifier_block nb;
+ struct lag_mp lag_mp;
+ struct mlx5_lag_port_sel port_sel;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+index f643202b29c6c..c17e8f1ec9146 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+@@ -7,63 +7,95 @@
+ #include "eswitch.h"
+ #include "lib/mlx5.h"
+
+-void mlx5_mpesw_work(struct work_struct *work)
++static int add_mpesw_rule(struct mlx5_lag *ldev)
+ {
+- struct mlx5_lag *ldev = container_of(work, struct mlx5_lag, mpesw_work);
++ struct mlx5_core_dev *dev = ldev->pf[MLX5_LAG_P1].dev;
++ int err;
+
+- mutex_lock(&ldev->lock);
+- mlx5_disable_lag(ldev);
+- mutex_unlock(&ldev->lock);
+-}
++ if (atomic_add_return(1, &ldev->lag_mpesw.mpesw_rule_count) != 1)
++ return 0;
+
+-static void mlx5_lag_disable_mpesw(struct mlx5_core_dev *dev)
+-{
+- struct mlx5_lag *ldev = dev->priv.lag;
++ if (ldev->mode != MLX5_LAG_MODE_NONE) {
++ err = -EINVAL;
++ goto out_err;
++ }
+
+- if (!queue_work(ldev->wq, &ldev->mpesw_work))
+- mlx5_core_warn(dev, "failed to queue work\n");
++ err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
++ if (err) {
++ mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);
++ goto out_err;
++ }
++
++ return 0;
++
++out_err:
++ atomic_dec(&ldev->lag_mpesw.mpesw_rule_count);
++ return err;
+ }
+
+-void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
++static void del_mpesw_rule(struct mlx5_lag *ldev)
+ {
+- struct mlx5_lag *ldev = dev->priv.lag;
++ if (!atomic_dec_return(&ldev->lag_mpesw.mpesw_rule_count) &&
++ ldev->mode == MLX5_LAG_MODE_MPESW)
++ mlx5_disable_lag(ldev);
++}
+
+- if (!ldev)
+- return;
++static void mlx5_mpesw_work(struct work_struct *work)
++{
++ struct mlx5_mpesw_work_st *mpesww = container_of(work, struct mlx5_mpesw_work_st, work);
++ struct mlx5_lag *ldev = mpesww->lag;
+
+ mutex_lock(&ldev->lock);
+- if (!atomic_dec_return(&ldev->lag_mpesw.mpesw_rule_count) &&
+- ldev->mode == MLX5_LAG_MODE_MPESW)
+- mlx5_lag_disable_mpesw(dev);
++ if (mpesww->op == MLX5_MPESW_OP_ENABLE)
++ mpesww->result = add_mpesw_rule(ldev);
++ else if (mpesww->op == MLX5_MPESW_OP_DISABLE)
++ del_mpesw_rule(ldev);
+ mutex_unlock(&ldev->lock);
++
++ complete(&mpesww->comp);
+ }
+
+-int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
++static int mlx5_lag_mpesw_queue_work(struct mlx5_core_dev *dev,
++ enum mpesw_op op)
+ {
+ struct mlx5_lag *ldev = dev->priv.lag;
++ struct mlx5_mpesw_work_st *work;
+ int err = 0;
+
+ if (!ldev)
+ return 0;
+
+- mutex_lock(&ldev->lock);
+- if (atomic_add_return(1, &ldev->lag_mpesw.mpesw_rule_count) != 1)
+- goto out;
++ work = kzalloc(sizeof(*work), GFP_KERNEL);
++ if (!work)
++ return -ENOMEM;
+
+- if (ldev->mode != MLX5_LAG_MODE_NONE) {
++ INIT_WORK(&work->work, mlx5_mpesw_work);
++ init_completion(&work->comp);
++ work->op = op;
++ work->lag = ldev;
++
++ if (!queue_work(ldev->wq, &work->work)) {
++ mlx5_core_warn(dev, "failed to queue mpesw work\n");
+ err = -EINVAL;
+ goto out;
+ }
+-
+- err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
+- if (err)
+- mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);
+-
++ wait_for_completion(&work->comp);
++ err = work->result;
+ out:
+- mutex_unlock(&ldev->lock);
++ kfree(work);
+ return err;
+ }
+
++void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
++{
++ mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_DISABLE);
++}
++
++int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
++{
++ return mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_ENABLE);
++}
++
+ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev)
+ {
+ struct mlx5_lag *ldev = mdev->priv.lag;
+@@ -71,12 +103,9 @@ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev)
+ if (!netif_is_bond_master(out_dev) || !ldev)
+ return 0;
+
+- mutex_lock(&ldev->lock);
+- if (ldev->mode == MLX5_LAG_MODE_MPESW) {
+- mutex_unlock(&ldev->lock);
++ if (ldev->mode == MLX5_LAG_MODE_MPESW)
+ return -EOPNOTSUPP;
+- }
+- mutex_unlock(&ldev->lock);
++
+ return 0;
+ }
+
+@@ -90,11 +119,10 @@ bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev)
+
+ void mlx5_lag_mpesw_init(struct mlx5_lag *ldev)
+ {
+- INIT_WORK(&ldev->mpesw_work, mlx5_mpesw_work);
+ atomic_set(&ldev->lag_mpesw.mpesw_rule_count, 0);
+ }
+
+ void mlx5_lag_mpesw_cleanup(struct mlx5_lag *ldev)
+ {
+- cancel_delayed_work_sync(&ldev->bond_work);
++ WARN_ON(atomic_read(&ldev->lag_mpesw.mpesw_rule_count));
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
+index be4abcb8fcd5b..88e8daffcf92e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
+@@ -12,7 +12,6 @@ struct lag_mpesw {
+ atomic_t mpesw_rule_count;
+ };
+
+-void mlx5_mpesw_work(struct work_struct *work);
+ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev);
+ bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev);
+ #if IS_ENABLED(CONFIG_MLX5_ESWITCH)
+diff --git a/drivers/net/ethernet/microchip/encx24j600-regmap.c b/drivers/net/ethernet/microchip/encx24j600-regmap.c
+index 81a8ccca7e5e0..5693784eec5bc 100644
+--- a/drivers/net/ethernet/microchip/encx24j600-regmap.c
++++ b/drivers/net/ethernet/microchip/encx24j600-regmap.c
+@@ -359,7 +359,7 @@ static int regmap_encx24j600_phy_reg_read(void *context, unsigned int reg,
+ goto err_out;
+
+ usleep_range(26, 100);
+- while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
++ while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
+ (mistat & BUSY))
+ cpu_relax();
+
+@@ -397,7 +397,7 @@ static int regmap_encx24j600_phy_reg_write(void *context, unsigned int reg,
+ goto err_out;
+
+ usleep_range(26, 100);
+- while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
++ while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
+ (mistat & BUSY))
+ cpu_relax();
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
+index 66360c8c5a38c..141897dfe3881 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
+@@ -317,7 +317,7 @@ int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
+ next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
+ db_hw = &next_dcb_hw->db[0];
+ if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
+- tx->dropped++;
++ return -EINVAL;
+ db = list_first_entry(&tx->db_list, struct sparx5_db, list);
+ list_move_tail(&db->list, &tx->db_list);
+ next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index 30815c0e3f76a..e58de119186a6 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -876,6 +876,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
+
+ cleanup_ports:
+ sparx5_cleanup_ports(sparx5);
++ if (sparx5->mact_queue)
++ destroy_workqueue(sparx5->mact_queue);
+ cleanup_config:
+ kfree(configs);
+ cleanup_pnode:
+@@ -900,6 +902,7 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
+ sparx5_cleanup_ports(sparx5);
+ /* Unregister netdevs */
+ sparx5_unregister_notifier_blocks(sparx5);
++ destroy_workqueue(sparx5->mact_queue);
+
+ return 0;
+ }
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+index 21844beba72df..0ce0fc9852227 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+@@ -234,9 +234,8 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
+ sparx5_set_port_ifh(ifh, port->portno);
+
+ if (sparx5->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+- ret = sparx5_ptp_txtstamp_request(port, skb);
+- if (ret)
+- return ret;
++ if (sparx5_ptp_txtstamp_request(port, skb) < 0)
++ return NETDEV_TX_BUSY;
+
+ sparx5_set_port_ifh_rew_op(ifh, SPARX5_SKB_CB(skb)->rew_op);
+ sparx5_set_port_ifh_pdu_type(ifh, SPARX5_SKB_CB(skb)->pdu_type);
+@@ -250,23 +249,31 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
+ else
+ ret = sparx5_inject(sparx5, ifh, skb, dev);
+
+- if (ret == NETDEV_TX_OK) {
+- stats->tx_bytes += skb->len;
+- stats->tx_packets++;
++ if (ret == -EBUSY)
++ goto busy;
++ if (ret < 0)
++ goto drop;
+
+- if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+- SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+- return ret;
++ stats->tx_bytes += skb->len;
++ stats->tx_packets++;
++ sparx5->tx.packets++;
+
+- dev_kfree_skb_any(skb);
+- } else {
+- stats->tx_dropped++;
++ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
++ SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
++ return NETDEV_TX_OK;
+
+- if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+- SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+- sparx5_ptp_txtstamp_release(port, skb);
+- }
+- return ret;
++ dev_consume_skb_any(skb);
++ return NETDEV_TX_OK;
++drop:
++ stats->tx_dropped++;
++ sparx5->tx.dropped++;
++ dev_kfree_skb_any(skb);
++ return NETDEV_TX_OK;
++busy:
++ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
++ SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
++ sparx5_ptp_txtstamp_release(port, skb);
++ return NETDEV_TX_BUSY;
+ }
+
+ static enum hrtimer_restart sparx5_injection_timeout(struct hrtimer *tmr)
+diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h
+index 4a6efe6ada080..65c24ee49efd9 100644
+--- a/drivers/net/ethernet/microsoft/mana/gdma.h
++++ b/drivers/net/ethernet/microsoft/mana/gdma.h
+@@ -498,7 +498,14 @@ enum {
+
+ #define GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT BIT(0)
+
+-#define GDMA_DRV_CAP_FLAGS1 GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT
++/* Advertise to the NIC firmware: the NAPI work_done variable race is fixed,
++ * so the driver is able to reliably support features like busy_poll.
++ */
++#define GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX BIT(2)
++
++#define GDMA_DRV_CAP_FLAGS1 \
++ (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
++ GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX)
+
+ #define GDMA_DRV_CAP_FLAGS2 0
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 9259a74eca40b..27a0f3af8aab4 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1303,10 +1303,11 @@ static void mana_poll_rx_cq(struct mana_cq *cq)
+ xdp_do_flush();
+ }
+
+-static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
++static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
+ {
+ struct mana_cq *cq = context;
+ u8 arm_bit;
++ int w;
+
+ WARN_ON_ONCE(cq->gdma_cq != gdma_queue);
+
+@@ -1315,26 +1316,31 @@ static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
+ else
+ mana_poll_tx_cq(cq);
+
+- if (cq->work_done < cq->budget &&
+- napi_complete_done(&cq->napi, cq->work_done)) {
++ w = cq->work_done;
++
++ if (w < cq->budget &&
++ napi_complete_done(&cq->napi, w)) {
+ arm_bit = SET_ARM_BIT;
+ } else {
+ arm_bit = 0;
+ }
+
+ mana_gd_ring_cq(gdma_queue, arm_bit);
++
++ return w;
+ }
+
+ static int mana_poll(struct napi_struct *napi, int budget)
+ {
+ struct mana_cq *cq = container_of(napi, struct mana_cq, napi);
++ int w;
+
+ cq->work_done = 0;
+ cq->budget = budget;
+
+- mana_cq_handler(cq, cq->gdma_cq);
++ w = mana_cq_handler(cq, cq->gdma_cq);
+
+- return min(cq->work_done, budget);
++ return min(w, budget);
+ }
+
+ static void mana_schedule_napi(void *context, struct gdma_queue *gdma_queue)
+diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
+index 2b427d8ccb2f3..ccacb6ab6c39f 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
++++ b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
+@@ -282,7 +282,7 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev)
+ dma_len = skb_headlen(skb);
+ if (skb_is_gso(skb))
+ type = NFDK_DESC_TX_TYPE_TSO;
+- else if (!nr_frags && dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++ else if (!nr_frags && dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ type = NFDK_DESC_TX_TYPE_SIMPLE;
+ else
+ type = NFDK_DESC_TX_TYPE_GATHER;
+@@ -927,7 +927,7 @@ nfp_nfdk_tx_xdp_buf(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring,
+ dma_len = pkt_len;
+ dma_addr = rxbuf->dma_addr + dma_off;
+
+- if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++ if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ type = NFDK_DESC_TX_TYPE_SIMPLE;
+ else
+ type = NFDK_DESC_TX_TYPE_GATHER;
+@@ -1325,7 +1325,7 @@ nfp_nfdk_ctrl_tx_one(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
+ txbuf = &tx_ring->ktxbufs[wr_idx];
+
+ dma_len = skb_headlen(skb);
+- if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++ if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ type = NFDK_DESC_TX_TYPE_SIMPLE;
+ else
+ type = NFDK_DESC_TX_TYPE_GATHER;
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 44f9b31f8b99b..77d4f3eab9715 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -835,7 +835,7 @@ static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
+ napi_gro_receive(&priv->napi[q],
+ priv->rx_1st_skb);
+ stats->rx_packets++;
+- stats->rx_bytes += priv->rx_1st_skb->len;
++ stats->rx_bytes += pkt_len;
+ break;
+ }
+ }
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 9f5cac4000da6..5c234a8158c71 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -108,10 +108,10 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
+
+ axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
+ axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
+- axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
+- axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
+- axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
+- axi->axi_rb = of_property_read_bool(np, "snps,axi_rb");
++ axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
++ axi->axi_fb = of_property_read_bool(np, "snps,fb");
++ axi->axi_mb = of_property_read_bool(np, "snps,mb");
++ axi->axi_rb = of_property_read_bool(np, "snps,rb");
+
+ if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
+ axi->axi_wr_osr_lmt = 1;
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 95baacd6c7610..47da11b9ac286 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1450,7 +1450,7 @@ static void am65_cpsw_nuss_mac_link_up(struct phylink_config *config, struct phy
+
+ if (speed == SPEED_1000)
+ mac_control |= CPSW_SL_CTL_GIG;
+- if (speed == SPEED_10 && interface == PHY_INTERFACE_MODE_RGMII)
++ if (speed == SPEED_10 && phy_interface_mode_is_rgmii(interface))
+ /* Can be used with in band mode only */
+ mac_control |= CPSW_SL_CTL_EXT_EN;
+ if (speed == SPEED_100 && interface == PHY_INTERFACE_MODE_RMII)
+diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
+index 450b16ad40a41..e1a569b99e4a6 100644
+--- a/drivers/net/ieee802154/ca8210.c
++++ b/drivers/net/ieee802154/ca8210.c
+@@ -885,7 +885,7 @@ static int ca8210_spi_transfer(
+
+ dev_dbg(&spi->dev, "%s called\n", __func__);
+
+- cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
++ cas_ctl = kzalloc(sizeof(*cas_ctl), GFP_ATOMIC);
+ if (!cas_ctl)
+ return -ENOMEM;
+
+diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
+index c69b87d3837da..edc769daad077 100644
+--- a/drivers/net/ieee802154/cc2520.c
++++ b/drivers/net/ieee802154/cc2520.c
+@@ -970,7 +970,7 @@ static int cc2520_hw_init(struct cc2520_private *priv)
+
+ if (timeout-- <= 0) {
+ dev_err(&priv->spi->dev, "oscillator start failed!\n");
+- return ret;
++ return -ETIMEDOUT;
+ }
+ udelay(1);
+ } while (!(status & CC2520_STATUS_XOSC32M_STABLE));
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 104fc564a766e..8dafc814282cb 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -3720,6 +3720,7 @@ static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
+ [IFLA_MACSEC_SCB] = { .type = NLA_U8 },
+ [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
+ [IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
++ [IFLA_MACSEC_OFFLOAD] = { .type = NLA_U8 },
+ };
+
+ static void macsec_free_netdev(struct net_device *dev)
+diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
+index 40e745a1d1854..2c47efdae73b4 100644
+--- a/drivers/net/mdio/fwnode_mdio.c
++++ b/drivers/net/mdio/fwnode_mdio.c
+@@ -77,6 +77,7 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
+ */
+ rc = phy_device_register(phy);
+ if (rc) {
++ device_set_node(&phy->mdio.dev, NULL);
+ fwnode_handle_put(child);
+ return rc;
+ }
+@@ -110,8 +111,8 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ else
+ phy = phy_device_create(bus, addr, phy_id, 0, NULL);
+ if (IS_ERR(phy)) {
+- unregister_mii_timestamper(mii_ts);
+- return PTR_ERR(phy);
++ rc = PTR_ERR(phy);
++ goto clean_mii_ts;
+ }
+
+ if (is_acpi_node(child)) {
+@@ -125,17 +126,14 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ /* All data is now stored in the phy struct, so register it */
+ rc = phy_device_register(phy);
+ if (rc) {
+- phy_device_free(phy);
+- fwnode_handle_put(phy->mdio.dev.fwnode);
+- return rc;
++ phy->mdio.dev.fwnode = NULL;
++ fwnode_handle_put(child);
++ goto clean_phy;
+ }
+ } else if (is_of_node(child)) {
+ rc = fwnode_mdiobus_phy_device_register(bus, phy, child, addr);
+- if (rc) {
+- unregister_mii_timestamper(mii_ts);
+- phy_device_free(phy);
+- return rc;
+- }
++ if (rc)
++ goto clean_phy;
+ }
+
+ /* phy->mii_ts may already be defined by the PHY driver. A
+@@ -145,5 +143,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ if (mii_ts)
+ phy->mii_ts = mii_ts;
+ return 0;
++
++clean_phy:
++ phy_device_free(phy);
++clean_mii_ts:
++ unregister_mii_timestamper(mii_ts);
++
++ return rc;
+ }
+ EXPORT_SYMBOL(fwnode_mdiobus_register_phy);
+diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c
+index 796e9c7857d09..510822d6d0d90 100644
+--- a/drivers/net/mdio/of_mdio.c
++++ b/drivers/net/mdio/of_mdio.c
+@@ -68,8 +68,9 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
+ /* All data is now stored in the mdiodev struct; register it. */
+ rc = mdio_device_register(mdiodev);
+ if (rc) {
++ device_set_node(&mdiodev->dev, NULL);
++ fwnode_handle_put(fwnode);
+ mdio_device_free(mdiodev);
+- of_node_put(child);
+ return rc;
+ }
+
+diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
+index 250742ffdfd91..044828d081d22 100644
+--- a/drivers/net/phy/mdio_device.c
++++ b/drivers/net/phy/mdio_device.c
+@@ -21,6 +21,7 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/unistd.h>
++#include <linux/property.h>
+
+ void mdio_device_free(struct mdio_device *mdiodev)
+ {
+@@ -30,6 +31,7 @@ EXPORT_SYMBOL(mdio_device_free);
+
+ static void mdio_device_release(struct device *dev)
+ {
++ fwnode_handle_put(dev->fwnode);
+ kfree(to_mdio_device(dev));
+ }
+
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index 24bae27eedefa..cae24091fb6f7 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/bitfield.h>
+ #include <linux/hwmon.h>
++#include <linux/mutex.h>
+ #include <linux/phy.h>
+ #include <linux/polynomial.h>
+ #include <linux/netdevice.h>
+@@ -70,6 +71,14 @@
+ #define VPSPEC1_TEMP_STA 0x0E
+ #define VPSPEC1_TEMP_STA_DATA GENMASK(9, 0)
+
++/* Mailbox */
++#define VSPEC1_MBOX_DATA 0x5
++#define VSPEC1_MBOX_ADDRLO 0x6
++#define VSPEC1_MBOX_CMD 0x7
++#define VSPEC1_MBOX_CMD_ADDRHI GENMASK(7, 0)
++#define VSPEC1_MBOX_CMD_RD (0 << 8)
++#define VSPEC1_MBOX_CMD_READY BIT(15)
++
+ /* WoL */
+ #define VPSPEC2_WOL_CTL 0x0E06
+ #define VPSPEC2_WOL_AD01 0x0E08
+@@ -77,7 +86,13 @@
+ #define VPSPEC2_WOL_AD45 0x0E0A
+ #define WOL_EN BIT(0)
+
++/* Internal registers, access via mbox */
++#define REG_GPIO0_OUT 0xd3ce00
++
+ struct gpy_priv {
++ /* serialize mailbox acesses */
++ struct mutex mbox_lock;
++
+ u8 fw_major;
+ u8 fw_minor;
+ };
+@@ -187,6 +202,45 @@ static int gpy_hwmon_register(struct phy_device *phydev)
+ }
+ #endif
+
++static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
++{
++ struct gpy_priv *priv = phydev->priv;
++ int val, ret;
++ u16 cmd;
++
++ mutex_lock(&priv->mbox_lock);
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_ADDRLO,
++ addr);
++ if (ret)
++ goto out;
++
++ cmd = VSPEC1_MBOX_CMD_RD;
++ cmd |= FIELD_PREP(VSPEC1_MBOX_CMD_ADDRHI, addr >> 16);
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_CMD, cmd);
++ if (ret)
++ goto out;
++
++ /* The mbox read is used in the interrupt workaround. It was observed
++ * that a read might take up to 2.5ms. This is also the time for which
++ * the interrupt line is stuck low. To be on the safe side, poll the
++ * ready bit for 10ms.
++ */
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++ VSPEC1_MBOX_CMD, val,
++ (val & VSPEC1_MBOX_CMD_READY),
++ 500, 10000, false);
++ if (ret)
++ goto out;
++
++ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_DATA);
++
++out:
++ mutex_unlock(&priv->mbox_lock);
++ return ret;
++}
++
+ static int gpy_config_init(struct phy_device *phydev)
+ {
+ int ret;
+@@ -201,6 +255,13 @@ static int gpy_config_init(struct phy_device *phydev)
+ return ret < 0 ? ret : 0;
+ }
+
++static bool gpy_has_broken_mdint(struct phy_device *phydev)
++{
++ /* At least these PHYs are known to have broken interrupt handling */
++ return phydev->drv->phy_id == PHY_ID_GPY215B ||
++ phydev->drv->phy_id == PHY_ID_GPY215C;
++}
++
+ static int gpy_probe(struct phy_device *phydev)
+ {
+ struct device *dev = &phydev->mdio.dev;
+@@ -218,6 +279,7 @@ static int gpy_probe(struct phy_device *phydev)
+ if (!priv)
+ return -ENOMEM;
+ phydev->priv = priv;
++ mutex_init(&priv->mbox_lock);
+
+ fw_version = phy_read(phydev, PHY_FWV);
+ if (fw_version < 0)
+@@ -492,6 +554,29 @@ static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)
+ if (!(reg & PHY_IMASK_MASK))
+ return IRQ_NONE;
+
++ /* The PHY might leave the interrupt line asserted even after PHY_ISTAT
++ * is read. To avoid interrupt storms, delay the interrupt handling as
++ * long as the PHY drives the interrupt line. An internal bus read will
++ * stall as long as the interrupt line is asserted, thus just read a
++ * random register here.
++ * Because we cannot access the internal bus at all while the interrupt
++ * is driven by the PHY, there is no way to make the interrupt line
++ * unstuck (e.g. by changing the pinmux to GPIO input) during that time
++ * frame. Therefore, polling is the best we can do and won't do any more
++ * harm.
++ * It was observed that this bug happens on link state and link speed
++ * changes on a GPY215B and GYP215C independent of the firmware version
++ * (which doesn't mean that this list is exhaustive).
++ */
++ if (gpy_has_broken_mdint(phydev) &&
++ (reg & (PHY_IMASK_LSTC | PHY_IMASK_LSPC))) {
++ reg = gpy_mbox_read(phydev, REG_GPIO0_OUT);
++ if (reg < 0) {
++ phy_error(phydev);
++ return IRQ_NONE;
++ }
++ }
++
+ phy_trigger_machine(phydev);
+
+ return IRQ_HANDLED;
+diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c
+index c8791e9b451d2..40ce8abe69995 100644
+--- a/drivers/net/plip/plip.c
++++ b/drivers/net/plip/plip.c
+@@ -450,12 +450,12 @@ plip_bh_timeout_error(struct net_device *dev, struct net_local *nl,
+ }
+ rcv->state = PLIP_PK_DONE;
+ if (rcv->skb) {
+- kfree_skb(rcv->skb);
++ dev_kfree_skb_irq(rcv->skb);
+ rcv->skb = NULL;
+ }
+ snd->state = PLIP_PK_DONE;
+ if (snd->skb) {
+- dev_kfree_skb(snd->skb);
++ dev_consume_skb_irq(snd->skb);
+ snd->skb = NULL;
+ }
+ spin_unlock_irq(&nl->lock);
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index 8391f83034992..1f4dcadc284c8 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -902,6 +902,7 @@ static int tbnet_open(struct net_device *dev)
+ tbnet_start_poll, net);
+ if (!ring) {
+ netdev_err(dev, "failed to allocate Rx ring\n");
++ tb_xdomain_release_out_hopid(xd, hopid);
+ tb_ring_free(net->tx_ring.ring);
+ net->tx_ring.ring = NULL;
+ return -ENOMEM;
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index afd6faa4c2ec9..554d4e2a84a4e 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1423,6 +1423,7 @@ static const struct usb_device_id products[] = {
+ {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */
+ {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
+ {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
++ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
+
+ /* 4. Gobi 1000 devices */
+ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index 53b3b241e0278..c28c4a654615c 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -75,8 +75,14 @@ vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
+
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ vmxnet3_enable_intr(adapter, i);
+- adapter->shared->devRead.intrConf.intrCtrl &=
++ if (!VMXNET3_VERSION_GE_6(adapter) ||
++ !adapter->queuesExtEnabled) {
++ adapter->shared->devRead.intrConf.intrCtrl &=
++ cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
++ } else {
++ adapter->shared->devReadExt.intrConfExt.intrCtrl &=
+ cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
++ }
+ }
+
+
+@@ -85,8 +91,14 @@ vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
+ {
+ int i;
+
+- adapter->shared->devRead.intrConf.intrCtrl |=
++ if (!VMXNET3_VERSION_GE_6(adapter) ||
++ !adapter->queuesExtEnabled) {
++ adapter->shared->devRead.intrConf.intrCtrl |=
++ cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
++ } else {
++ adapter->shared->devReadExt.intrConfExt.intrCtrl |=
+ cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
++ }
+ for (i = 0; i < adapter->intr.num_intrs; i++)
+ vmxnet3_disable_intr(adapter, i);
+ }
+@@ -1396,6 +1408,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ };
+ u32 num_pkts = 0;
+ bool skip_page_frags = false;
++ bool encap_lro = false;
+ struct Vmxnet3_RxCompDesc *rcd;
+ struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
+ u16 segCnt = 0, mss = 0;
+@@ -1556,13 +1569,18 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ if (VMXNET3_VERSION_GE_2(adapter) &&
+ rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
+ struct Vmxnet3_RxCompDescExt *rcdlro;
++ union Vmxnet3_GenericDesc *gdesc;
++
+ rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
++ gdesc = (union Vmxnet3_GenericDesc *)rcd;
+
+ segCnt = rcdlro->segCnt;
+ WARN_ON_ONCE(segCnt == 0);
+ mss = rcdlro->mss;
+ if (unlikely(segCnt <= 1))
+ segCnt = 0;
++ encap_lro = (le32_to_cpu(gdesc->dword[0]) &
++ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT));
+ } else {
+ segCnt = 0;
+ }
+@@ -1630,7 +1648,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ vmxnet3_rx_csum(adapter, skb,
+ (union Vmxnet3_GenericDesc *)rcd);
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
+- if (!rcd->tcp ||
++ if ((!rcd->tcp && !encap_lro) ||
+ !(adapter->netdev->features & NETIF_F_LRO))
+ goto not_lro;
+
+@@ -1639,7 +1657,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
+ skb_shinfo(skb)->gso_size = mss;
+ skb_shinfo(skb)->gso_segs = segCnt;
+- } else if (segCnt != 0 || skb->len > mtu) {
++ } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
+ u32 hlen;
+
+ hlen = vmxnet3_get_hdr_len(adapter, skb,
+@@ -1668,6 +1686,7 @@ not_lro:
+ napi_gro_receive(&rq->napi, skb);
+
+ ctx->skb = NULL;
++ encap_lro = false;
+ num_pkts++;
+ }
+
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.c b/drivers/net/wwan/iosm/iosm_ipc_mux.c
+index 9c7a9a2a1f252..fc928b298a984 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux.c
+@@ -332,6 +332,7 @@ struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg,
+ if (!ipc_mux->ul_adb.pp_qlt[i]) {
+ for (j = i - 1; j >= 0; j--)
+ kfree(ipc_mux->ul_adb.pp_qlt[j]);
++ kfree(ipc_mux);
+ return NULL;
+ }
+ }
+diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
+index 8174d7b2966c0..adfd21aa5b6ad 100644
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -386,7 +386,7 @@ int xenvif_dealloc_kthread(void *data);
+ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data);
+
+ bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread);
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
+
+ void xenvif_carrier_on(struct xenvif *vif);
+
+diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
+index fb32ae82d9b04..d048a5cc918b2 100644
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -254,14 +254,16 @@ xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
+ skb_clear_hash(skb);
+
+- xenvif_rx_queue_tail(queue, skb);
++ if (!xenvif_rx_queue_tail(queue, skb))
++ goto drop;
++
+ xenvif_kick_thread(queue);
+
+ return NETDEV_TX_OK;
+
+ drop:
+ vif->dev->stats.tx_dropped++;
+- dev_kfree_skb(skb);
++ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
+index a256695fc89ec..82d7910f7ade5 100644
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -332,10 +332,13 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
+
+
+ struct xenvif_tx_cb {
+- u16 pending_idx;
++ u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
++ u8 copy_count;
+ };
+
+ #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
++#define copy_pending_idx(skb, i) (XENVIF_TX_CB(skb)->copy_pending_idx[i])
++#define copy_count(skb) (XENVIF_TX_CB(skb)->copy_count)
+
+ static inline void xenvif_tx_create_map_op(struct xenvif_queue *queue,
+ u16 pending_idx,
+@@ -370,31 +373,93 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size)
+ return skb;
+ }
+
+-static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue,
+- struct sk_buff *skb,
+- struct xen_netif_tx_request *txp,
+- struct gnttab_map_grant_ref *gop,
+- unsigned int frag_overflow,
+- struct sk_buff *nskb)
++static void xenvif_get_requests(struct xenvif_queue *queue,
++ struct sk_buff *skb,
++ struct xen_netif_tx_request *first,
++ struct xen_netif_tx_request *txfrags,
++ unsigned *copy_ops,
++ unsigned *map_ops,
++ unsigned int frag_overflow,
++ struct sk_buff *nskb,
++ unsigned int extra_count,
++ unsigned int data_len)
+ {
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ skb_frag_t *frags = shinfo->frags;
+- u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
+- int start;
++ u16 pending_idx;
+ pending_ring_idx_t index;
+ unsigned int nr_slots;
++ struct gnttab_copy *cop = queue->tx_copy_ops + *copy_ops;
++ struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops;
++ struct xen_netif_tx_request *txp = first;
++
++ nr_slots = shinfo->nr_frags + 1;
++
++ copy_count(skb) = 0;
++
++ /* Create copy ops for exactly data_len bytes into the skb head. */
++ __skb_put(skb, data_len);
++ while (data_len > 0) {
++ int amount = data_len > txp->size ? txp->size : data_len;
++
++ cop->source.u.ref = txp->gref;
++ cop->source.domid = queue->vif->domid;
++ cop->source.offset = txp->offset;
++
++ cop->dest.domid = DOMID_SELF;
++ cop->dest.offset = (offset_in_page(skb->data +
++ skb_headlen(skb) -
++ data_len)) & ~XEN_PAGE_MASK;
++ cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
++ - data_len);
++
++ cop->len = amount;
++ cop->flags = GNTCOPY_source_gref;
+
+- nr_slots = shinfo->nr_frags;
++ index = pending_index(queue->pending_cons);
++ pending_idx = queue->pending_ring[index];
++ callback_param(queue, pending_idx).ctx = NULL;
++ copy_pending_idx(skb, copy_count(skb)) = pending_idx;
++ copy_count(skb)++;
++
++ cop++;
++ data_len -= amount;
+
+- /* Skip first skb fragment if it is on same page as header fragment. */
+- start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);
++ if (amount == txp->size) {
++ /* The copy op covered the full tx_request */
++
++ memcpy(&queue->pending_tx_info[pending_idx].req,
++ txp, sizeof(*txp));
++ queue->pending_tx_info[pending_idx].extra_count =
++ (txp == first) ? extra_count : 0;
++
++ if (txp == first)
++ txp = txfrags;
++ else
++ txp++;
++ queue->pending_cons++;
++ nr_slots--;
++ } else {
++ /* The copy op partially covered the tx_request.
++ * The remainder will be mapped.
++ */
++ txp->offset += amount;
++ txp->size -= amount;
++ }
++ }
+
+- for (shinfo->nr_frags = start; shinfo->nr_frags < nr_slots;
+- shinfo->nr_frags++, txp++, gop++) {
++ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
++ shinfo->nr_frags++, gop++) {
+ index = pending_index(queue->pending_cons++);
+ pending_idx = queue->pending_ring[index];
+- xenvif_tx_create_map_op(queue, pending_idx, txp, 0, gop);
++ xenvif_tx_create_map_op(queue, pending_idx, txp,
++ txp == first ? extra_count : 0, gop);
+ frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx);
++
++ if (txp == first)
++ txp = txfrags;
++ else
++ txp++;
+ }
+
+ if (frag_overflow) {
+@@ -415,7 +480,8 @@ static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *que
+ skb_shinfo(skb)->frag_list = nskb;
+ }
+
+- return gop;
++ (*copy_ops) = cop - queue->tx_copy_ops;
++ (*map_ops) = gop - queue->tx_map_ops;
+ }
+
+ static inline void xenvif_grant_handle_set(struct xenvif_queue *queue,
+@@ -451,7 +517,7 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ struct gnttab_copy **gopp_copy)
+ {
+ struct gnttab_map_grant_ref *gop_map = *gopp_map;
+- u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++ u16 pending_idx;
+ /* This always points to the shinfo of the skb being checked, which
+ * could be either the first or the one on the frag_list
+ */
+@@ -462,24 +528,37 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ struct skb_shared_info *first_shinfo = NULL;
+ int nr_frags = shinfo->nr_frags;
+ const bool sharedslot = nr_frags &&
+- frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
+- int i, err;
++ frag_get_pending_idx(&shinfo->frags[0]) ==
++ copy_pending_idx(skb, copy_count(skb) - 1);
++ int i, err = 0;
+
+- /* Check status of header. */
+- err = (*gopp_copy)->status;
+- if (unlikely(err)) {
+- if (net_ratelimit())
+- netdev_dbg(queue->vif->dev,
+- "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
+- (*gopp_copy)->status,
+- pending_idx,
+- (*gopp_copy)->source.u.ref);
+- /* The first frag might still have this slot mapped */
+- if (!sharedslot)
+- xenvif_idx_release(queue, pending_idx,
+- XEN_NETIF_RSP_ERROR);
++ for (i = 0; i < copy_count(skb); i++) {
++ int newerr;
++
++ /* Check status of header. */
++ pending_idx = copy_pending_idx(skb, i);
++
++ newerr = (*gopp_copy)->status;
++ if (likely(!newerr)) {
++ /* The first frag might still have this slot mapped */
++ if (i < copy_count(skb) - 1 || !sharedslot)
++ xenvif_idx_release(queue, pending_idx,
++ XEN_NETIF_RSP_OKAY);
++ } else {
++ err = newerr;
++ if (net_ratelimit())
++ netdev_dbg(queue->vif->dev,
++ "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
++ (*gopp_copy)->status,
++ pending_idx,
++ (*gopp_copy)->source.u.ref);
++ /* The first frag might still have this slot mapped */
++ if (i < copy_count(skb) - 1 || !sharedslot)
++ xenvif_idx_release(queue, pending_idx,
++ XEN_NETIF_RSP_ERROR);
++ }
++ (*gopp_copy)++;
+ }
+- (*gopp_copy)++;
+
+ check_frags:
+ for (i = 0; i < nr_frags; i++, gop_map++) {
+@@ -526,14 +605,6 @@ check_frags:
+ if (err)
+ continue;
+
+- /* First error: if the header haven't shared a slot with the
+- * first frag, release it as well.
+- */
+- if (!sharedslot)
+- xenvif_idx_release(queue,
+- XENVIF_TX_CB(skb)->pending_idx,
+- XEN_NETIF_RSP_OKAY);
+-
+ /* Invalidate preceding fragments of this skb. */
+ for (j = 0; j < i; j++) {
+ pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
+@@ -803,7 +874,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ unsigned *copy_ops,
+ unsigned *map_ops)
+ {
+- struct gnttab_map_grant_ref *gop = queue->tx_map_ops;
+ struct sk_buff *skb, *nskb;
+ int ret;
+ unsigned int frag_overflow;
+@@ -885,8 +955,12 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ continue;
+ }
+
++ data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN) ?
++ XEN_NETBACK_TX_COPY_LEN : txreq.size;
++
+ ret = xenvif_count_requests(queue, &txreq, extra_count,
+ txfrags, work_to_do);
++
+ if (unlikely(ret < 0))
+ break;
+
+@@ -912,9 +986,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ index = pending_index(queue->pending_cons);
+ pending_idx = queue->pending_ring[index];
+
+- data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN &&
+- ret < XEN_NETBK_LEGACY_SLOTS_MAX) ?
+- XEN_NETBACK_TX_COPY_LEN : txreq.size;
++ if (ret >= XEN_NETBK_LEGACY_SLOTS_MAX - 1 && data_len < txreq.size)
++ data_len = txreq.size;
+
+ skb = xenvif_alloc_skb(data_len);
+ if (unlikely(skb == NULL)) {
+@@ -925,8 +998,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ }
+
+ skb_shinfo(skb)->nr_frags = ret;
+- if (data_len < txreq.size)
+- skb_shinfo(skb)->nr_frags++;
+ /* At this point shinfo->nr_frags is in fact the number of
+ * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
+ */
+@@ -988,54 +1059,19 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ type);
+ }
+
+- XENVIF_TX_CB(skb)->pending_idx = pending_idx;
+-
+- __skb_put(skb, data_len);
+- queue->tx_copy_ops[*copy_ops].source.u.ref = txreq.gref;
+- queue->tx_copy_ops[*copy_ops].source.domid = queue->vif->domid;
+- queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
+-
+- queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
+- virt_to_gfn(skb->data);
+- queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
+- queue->tx_copy_ops[*copy_ops].dest.offset =
+- offset_in_page(skb->data) & ~XEN_PAGE_MASK;
+-
+- queue->tx_copy_ops[*copy_ops].len = data_len;
+- queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref;
+-
+- (*copy_ops)++;
+-
+- if (data_len < txreq.size) {
+- frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+- pending_idx);
+- xenvif_tx_create_map_op(queue, pending_idx, &txreq,
+- extra_count, gop);
+- gop++;
+- } else {
+- frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+- INVALID_PENDING_IDX);
+- memcpy(&queue->pending_tx_info[pending_idx].req,
+- &txreq, sizeof(txreq));
+- queue->pending_tx_info[pending_idx].extra_count =
+- extra_count;
+- }
+-
+- queue->pending_cons++;
+-
+- gop = xenvif_get_requests(queue, skb, txfrags, gop,
+- frag_overflow, nskb);
++ xenvif_get_requests(queue, skb, &txreq, txfrags, copy_ops,
++ map_ops, frag_overflow, nskb, extra_count,
++ data_len);
+
+ __skb_queue_tail(&queue->tx_queue, skb);
+
+ queue->tx.req_cons = idx;
+
+- if (((gop-queue->tx_map_ops) >= ARRAY_SIZE(queue->tx_map_ops)) ||
++ if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) ||
+ (*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops)))
+ break;
+ }
+
+- (*map_ops) = gop - queue->tx_map_ops;
+ return;
+ }
+
+@@ -1114,9 +1150,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ while ((skb = __skb_dequeue(&queue->tx_queue)) != NULL) {
+ struct xen_netif_tx_request *txp;
+ u16 pending_idx;
+- unsigned data_len;
+
+- pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++ pending_idx = copy_pending_idx(skb, 0);
+ txp = &queue->pending_tx_info[pending_idx].req;
+
+ /* Check the remap error code. */
+@@ -1135,18 +1170,6 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ continue;
+ }
+
+- data_len = skb->len;
+- callback_param(queue, pending_idx).ctx = NULL;
+- if (data_len < txp->size) {
+- /* Append the packet payload as a fragment. */
+- txp->offset += data_len;
+- txp->size -= data_len;
+- } else {
+- /* Schedule a response immediately. */
+- xenvif_idx_release(queue, pending_idx,
+- XEN_NETIF_RSP_OKAY);
+- }
+-
+ if (txp->flags & XEN_NETTXF_csum_blank)
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ else if (txp->flags & XEN_NETTXF_data_validated)
+@@ -1331,7 +1354,7 @@ static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue)
+ /* Called after netfront has transmitted */
+ int xenvif_tx_action(struct xenvif_queue *queue, int budget)
+ {
+- unsigned nr_mops, nr_cops = 0;
++ unsigned nr_mops = 0, nr_cops = 0;
+ int work_done, ret;
+
+ if (unlikely(!tx_work_todo(queue)))
+diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
+index 9327621771109..0ba754ebc5baa 100644
+--- a/drivers/net/xen-netback/rx.c
++++ b/drivers/net/xen-netback/rx.c
+@@ -82,9 +82,10 @@ static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
+ return false;
+ }
+
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ {
+ unsigned long flags;
++ bool ret = true;
+
+ spin_lock_irqsave(&queue->rx_queue.lock, flags);
+
+@@ -92,8 +93,7 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ struct net_device *dev = queue->vif->dev;
+
+ netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
+- kfree_skb(skb);
+- queue->vif->dev->stats.rx_dropped++;
++ ret = false;
+ } else {
+ if (skb_queue_empty(&queue->rx_queue))
+ xenvif_update_needed_slots(queue, skb);
+@@ -104,6 +104,8 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ }
+
+ spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
++
++ return ret;
+ }
+
+ static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue)
+diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
+index 27a11cc08c61e..479e215159fcc 100644
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -1862,6 +1862,12 @@ static int netfront_resume(struct xenbus_device *dev)
+ netif_tx_unlock_bh(info->netdev);
+
+ xennet_disconnect_backend(info);
++
++ rtnl_lock();
++ if (info->queues)
++ xennet_destroy_queues(info);
++ rtnl_unlock();
++
+ return 0;
+ }
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index f612a0ba64d00..aca50bb937506 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3089,10 +3089,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ if (!ctrl->identified) {
+ unsigned int i;
+
+- ret = nvme_init_subsystem(ctrl, id);
+- if (ret)
+- goto out_free;
+-
+ /*
+ * Check for quirks. Quirk can depend on firmware version,
+ * so, in principle, the set of quirks present can change
+@@ -3105,6 +3101,10 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ if (quirk_matches(id, &core_quirks[i]))
+ ctrl->quirks |= core_quirks[i].quirks;
+ }
++
++ ret = nvme_init_subsystem(ctrl, id);
++ if (ret)
++ goto out_free;
+ }
+ memcpy(ctrl->subsys->firmware_rev, id->fr,
+ sizeof(ctrl->subsys->firmware_rev));
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index 478dd300b9c9a..d9e7cf6e4a0e1 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -115,12 +115,17 @@ static struct quirk_entry quirk_asus_forceals = {
+ };
+
+ static struct quirk_entry quirk_asus_use_kbd_dock_devid = {
+- .use_kbd_dock_devid = true,
++ .tablet_switch_mode = asus_wmi_kbd_dock_devid,
+ };
+
+ static struct quirk_entry quirk_asus_use_lid_flip_devid = {
+ .wmi_backlight_set_devstate = true,
+- .use_lid_flip_devid = true,
++ .tablet_switch_mode = asus_wmi_lid_flip_devid,
++};
++
++static struct quirk_entry quirk_asus_tablet_mode = {
++ .wmi_backlight_set_devstate = true,
++ .tablet_switch_mode = asus_wmi_lid_flip_rog_devid,
+ };
+
+ static int dmi_matched(const struct dmi_system_id *dmi)
+@@ -471,6 +476,15 @@ static const struct dmi_system_id asus_quirks[] = {
+ },
+ .driver_data = &quirk_asus_use_lid_flip_devid,
+ },
++ {
++ .callback = dmi_matched,
++ .ident = "ASUS ROG FLOW X13",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "GV301Q"),
++ },
++ .driver_data = &quirk_asus_tablet_mode,
++ },
+ {},
+ };
+
+@@ -492,16 +506,13 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
+
+ switch (tablet_mode_sw) {
+ case 0:
+- quirks->use_kbd_dock_devid = false;
+- quirks->use_lid_flip_devid = false;
++ quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+ break;
+ case 1:
+- quirks->use_kbd_dock_devid = true;
+- quirks->use_lid_flip_devid = false;
++ quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid;
+ break;
+ case 2:
+- quirks->use_kbd_dock_devid = false;
+- quirks->use_lid_flip_devid = true;
++ quirks->tablet_switch_mode = asus_wmi_lid_flip_devid;
+ break;
+ }
+
+@@ -581,6 +592,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
+ { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */
+ { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */
++ { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */
+ { KE_END, 0},
+ };
+
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index 8e1979b477a7d..dce93187e11f9 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -68,6 +68,7 @@ module_param(fnlock_default, bool, 0444);
+ #define NOTIFY_KBD_FBM 0x99
+ #define NOTIFY_KBD_TTP 0xae
+ #define NOTIFY_LID_FLIP 0xfa
++#define NOTIFY_LID_FLIP_ROG 0xbd
+
+ #define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
+
+@@ -489,8 +490,11 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
+
+ static int asus_wmi_input_init(struct asus_wmi *asus)
+ {
++ struct device *dev;
+ int err, result;
+
++ dev = &asus->platform_device->dev;
++
+ asus->inputdev = input_allocate_device();
+ if (!asus->inputdev)
+ return -ENOMEM;
+@@ -498,35 +502,51 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
+ asus->inputdev->name = asus->driver->input_name;
+ asus->inputdev->phys = asus->driver->input_phys;
+ asus->inputdev->id.bustype = BUS_HOST;
+- asus->inputdev->dev.parent = &asus->platform_device->dev;
++ asus->inputdev->dev.parent = dev;
+ set_bit(EV_REP, asus->inputdev->evbit);
+
+ err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+- if (asus->driver->quirks->use_kbd_dock_devid) {
++ switch (asus->driver->quirks->tablet_switch_mode) {
++ case asus_wmi_no_tablet_switch:
++ break;
++ case asus_wmi_kbd_dock_devid:
+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_KBD_DOCK);
+ if (result >= 0) {
+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
+ input_report_switch(asus->inputdev, SW_TABLET_MODE, !result);
+ } else if (result != -ENODEV) {
+- pr_err("Error checking for keyboard-dock: %d\n", result);
++ dev_err(dev, "Error checking for keyboard-dock: %d\n", result);
+ }
+- }
+-
+- if (asus->driver->quirks->use_lid_flip_devid) {
++ break;
++ case asus_wmi_lid_flip_devid:
+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
+ if (result < 0)
+- asus->driver->quirks->use_lid_flip_devid = 0;
++ asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
++ if (result >= 0) {
++ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
++ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
++ } else if (result == -ENODEV) {
++ dev_err(dev, "This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
++ } else {
++ dev_err(dev, "Error checking for lid-flip: %d\n", result);
++ }
++ break;
++ case asus_wmi_lid_flip_rog_devid:
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
++ if (result < 0)
++ asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+ if (result >= 0) {
+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
+ } else if (result == -ENODEV) {
+- pr_err("This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
++ dev_err(dev, "This device has lid-flip-rog quirk but got ENODEV checking it. This is a bug.");
+ } else {
+- pr_err("Error checking for lid-flip: %d\n", result);
++ dev_err(dev, "Error checking for lid-flip: %d\n", result);
+ }
++ break;
+ }
+
+ err = input_register_device(asus->inputdev);
+@@ -552,8 +572,20 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
+
+ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
+ {
+- int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
++ int result;
+
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
++ if (result >= 0) {
++ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
++ input_sync(asus->inputdev);
++ }
++}
++
++static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus)
++{
++ int result;
++
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
+ if (result >= 0) {
+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
+ input_sync(asus->inputdev);
+@@ -3109,7 +3141,8 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ return;
+ }
+
+- if (asus->driver->quirks->use_kbd_dock_devid && code == NOTIFY_KBD_DOCK_CHANGE) {
++ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid &&
++ code == NOTIFY_KBD_DOCK_CHANGE) {
+ result = asus_wmi_get_devstate_simple(asus,
+ ASUS_WMI_DEVID_KBD_DOCK);
+ if (result >= 0) {
+@@ -3120,11 +3153,18 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ return;
+ }
+
+- if (asus->driver->quirks->use_lid_flip_devid && code == NOTIFY_LID_FLIP) {
++ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid &&
++ code == NOTIFY_LID_FLIP) {
+ lid_flip_tablet_mode_get_state(asus);
+ return;
+ }
+
++ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid &&
++ code == NOTIFY_LID_FLIP_ROG) {
++ lid_flip_rog_tablet_mode_get_state(asus);
++ return;
++ }
++
+ if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
+ fan_boost_mode_switch_next(asus);
+ return;
+@@ -3757,8 +3797,17 @@ static int asus_hotk_resume(struct device *device)
+ if (asus_wmi_has_fnlock_key(asus))
+ asus_wmi_fnlock_update(asus);
+
+- if (asus->driver->quirks->use_lid_flip_devid)
++ switch (asus->driver->quirks->tablet_switch_mode) {
++ case asus_wmi_no_tablet_switch:
++ case asus_wmi_kbd_dock_devid:
++ break;
++ case asus_wmi_lid_flip_devid:
+ lid_flip_tablet_mode_get_state(asus);
++ break;
++ case asus_wmi_lid_flip_rog_devid:
++ lid_flip_rog_tablet_mode_get_state(asus);
++ break;
++ }
+
+ return 0;
+ }
+@@ -3799,8 +3848,17 @@ static int asus_hotk_restore(struct device *device)
+ if (asus_wmi_has_fnlock_key(asus))
+ asus_wmi_fnlock_update(asus);
+
+- if (asus->driver->quirks->use_lid_flip_devid)
++ switch (asus->driver->quirks->tablet_switch_mode) {
++ case asus_wmi_no_tablet_switch:
++ case asus_wmi_kbd_dock_devid:
++ break;
++ case asus_wmi_lid_flip_devid:
+ lid_flip_tablet_mode_get_state(asus);
++ break;
++ case asus_wmi_lid_flip_rog_devid:
++ lid_flip_rog_tablet_mode_get_state(asus);
++ break;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
+index b302415bf1d95..0187f13d24148 100644
+--- a/drivers/platform/x86/asus-wmi.h
++++ b/drivers/platform/x86/asus-wmi.h
+@@ -25,6 +25,13 @@ struct module;
+ struct key_entry;
+ struct asus_wmi;
+
++enum asus_wmi_tablet_switch_mode {
++ asus_wmi_no_tablet_switch,
++ asus_wmi_kbd_dock_devid,
++ asus_wmi_lid_flip_devid,
++ asus_wmi_lid_flip_rog_devid,
++};
++
+ struct quirk_entry {
+ bool hotplug_wireless;
+ bool scalar_panel_brightness;
+@@ -33,8 +40,7 @@ struct quirk_entry {
+ bool wmi_backlight_native;
+ bool wmi_backlight_set_devstate;
+ bool wmi_force_als_set;
+- bool use_kbd_dock_devid;
+- bool use_lid_flip_devid;
++ enum asus_wmi_tablet_switch_mode tablet_switch_mode;
+ int wapf;
+ /*
+ * For machines with AMD graphic chips, it will send out WMI event
+diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
+index 75a941fb3c2bd..1b2eee95ad3f9 100644
+--- a/drivers/regulator/slg51000-regulator.c
++++ b/drivers/regulator/slg51000-regulator.c
+@@ -457,6 +457,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
+ chip->cs_gpiod = cs_gpiod;
+ }
+
++ usleep_range(10000, 11000);
++
+ i2c_set_clientdata(client, chip);
+ chip->chip_irq = client->irq;
+ chip->dev = dev;
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 7c7e3648ea4bf..f3856750944f4 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -67,6 +67,7 @@ struct twlreg_info {
+ #define TWL6030_CFG_STATE_SLEEP 0x03
+ #define TWL6030_CFG_STATE_GRP_SHIFT 5
+ #define TWL6030_CFG_STATE_APP_SHIFT 2
++#define TWL6030_CFG_STATE_MASK 0x03
+ #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
+ #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
+ TWL6030_CFG_STATE_APP_SHIFT)
+@@ -128,13 +129,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
+ if (grp < 0)
+ return grp;
+ grp &= P1_GRP_6030;
++ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++ val = TWL6030_CFG_STATE_APP(val);
+ } else {
++ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++ val &= TWL6030_CFG_STATE_MASK;
+ grp = 1;
+ }
+
+- val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+- val = TWL6030_CFG_STATE_APP(val);
+-
+ return grp && (val == TWL6030_CFG_STATE_ON);
+ }
+
+@@ -187,7 +189,12 @@ static int twl6030reg_get_status(struct regulator_dev *rdev)
+
+ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+
+- switch (TWL6030_CFG_STATE_APP(val)) {
++ if (info->features & TWL6032_SUBCLASS)
++ val &= TWL6030_CFG_STATE_MASK;
++ else
++ val = TWL6030_CFG_STATE_APP(val);
++
++ switch (val) {
+ case TWL6030_CFG_STATE_ON:
+ return REGULATOR_STATUS_NORMAL;
+
+diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
+index 2d4436cbcb47b..b38024a79376b 100644
+--- a/drivers/s390/net/qeth_l2_main.c
++++ b/drivers/s390/net/qeth_l2_main.c
+@@ -758,7 +758,6 @@ static void qeth_l2_br2dev_worker(struct work_struct *work)
+ struct list_head *iter;
+ int err = 0;
+
+- kfree(br2dev_event_work);
+ QETH_CARD_TEXT_(card, 4, "b2dw%04lx", event);
+ QETH_CARD_TEXT_(card, 4, "ma%012llx", ether_addr_to_u64(addr));
+
+@@ -815,6 +814,7 @@ unlock:
+ dev_put(brdev);
+ dev_put(lsyncdev);
+ dev_put(dstdev);
++ kfree(br2dev_event_work);
+ }
+
+ static int qeth_l2_br2dev_queue_work(struct net_device *brdev,
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index 747983743a14b..f81cdd83ec26e 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -55,7 +55,26 @@ static const struct adr_remap dell_sku_0A3E[] = {
+ {}
+ };
+
++/*
++ * The HP Omen 16-k0005TX does not expose the correct version of RT711 on link0
++ * and does not expose a RT1316 on link3
++ */
++static const struct adr_remap hp_omen_16[] = {
++ /* rt711-sdca on link0 */
++ {
++ 0x000020025d071100ull,
++ 0x000030025d071101ull
++ },
++ /* rt1316-sdca on link3 */
++ {
++ 0x000120025d071100ull,
++ 0x000330025d131601ull
++ },
++ {}
++};
++
+ static const struct dmi_system_id adr_remap_quirk_table[] = {
++ /* TGL devices */
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+@@ -78,6 +97,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ },
+ .driver_data = (void *)dell_sku_0A3E,
+ },
++ /* ADL devices */
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"),
++ },
++ .driver_data = (void *)hp_omen_16,
++ },
+ {}
+ };
+
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index af6c1a93372d9..002bc26b525e8 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -1307,6 +1307,7 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
+ cdns->msg_count = 0;
+
+ bus->link_id = auxdev->id;
++ bus->clk_stop_timeout = 1;
+
+ sdw_cdns_probe(cdns);
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index cd9dc358d3967..a7cc96aeb5903 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1268,8 +1268,11 @@ static int mtk_spi_remove(struct platform_device *pdev)
+ {
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct mtk_spi *mdata = spi_master_get_devdata(master);
++ int ret;
+
+- pm_runtime_disable(&pdev->dev);
++ ret = pm_runtime_resume_and_get(&pdev->dev);
++ if (ret < 0)
++ return ret;
+
+ mtk_spi_reset(mdata);
+
+@@ -1278,6 +1281,9 @@ static int mtk_spi_remove(struct platform_device *pdev)
+ clk_unprepare(mdata->spi_hclk);
+ }
+
++ pm_runtime_put_noidle(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
+ return 0;
+ }
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 6f61a288073bb..c2075b90f3dfe 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -291,7 +291,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
+ *
+ * DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section 3.2.2
+ */
+- if (dwc->gadget->speed <= USB_SPEED_HIGH) {
++ if (dwc->gadget->speed <= USB_SPEED_HIGH ||
++ DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
+ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 098b62f7b701e..c0143d38df83a 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -577,7 +577,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+ if (scr_readw(r) != vc->vc_video_erase_char)
+ break;
+ if (r != q && new_rows >= rows + logo_lines) {
+- save = kmalloc(array3_size(logo_lines, new_cols, 2),
++ save = kzalloc(array3_size(logo_lines, new_cols, 2),
+ GFP_KERNEL);
+ if (save) {
+ int i = min(cols, new_cols);
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index e7671afcee4f0..8cc038460bed7 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5615,6 +5615,7 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ u64 ext_len;
+ u64 clone_len;
+ u64 clone_data_offset;
++ bool crossed_src_i_size = false;
+
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(clone_root->root, path);
+@@ -5672,8 +5673,10 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ if (key.offset >= clone_src_i_size)
+ break;
+
+- if (key.offset + ext_len > clone_src_i_size)
++ if (key.offset + ext_len > clone_src_i_size) {
+ ext_len = clone_src_i_size - key.offset;
++ crossed_src_i_size = true;
++ }
+
+ clone_data_offset = btrfs_file_extent_offset(leaf, ei);
+ if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte) {
+@@ -5734,6 +5737,25 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ ret = send_clone(sctx, offset, clone_len,
+ clone_root);
+ }
++ } else if (crossed_src_i_size && clone_len < len) {
++ /*
++ * If we are at i_size of the clone source inode and we
++ * can not clone from it, terminate the loop. This is
++ * to avoid sending two write operations, one with a
++ * length matching clone_len and the final one after
++ * this loop with a length of len - clone_len.
++ *
++ * When using encoded writes (BTRFS_SEND_FLAG_COMPRESSED
++ * was passed to the send ioctl), this helps avoid
++ * sending an encoded write for an offset that is not
++ * sector size aligned, in case the i_size of the source
++ * inode is not sector size aligned. That will make the
++ * receiver fallback to decompression of the data and
++ * writing it using regular buffered IO, therefore while
++ * not incorrect, it's not optimal due decompression and
++ * possible re-compression at the receiver.
++ */
++ break;
+ } else {
+ ret = send_extent_data(sctx, dst_path, offset,
+ clone_len);
+diff --git a/fs/file.c b/fs/file.c
+index 3bcc1ecc314a7..57af5f8375fd2 100644
+--- a/fs/file.c
++++ b/fs/file.c
+@@ -1002,7 +1002,16 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
+ struct files_struct *files = current->files;
+ struct file *file;
+
+- if (atomic_read(&files->count) == 1) {
++ /*
++ * If another thread is concurrently calling close_fd() followed
++ * by put_files_struct(), we must not observe the old table
++ * entry combined with the new refcount - otherwise we could
++ * return a file that is concurrently being freed.
++ *
++ * atomic_read_acquire() pairs with atomic_dec_and_test() in
++ * put_files_struct().
++ */
++ if (atomic_read_acquire(&files->count) == 1) {
+ file = files_lookup_fd_raw(files, fd);
+ if (!file || unlikely(file->f_mode & mask))
+ return 0;
+diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
+index 451d8a077e125..bce2492186d0b 100644
+--- a/fs/fscache/cookie.c
++++ b/fs/fscache/cookie.c
+@@ -605,6 +605,14 @@ again:
+ set_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags);
+ queue = true;
+ }
++ /*
++ * We could race with cookie_lru which may set LRU_DISCARD bit
++ * but has yet to run the cookie state machine. If this happens
++ * and another thread tries to use the cookie, clear LRU_DISCARD
++ * so we don't end up withdrawing the cookie while in use.
++ */
++ if (test_and_clear_bit(FSCACHE_COOKIE_DO_LRU_DISCARD, &cookie->flags))
++ fscache_see_cookie(cookie, fscache_cookie_see_lru_discard_clear);
+ break;
+
+ case FSCACHE_COOKIE_STATE_FAILED:
+diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
+index 492dce43236ea..cab7cfebf40bd 100644
+--- a/include/asm-generic/tlb.h
++++ b/include/asm-generic/tlb.h
+@@ -222,12 +222,16 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+ #define tlb_needs_table_invalidate() (true)
+ #endif
+
++void tlb_remove_table_sync_one(void);
++
+ #else
+
+ #ifdef tlb_needs_table_invalidate
+ #error tlb_needs_table_invalidate() requires MMU_GATHER_RCU_TABLE_FREE
+ #endif
+
++static inline void tlb_remove_table_sync_one(void) { }
++
+ #endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+
+diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
+index ac5d0515680ea..a3535a485497b 100644
+--- a/include/linux/cgroup.h
++++ b/include/linux/cgroup.h
+@@ -68,6 +68,7 @@ struct css_task_iter {
+ struct list_head iters_node; /* css_set->task_iters */
+ };
+
++extern struct file_system_type cgroup_fs_type;
+ extern struct cgroup_root cgrp_dfl_root;
+ extern struct css_set init_css_set;
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 21f8b27bd9fd3..4ff52127a6b88 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1778,6 +1778,25 @@ extern void pagefault_out_of_memory(void);
+
+ extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);
+
++/*
++ * Parameter block passed down to zap_pte_range in exceptional cases.
++ */
++struct zap_details {
++ struct folio *single_folio; /* Locked folio to be unmapped */
++ bool even_cows; /* Zap COWed private pages too? */
++ zap_flags_t zap_flags; /* Extra flags for zapping */
++};
++
++/*
++ * Whether to drop the pte markers, for example, the uffd-wp information for
++ * file-backed memory. This should only be specified when we will completely
++ * drop the page in the mm, either by truncation or unmapping of the vma. By
++ * default, the flag is not set.
++ */
++#define ZAP_FLAG_DROP_MARKER ((__force zap_flags_t) BIT(0))
++/* Set in unmap_vmas() to indicate a final unmap call. Only used by hugetlb */
++#define ZAP_FLAG_UNMAP ((__force zap_flags_t) BIT(1))
++
+ #ifdef CONFIG_MMU
+ extern bool can_do_mlock(void);
+ #else
+@@ -1797,6 +1816,8 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address,
+ unsigned long size);
+ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
+ unsigned long start, unsigned long end);
++void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
++ unsigned long size, struct zap_details *details);
+
+ struct mmu_notifier_range;
+
+@@ -3386,12 +3407,4 @@ madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
+ }
+ #endif
+
+-/*
+- * Whether to drop the pte markers, for example, the uffd-wp information for
+- * file-backed memory. This should only be specified when we will completely
+- * drop the page in the mm, either by truncation or unmapping of the vma. By
+- * default, the flag is not set.
+- */
+-#define ZAP_FLAG_DROP_MARKER ((__force zap_flags_t) BIT(0))
+-
+ #endif /* _LINUX_MM_H */
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 98f2b2f20f3e9..7c96db7f30602 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -65,6 +65,7 @@
+ #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
+ #define ASUS_WMI_DEVID_CAMERA 0x00060013
+ #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
++#define ASUS_WMI_DEVID_LID_FLIP_ROG 0x00060077
+
+ /* Storage */
+ #define ASUS_WMI_DEVID_CARDREADER 0x00080013
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index cf29511b25a8d..4518c63e9d179 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -228,6 +228,17 @@ enum {
+ */
+ HCI_QUIRK_VALID_LE_STATES,
+
++ /* When this quirk is set, then erroneous data reporting
++ * is ignored. This is mainly due to the fact that the HCI
++ * Read Default Erroneous Data Reporting command is advertised,
++ * but not supported; these controllers often reply with unknown
++ * command and tend to lock up randomly. Needing a hard reset.
++ *
++ * This quirk can be set before hci_register_dev is called or
++ * during the hdev->setup vendor callback.
++ */
++ HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
++
+ /*
+ * When this quirk is set, then the hci_suspend_notifier is not
+ * registered. This is intended for devices which drop completely
+@@ -1420,7 +1431,6 @@ struct hci_std_codecs_v2 {
+ } __packed;
+
+ struct hci_vnd_codec_v2 {
+- __u8 id;
+ __le16 cid;
+ __le16 vid;
+ __u8 transport;
+diff --git a/include/net/ping.h b/include/net/ping.h
+index e4ff3911cbf56..9233ad3de0ade 100644
+--- a/include/net/ping.h
++++ b/include/net/ping.h
+@@ -16,9 +16,6 @@
+ #define PING_HTABLE_SIZE 64
+ #define PING_HTABLE_MASK (PING_HTABLE_SIZE-1)
+
+-#define ping_portaddr_for_each_entry(__sk, node, list) \
+- hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+-
+ /*
+ * gid_t is either uint or ushort. We want to pass it to
+ * proc_dointvec_minmax(), so it must not be larger than MAX_INT
+diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
+index c078c48a8e6d3..a6190aa1b4060 100644
+--- a/include/trace/events/fscache.h
++++ b/include/trace/events/fscache.h
+@@ -66,6 +66,7 @@ enum fscache_cookie_trace {
+ fscache_cookie_put_work,
+ fscache_cookie_see_active,
+ fscache_cookie_see_lru_discard,
++ fscache_cookie_see_lru_discard_clear,
+ fscache_cookie_see_lru_do_one,
+ fscache_cookie_see_relinquish,
+ fscache_cookie_see_withdraw,
+@@ -149,6 +150,7 @@ enum fscache_access_trace {
+ EM(fscache_cookie_put_work, "PQ work ") \
+ EM(fscache_cookie_see_active, "- activ") \
+ EM(fscache_cookie_see_lru_discard, "- x-lru") \
++ EM(fscache_cookie_see_lru_discard_clear,"- lrudc") \
+ EM(fscache_cookie_see_lru_do_one, "- lrudo") \
+ EM(fscache_cookie_see_relinquish, "- x-rlq") \
+ EM(fscache_cookie_see_withdraw, "- x-wth") \
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index adf73d1625218..1b6c25dc3f0c5 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2560,8 +2560,10 @@ static __cold void io_tctx_exit_cb(struct callback_head *cb)
+ /*
+ * When @in_idle, we're in cancellation and it's racy to remove the
+ * node. It'll be removed by the end of cancellation, just ignore it.
++ * tctx can be NULL if the queueing of this task_work raced with
++ * work cancelation off the exec path.
+ */
+- if (!atomic_read(&tctx->in_idle))
++ if (tctx && !atomic_read(&tctx->in_idle))
+ io_uring_del_tctx_node((unsigned long)work->ctx);
+ complete(&work->completion);
+ }
+diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
+index 36b740cb3d59e..b231081be177c 100644
+--- a/kernel/cgroup/cgroup-internal.h
++++ b/kernel/cgroup/cgroup-internal.h
+@@ -168,7 +168,6 @@ extern struct mutex cgroup_mutex;
+ extern spinlock_t css_set_lock;
+ extern struct cgroup_subsys *cgroup_subsys[];
+ extern struct list_head cgroup_roots;
+-extern struct file_system_type cgroup_fs_type;
+
+ /* iterate across the hierarchies */
+ #define for_each_root(root) \
+diff --git a/mm/gup.c b/mm/gup.c
+index 251cb6a10bc0d..d7f9116fc645c 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -2818,7 +2818,7 @@ static int gup_pud_range(p4d_t *p4dp, p4d_t p4d, unsigned long addr, unsigned lo
+ next = pud_addr_end(addr, end);
+ if (unlikely(!pud_present(pud)))
+ return 0;
+- if (unlikely(pud_huge(pud))) {
++ if (unlikely(pud_huge(pud) || pud_devmap(pud))) {
+ if (!gup_huge_pud(pud, pudp, addr, next, flags,
+ pages, nr))
+ return 0;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index dbb558e71e9e1..022a3bfafec44 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5145,17 +5145,20 @@ void __unmap_hugepage_range_final(struct mmu_gather *tlb,
+ {
+ __unmap_hugepage_range(tlb, vma, start, end, ref_page, zap_flags);
+
+- /*
+- * Clear this flag so that x86's huge_pmd_share page_table_shareable
+- * test will fail on a vma being torn down, and not grab a page table
+- * on its way out. We're lucky that the flag has such an appropriate
+- * name, and can in fact be safely cleared here. We could clear it
+- * before the __unmap_hugepage_range above, but all that's necessary
+- * is to clear it before releasing the i_mmap_rwsem. This works
+- * because in the context this is called, the VMA is about to be
+- * destroyed and the i_mmap_rwsem is held.
+- */
+- vma->vm_flags &= ~VM_MAYSHARE;
++ if (zap_flags & ZAP_FLAG_UNMAP) { /* final unmap */
++ /*
++ * Clear this flag so that x86's huge_pmd_share
++ * page_table_shareable test will fail on a vma being torn
++ * down, and not grab a page table on its way out. We're lucky
++ * that the flag has such an appropriate name, and can in fact
++ * be safely cleared here. We could clear it before the
++ * __unmap_hugepage_range above, but all that's necessary
++ * is to clear it before releasing the i_mmap_rwsem. This works
++ * because in the context this is called, the VMA is about to
++ * be destroyed and the i_mmap_rwsem is held.
++ */
++ vma->vm_flags &= ~VM_MAYSHARE;
++ }
+ }
+
+ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 70b7ac66411c0..5935765bcb33b 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1093,6 +1093,7 @@ static void collapse_huge_page(struct mm_struct *mm,
+ _pmd = pmdp_collapse_flush(vma, address, pmd);
+ spin_unlock(pmd_ptl);
+ mmu_notifier_invalidate_range_end(&range);
++ tlb_remove_table_sync_one();
+
+ spin_lock(pte_ptl);
+ isolated = __collapse_huge_page_isolate(vma, address, pte,
+@@ -1360,16 +1361,43 @@ static void khugepaged_add_pte_mapped_thp(struct mm_struct *mm,
+ spin_unlock(&khugepaged_mm_lock);
+ }
+
++/*
++ * A note about locking:
++ * Trying to take the page table spinlocks would be useless here because those
++ * are only used to synchronize:
++ *
++ * - modifying terminal entries (ones that point to a data page, not to another
++ * page table)
++ * - installing *new* non-terminal entries
++ *
++ * Instead, we need roughly the same kind of protection as free_pgtables() or
++ * mm_take_all_locks() (but only for a single VMA):
++ * The mmap lock together with this VMA's rmap locks covers all paths towards
++ * the page table entries we're messing with here, except for hardware page
++ * table walks and lockless_pages_from_mm().
++ */
+ static void collapse_and_free_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, pmd_t *pmdp)
+ {
+- spinlock_t *ptl;
+ pmd_t pmd;
++ struct mmu_notifier_range range;
+
+ mmap_assert_write_locked(mm);
+- ptl = pmd_lock(vma->vm_mm, pmdp);
++ if (vma->vm_file)
++ lockdep_assert_held_write(&vma->vm_file->f_mapping->i_mmap_rwsem);
++ /*
++ * All anon_vmas attached to the VMA have the same root and are
++ * therefore locked by the same lock.
++ */
++ if (vma->anon_vma)
++ lockdep_assert_held_write(&vma->anon_vma->root->rwsem);
++
++ mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, addr,
++ addr + HPAGE_PMD_SIZE);
++ mmu_notifier_invalidate_range_start(&range);
+ pmd = pmdp_collapse_flush(vma, addr, pmdp);
+- spin_unlock(ptl);
++ tlb_remove_table_sync_one();
++ mmu_notifier_invalidate_range_end(&range);
+ mm_dec_nr_ptes(mm);
+ page_table_check_pte_clear_range(mm, addr, pmd);
+ pte_free(mm, pmd_pgtable(pmd));
+@@ -1410,6 +1438,14 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE, false, false))
+ return;
+
++ /*
++ * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
++ * that got written to. Without this, we'd have to also lock the
++ * anon_vma if one exists.
++ */
++ if (vma->anon_vma)
++ return;
++
+ /* Keep pmd pgtable for uffd-wp; see comment in retract_page_tables() */
+ if (userfaultfd_wp(vma))
+ return;
+@@ -1426,6 +1462,20 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ if (!pmd)
+ goto drop_hpage;
+
++ /*
++ * We need to lock the mapping so that from here on, only GUP-fast and
++ * hardware page walks can access the parts of the page tables that
++ * we're operating on.
++ * See collapse_and_free_pmd().
++ */
++ i_mmap_lock_write(vma->vm_file->f_mapping);
++
++ /*
++ * This spinlock should be unnecessary: Nobody else should be accessing
++ * the page tables under spinlock protection here, only
++ * lockless_pages_from_mm() and the hardware page walker can access page
++ * tables while all the high-level locks are held in write mode.
++ */
+ start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
+
+ /* step 1: check all mapped PTEs are to the right huge page */
+@@ -1476,6 +1526,9 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+
+ /* step 4: collapse pmd */
+ collapse_and_free_pmd(mm, vma, haddr, pmd);
++
++ i_mmap_unlock_write(vma->vm_file->f_mapping);
++
+ drop_hpage:
+ unlock_page(hpage);
+ put_page(hpage);
+@@ -1483,6 +1536,7 @@ drop_hpage:
+
+ abort:
+ pte_unmap_unlock(start_pte, ptl);
++ i_mmap_unlock_write(vma->vm_file->f_mapping);
+ goto drop_hpage;
+ }
+
+@@ -1531,7 +1585,8 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ * An alternative would be drop the check, but check that page
+ * table is clear before calling pmdp_collapse_flush() under
+ * ptl. It has higher chance to recover THP for the VMA, but
+- * has higher cost too.
++ * has higher cost too. It would also probably require locking
++ * the anon_vma.
+ */
+ if (vma->anon_vma)
+ continue;
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 98ed17a4471a0..b2831b57aef8c 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -770,8 +770,8 @@ static int madvise_free_single_vma(struct vm_area_struct *vma,
+ * Application no longer needs these pages. If the pages are dirty,
+ * it's OK to just throw them away. The app will be more careful about
+ * data it wants to keep. Be sure to free swap resources too. The
+- * zap_page_range call sets things up for shrink_active_list to actually free
+- * these pages later if no one else has touched them in the meantime,
++ * zap_page_range_single call sets things up for shrink_active_list to actually
++ * free these pages later if no one else has touched them in the meantime,
+ * although we could add these pages to a global reuse list for
+ * shrink_active_list to pick up before reclaiming other pages.
+ *
+@@ -788,7 +788,7 @@ static int madvise_free_single_vma(struct vm_area_struct *vma,
+ static long madvise_dontneed_single_vma(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+ {
+- zap_page_range(vma, start, end - start);
++ zap_page_range_single(vma, start, end - start, NULL);
+ return 0;
+ }
+
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 6a95ea7c5ee70..f2fc11ba24267 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4772,6 +4772,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ unsigned int efd, cfd;
+ struct fd efile;
+ struct fd cfile;
++ struct dentry *cdentry;
+ const char *name;
+ char *endp;
+ int ret;
+@@ -4825,6 +4826,16 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ if (ret < 0)
+ goto out_put_cfile;
+
++ /*
++ * The control file must be a regular cgroup1 file. As a regular cgroup
++ * file can't be renamed, it's safe to access its name afterwards.
++ */
++ cdentry = cfile.file->f_path.dentry;
++ if (cdentry->d_sb->s_type != &cgroup_fs_type || !d_is_reg(cdentry)) {
++ ret = -EINVAL;
++ goto out_put_cfile;
++ }
++
+ /*
+ * Determine the event callbacks and set them in @event. This used
+ * to be done via struct cftype but cgroup core no longer knows
+@@ -4833,7 +4844,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ *
+ * DO NOT ADD NEW FILES.
+ */
+- name = cfile.file->f_path.dentry->d_name.name;
++ name = cdentry->d_name.name;
+
+ if (!strcmp(name, "memory.usage_in_bytes")) {
+ event->register_event = mem_cgroup_usage_register_event;
+@@ -4857,7 +4868,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ * automatically removed on cgroup destruction but the removal is
+ * asynchronous, so take an extra ref on @css.
+ */
+- cfile_css = css_tryget_online_from_dir(cfile.file->f_path.dentry->d_parent,
++ cfile_css = css_tryget_online_from_dir(cdentry->d_parent,
+ &memory_cgrp_subsys);
+ ret = -EINVAL;
+ if (IS_ERR(cfile_css))
+diff --git a/mm/memory.c b/mm/memory.c
+index de0dbe09b013f..a0fdaa74091fe 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1341,15 +1341,6 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+ return ret;
+ }
+
+-/*
+- * Parameter block passed down to zap_pte_range in exceptional cases.
+- */
+-struct zap_details {
+- struct folio *single_folio; /* Locked folio to be unmapped */
+- bool even_cows; /* Zap COWed private pages too? */
+- zap_flags_t zap_flags; /* Extra flags for zapping */
+-};
+-
+ /* Whether we should zap all COWed (private) pages too */
+ static inline bool should_zap_cows(struct zap_details *details)
+ {
+@@ -1721,7 +1712,7 @@ void unmap_vmas(struct mmu_gather *tlb,
+ {
+ struct mmu_notifier_range range;
+ struct zap_details details = {
+- .zap_flags = ZAP_FLAG_DROP_MARKER,
++ .zap_flags = ZAP_FLAG_DROP_MARKER | ZAP_FLAG_UNMAP,
+ /* Careful - we need to zap private pages too! */
+ .even_cows = true,
+ };
+@@ -1769,19 +1760,27 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start,
+ *
+ * The range must fit into one VMA.
+ */
+-static void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
++void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
+ unsigned long size, struct zap_details *details)
+ {
++ const unsigned long end = address + size;
+ struct mmu_notifier_range range;
+ struct mmu_gather tlb;
+
+ lru_add_drain();
+ mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm,
+- address, address + size);
++ address, end);
++ if (is_vm_hugetlb_page(vma))
++ adjust_range_if_pmd_sharing_possible(vma, &range.start,
++ &range.end);
+ tlb_gather_mmu(&tlb, vma->vm_mm);
+ update_hiwater_rss(vma->vm_mm);
+ mmu_notifier_invalidate_range_start(&range);
+- unmap_single_vma(&tlb, vma, address, range.end, details);
++ /*
++ * unmap 'address-end' not 'range.start-range.end' as range
++ * could have been expanded for hugetlb pmd sharing.
++ */
++ unmap_single_vma(&tlb, vma, address, end, details);
+ mmu_notifier_invalidate_range_end(&range);
+ tlb_finish_mmu(&tlb);
+ }
+diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c
+index a71924bd38c0d..ba7d26a291dda 100644
+--- a/mm/mmu_gather.c
++++ b/mm/mmu_gather.c
+@@ -152,7 +152,7 @@ static void tlb_remove_table_smp_sync(void *arg)
+ /* Simply deliver the interrupt */
+ }
+
+-static void tlb_remove_table_sync_one(void)
++void tlb_remove_table_sync_one(void)
+ {
+ /*
+ * This isn't an RCU grace period and hence the page-tables cannot be
+@@ -176,8 +176,6 @@ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+
+ #else /* !CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+-static void tlb_remove_table_sync_one(void) { }
+-
+ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+ {
+ __tlb_remove_table_free(batch);
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 42e5888bf84d8..112ebf601bb41 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -958,6 +958,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
+ index++;
+ }
+
++ /*
++ * When undoing a failed fallocate, we want none of the partial folio
++ * zeroing and splitting below, but shall want to truncate the whole
++ * folio when !uptodate indicates that it was added by this fallocate,
++ * even when [lstart, lend] covers only a part of the folio.
++ */
++ if (unfalloc)
++ goto whole_folios;
++
+ same_folio = (lstart >> PAGE_SHIFT) == (lend >> PAGE_SHIFT);
+ folio = shmem_get_partial_folio(inode, lstart >> PAGE_SHIFT);
+ if (folio) {
+@@ -983,6 +992,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
+ folio_put(folio);
+ }
+
++whole_folios:
++
+ index = start;
+ while (index < end) {
+ cond_resched();
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 3e056fb043bb1..080b5de3e1ed8 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -120,7 +120,7 @@ struct p9_conn {
+ struct list_head unsent_req_list;
+ struct p9_req_t *rreq;
+ struct p9_req_t *wreq;
+- char tmp_buf[7];
++ char tmp_buf[P9_HDRSZ];
+ struct p9_fcall rc;
+ int wpos;
+ int wsize;
+@@ -293,7 +293,7 @@ static void p9_read_work(struct work_struct *work)
+ if (!m->rc.sdata) {
+ m->rc.sdata = m->tmp_buf;
+ m->rc.offset = 0;
+- m->rc.capacity = 7; /* start by reading header */
++ m->rc.capacity = P9_HDRSZ; /* start by reading header */
+ }
+
+ clear_bit(Rpending, &m->wsched);
+@@ -316,7 +316,7 @@ static void p9_read_work(struct work_struct *work)
+ p9_debug(P9_DEBUG_TRANS, "got new header\n");
+
+ /* Header size */
+- m->rc.size = 7;
++ m->rc.size = P9_HDRSZ;
+ err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
+ if (err) {
+ p9_debug(P9_DEBUG_ERROR,
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 227f89cc7237c..0f862d5a59601 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -208,6 +208,14 @@ static void p9_xen_response(struct work_struct *work)
+ continue;
+ }
+
++ if (h.size > req->rc.capacity) {
++ dev_warn(&priv->dev->dev,
++ "requested packet size too big: %d for tag %d with capacity %zd\n",
++ h.size, h.tag, req->rc.capacity);
++ req->status = REQ_STATUS_ERROR;
++ goto recv_error;
++ }
++
+ memcpy(&req->rc, &h, sizeof(h));
+ req->rc.offset = 0;
+
+@@ -217,6 +225,7 @@ static void p9_xen_response(struct work_struct *work)
+ masked_prod, &masked_cons,
+ XEN_9PFS_RING_SIZE(ring));
+
++recv_error:
+ virt_mb();
+ cons += h.size;
+ ring->intf->in_cons = cons;
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 215af9b3b5895..c57d643afb108 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -972,6 +972,7 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ hci_dev_lock(hdev);
+ hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
+ hci_dev_unlock(hdev);
++ hci_dev_put(hdev);
+
+ if (!hcon)
+ return -ENOENT;
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index dc65974f5adb1..1c3c7ff5c3c66 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -737,7 +737,7 @@ static int __init bt_init(void)
+
+ err = bt_sysfs_init();
+ if (err < 0)
+- return err;
++ goto cleanup_led;
+
+ err = sock_register(&bt_sock_family_ops);
+ if (err)
+@@ -773,6 +773,8 @@ unregister_socket:
+ sock_unregister(PF_BLUETOOTH);
+ cleanup_sysfs:
+ bt_sysfs_cleanup();
++cleanup_led:
++ bt_leds_cleanup();
+ return err;
+ }
+
+diff --git a/net/bluetooth/hci_codec.c b/net/bluetooth/hci_codec.c
+index 38201532f58e8..3cc135bb1d30c 100644
+--- a/net/bluetooth/hci_codec.c
++++ b/net/bluetooth/hci_codec.c
+@@ -72,9 +72,8 @@ static void hci_read_codec_capabilities(struct hci_dev *hdev, __u8 transport,
+ continue;
+ }
+
+- skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
+- sizeof(*cmd), cmd,
+- HCI_CMD_TIMEOUT);
++ skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
++ sizeof(*cmd), cmd, 0, HCI_CMD_TIMEOUT, NULL);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Failed to read codec capabilities (%ld)",
+ PTR_ERR(skb));
+@@ -127,8 +126,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ struct hci_op_read_local_codec_caps caps;
+ __u8 i;
+
+- skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
+- HCI_CMD_TIMEOUT);
++ skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
++ 0, HCI_CMD_TIMEOUT, NULL);
+
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
+@@ -158,7 +157,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ for (i = 0; i < std_codecs->num; i++) {
+ caps.id = std_codecs->codec[i];
+ caps.direction = 0x00;
+- hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
++ hci_read_codec_capabilities(hdev,
++ LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
+ }
+
+ skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
+@@ -178,7 +178,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ caps.cid = vnd_codecs->codec[i].cid;
+ caps.vid = vnd_codecs->codec[i].vid;
+ caps.direction = 0x00;
+- hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
++ hci_read_codec_capabilities(hdev,
++ LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
+ }
+
+ error:
+@@ -194,8 +195,8 @@ void hci_read_supported_codecs_v2(struct hci_dev *hdev)
+ struct hci_op_read_local_codec_caps caps;
+ __u8 i;
+
+- skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
+- HCI_CMD_TIMEOUT);
++ skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
++ 0, HCI_CMD_TIMEOUT, NULL);
+
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 6ae5aa5c0927b..c8ea03edd081f 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2757,7 +2757,8 @@ int hci_register_suspend_notifier(struct hci_dev *hdev)
+ {
+ int ret = 0;
+
+- if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
++ if (!hdev->suspend_notifier.notifier_call &&
++ !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
+ hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
+ ret = register_pm_notifier(&hdev->suspend_notifier);
+ }
+@@ -2769,8 +2770,11 @@ int hci_unregister_suspend_notifier(struct hci_dev *hdev)
+ {
+ int ret = 0;
+
+- if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks))
++ if (hdev->suspend_notifier.notifier_call) {
+ ret = unregister_pm_notifier(&hdev->suspend_notifier);
++ if (!ret)
++ hdev->suspend_notifier.notifier_call = NULL;
++ }
+
+ return ret;
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index f70798589bf51..a5e89e1b5452a 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -12,6 +12,7 @@
+ #include <net/bluetooth/mgmt.h>
+
+ #include "hci_request.h"
++#include "hci_codec.h"
+ #include "hci_debugfs.h"
+ #include "smp.h"
+ #include "eir.h"
+@@ -3459,7 +3460,8 @@ static int hci_read_page_scan_activity_sync(struct hci_dev *hdev)
+ static int hci_read_def_err_data_reporting_sync(struct hci_dev *hdev)
+ {
+ if (!(hdev->commands[18] & 0x04) ||
+- !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
++ !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
++ test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_READ_DEF_ERR_DATA_REPORTING,
+@@ -3917,11 +3919,12 @@ static int hci_set_event_mask_page_2_sync(struct hci_dev *hdev)
+ /* Read local codec list if the HCI command is supported */
+ static int hci_read_local_codecs_sync(struct hci_dev *hdev)
+ {
+- if (!(hdev->commands[29] & 0x20))
+- return 0;
++ if (hdev->commands[45] & 0x04)
++ hci_read_supported_codecs_v2(hdev);
++ else if (hdev->commands[29] & 0x20)
++ hci_read_supported_codecs(hdev);
+
+- return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
+- HCI_CMD_TIMEOUT);
++ return 0;
+ }
+
+ /* Read local pairing options if the HCI command is supported */
+@@ -3977,7 +3980,8 @@ static int hci_set_err_data_report_sync(struct hci_dev *hdev)
+ bool enabled = hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED);
+
+ if (!(hdev->commands[18] & 0x08) ||
+- !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
++ !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
++ test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
+ return 0;
+
+ if (enabled == hdev->err_data_reporting)
+@@ -4136,6 +4140,9 @@ static const struct {
+ HCI_QUIRK_BROKEN(STORED_LINK_KEY,
+ "HCI Delete Stored Link Key command is advertised, "
+ "but not supported."),
++ HCI_QUIRK_BROKEN(ERR_DATA_REPORTING,
++ "HCI Read Default Erroneous Data Reporting command is "
++ "advertised, but not supported."),
+ HCI_QUIRK_BROKEN(READ_TRANSMIT_POWER,
+ "HCI Read Transmit Power Level command is advertised, "
+ "but not supported."),
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index f825857db6d0b..26db929b97c43 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -879,6 +879,7 @@ static int iso_listen_bis(struct sock *sk)
+ iso_pi(sk)->bc_sid);
+
+ hci_dev_unlock(hdev);
++ hci_dev_put(hdev);
+
+ return err;
+ }
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index e48ccf7cf2007..461fa7c04464b 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -680,7 +680,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
+ {
+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+
+- if (unlikely(dev->type != ARPHRD_CAN || skb->len != CAN_MTU)) {
++ if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || skb->len != CAN_MTU)) {
+ pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
+ dev->type, skb->len);
+ goto free_skb;
+@@ -706,7 +706,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
+ {
+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+
+- if (unlikely(dev->type != ARPHRD_CAN || skb->len != CANFD_MTU)) {
++ if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || skb->len != CANFD_MTU)) {
+ pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
+ dev->type, skb->len);
+ goto free_skb;
+diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c
+index 846588c0070a5..53a206d116850 100644
+--- a/net/dsa/tag_hellcreek.c
++++ b/net/dsa/tag_hellcreek.c
+@@ -49,7 +49,8 @@ static struct sk_buff *hellcreek_rcv(struct sk_buff *skb,
+ return NULL;
+ }
+
+- pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN);
++ if (pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN))
++ return NULL;
+
+ dsa_default_offload_fwd_mark(skb);
+
+diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
+index 38fa19c1e2d5e..429250298ac4b 100644
+--- a/net/dsa/tag_ksz.c
++++ b/net/dsa/tag_ksz.c
+@@ -21,7 +21,8 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
+ if (!skb->dev)
+ return NULL;
+
+- pskb_trim_rcsum(skb, skb->len - len);
++ if (pskb_trim_rcsum(skb, skb->len - len))
++ return NULL;
+
+ dsa_default_offload_fwd_mark(skb);
+
+diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
+index 83e4136516b02..1a85125bda6da 100644
+--- a/net/dsa/tag_sja1105.c
++++ b/net/dsa/tag_sja1105.c
+@@ -665,7 +665,8 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
+ * padding and trailer we need to account for the fact that
+ * skb->data points to skb_mac_header(skb) + ETH_HLEN.
+ */
+- pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN);
++ if (pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN))
++ return NULL;
+ /* Trap-to-host frame, no timestamp trailer */
+ } else {
+ *source_port = SJA1110_RX_HEADER_SRC_PORT(rx_header);
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 943edf4ad4db0..3528e8befa58f 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -841,6 +841,9 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
+ return -EINVAL;
+ }
+
++ if (!cfg->fc_table)
++ cfg->fc_table = RT_TABLE_MAIN;
++
+ return 0;
+ errout:
+ return err;
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index cb24260692e10..7885b2f15315e 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -423,6 +423,7 @@ static struct fib_info *fib_find_info(struct fib_info *nfi)
+ nfi->fib_prefsrc == fi->fib_prefsrc &&
+ nfi->fib_priority == fi->fib_priority &&
+ nfi->fib_type == fi->fib_type &&
++ nfi->fib_tb_id == fi->fib_tb_id &&
+ memcmp(nfi->fib_metrics, fi->fib_metrics,
+ sizeof(u32) * RTAX_MAX) == 0 &&
+ !((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_COMPARE_MASK) &&
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index f866d6282b2b3..cae9f1a4e059f 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -1492,24 +1492,6 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ struct ip_tunnel_parm *p = &t->parms;
+ __be16 o_flags = p->o_flags;
+
+- if (t->erspan_ver <= 2) {
+- if (t->erspan_ver != 0 && !t->collect_md)
+- o_flags |= TUNNEL_KEY;
+-
+- if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
+- goto nla_put_failure;
+-
+- if (t->erspan_ver == 1) {
+- if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
+- goto nla_put_failure;
+- } else if (t->erspan_ver == 2) {
+- if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
+- goto nla_put_failure;
+- if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
+- goto nla_put_failure;
+- }
+- }
+-
+ if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
+ nla_put_be16(skb, IFLA_GRE_IFLAGS,
+ gre_tnl_flags_to_gre_flags(p->i_flags)) ||
+@@ -1550,6 +1532,34 @@ nla_put_failure:
+ return -EMSGSIZE;
+ }
+
++static int erspan_fill_info(struct sk_buff *skb, const struct net_device *dev)
++{
++ struct ip_tunnel *t = netdev_priv(dev);
++
++ if (t->erspan_ver <= 2) {
++ if (t->erspan_ver != 0 && !t->collect_md)
++ t->parms.o_flags |= TUNNEL_KEY;
++
++ if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
++ goto nla_put_failure;
++
++ if (t->erspan_ver == 1) {
++ if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
++ goto nla_put_failure;
++ } else if (t->erspan_ver == 2) {
++ if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
++ goto nla_put_failure;
++ if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
++ goto nla_put_failure;
++ }
++ }
++
++ return ipgre_fill_info(skb, dev);
++
++nla_put_failure:
++ return -EMSGSIZE;
++}
++
+ static void erspan_setup(struct net_device *dev)
+ {
+ struct ip_tunnel *t = netdev_priv(dev);
+@@ -1628,7 +1638,7 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = {
+ .changelink = erspan_changelink,
+ .dellink = ip_tunnel_dellink,
+ .get_size = ipgre_get_size,
+- .fill_info = ipgre_fill_info,
++ .fill_info = erspan_fill_info,
+ .get_link_net = ip_tunnel_get_link_net,
+ };
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index b83c2bd9d7223..3b2420829c237 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -48,6 +48,11 @@
+ #include <net/transp_v6.h>
+ #endif
+
++#define ping_portaddr_for_each_entry(__sk, node, list) \
++ hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
++#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \
++ hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
++
+ struct ping_table {
+ struct hlist_nulls_head hash[PING_HTABLE_SIZE];
+ spinlock_t lock;
+@@ -191,7 +196,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ return NULL;
+ }
+
+- ping_portaddr_for_each_entry(sk, hnode, hslot) {
++ ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) {
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index f152e51242cb6..4fb5dd35af188 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -920,6 +920,9 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ if (err < 0)
+ goto fail;
+
++ /* We prevent @rt from being freed. */
++ rcu_read_lock();
++
+ for (;;) {
+ /* Prepare header of the next frame,
+ * before previous one went down. */
+@@ -943,6 +946,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ if (err == 0) {
+ IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
+ IPSTATS_MIB_FRAGOKS);
++ rcu_read_unlock();
+ return 0;
+ }
+
+@@ -950,6 +954,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+
+ IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
+ IPSTATS_MIB_FRAGFAILS);
++ rcu_read_unlock();
+ return err;
+
+ slow_path_clean:
+diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
+index 500ed1b812503..7e2065e729156 100644
+--- a/net/mac802154/iface.c
++++ b/net/mac802154/iface.c
+@@ -662,6 +662,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
+ sdata->dev = ndev;
+ sdata->wpan_dev.wpan_phy = local->hw.phy;
+ sdata->local = local;
++ INIT_LIST_HEAD(&sdata->wpan_dev.list);
+
+ /* setup type-dependent data */
+ ret = ieee802154_setup_sdata(sdata, type);
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 60289c074eef4..df46e9a35e47a 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -891,7 +891,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ zone = nf_ct_zone(ct);
+
+ if (!nf_ct_ext_valid_pre(ct->ext)) {
+- NF_CT_STAT_INC(net, insert_failed);
++ NF_CT_STAT_INC_ATOMIC(net, insert_failed);
+ return -ETIMEDOUT;
+ }
+
+@@ -938,7 +938,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+
+ if (!nf_ct_ext_valid_post(ct->ext)) {
+ nf_ct_kill(ct);
+- NF_CT_STAT_INC(net, drop);
++ NF_CT_STAT_INC_ATOMIC(net, drop);
+ return -ETIMEDOUT;
+ }
+
+@@ -1275,7 +1275,7 @@ chaintoolong:
+ */
+ if (!nf_ct_ext_valid_post(ct->ext)) {
+ nf_ct_kill(ct);
+- NF_CT_STAT_INC(net, drop);
++ NF_CT_STAT_INC_ATOMIC(net, drop);
+ return NF_DROP;
+ }
+
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d71150a40fb08..1286ae7d46096 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,8 +328,13 @@ nla_put_failure:
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
++static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+ {
++ u32 mark = READ_ONCE(ct->mark);
++
++ if (!mark)
++ return 0;
++
+ if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ goto nla_put_failure;
+ return 0;
+@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ if (ctnetlink_dump_status(skb, ct) < 0 ||
+- ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
++ ctnetlink_dump_mark(skb, ct) < 0 ||
+ ctnetlink_dump_secctx(skb, ct) < 0 ||
+ ctnetlink_dump_id(skb, ct) < 0 ||
+ ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ struct sk_buff *skb;
+ unsigned int type;
+ unsigned int flags = 0, group;
+- u32 mark;
+ int err;
+
+ if (events & (1 << IPCT_DESTROY)) {
+@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- mark = READ_ONCE(ct->mark);
+- if ((events & (1 << IPCT_MARK) || mark) &&
+- ctnetlink_dump_mark(skb, mark) < 0)
++ if (events & (1 << IPCT_MARK) &&
++ ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+ #endif
+ nlmsg_end(skb, nlh);
+@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ const struct nf_conntrack_zone *zone;
+ struct nlattr *nest_parms;
+- u32 mark;
+
+ zone = nf_ct_zone(ct);
+
+@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ goto nla_put_failure;
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+- mark = READ_ONCE(ct->mark);
+- if (mark && ctnetlink_dump_mark(skb, mark) < 0)
++ if (ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+ #endif
+ if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 00b522890d77b..0fdcdb2c9ae43 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -997,13 +997,13 @@ static void flow_offload_queue_work(struct flow_offload_work *offload)
+ struct net *net = read_pnet(&offload->flowtable->net);
+
+ if (offload->cmd == FLOW_CLS_REPLACE) {
+- NF_FLOW_TABLE_STAT_INC(net, count_wq_add);
++ NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_add);
+ queue_work(nf_flow_offload_add_wq, &offload->work);
+ } else if (offload->cmd == FLOW_CLS_DESTROY) {
+- NF_FLOW_TABLE_STAT_INC(net, count_wq_del);
++ NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_del);
+ queue_work(nf_flow_offload_del_wq, &offload->work);
+ } else {
+- NF_FLOW_TABLE_STAT_INC(net, count_wq_stats);
++ NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_stats);
+ queue_work(nf_flow_offload_stats_wq, &offload->work);
+ }
+ }
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 4f9299b9dcddc..06d46d1826347 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -1162,6 +1162,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
+ struct nft_pipapo_match *m = priv->clone;
+ u8 genmask = nft_genmask_next(net);
+ struct nft_pipapo_field *f;
++ const u8 *start_p, *end_p;
+ int i, bsize_max, err = 0;
+
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END))
+@@ -1202,9 +1203,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
+ }
+
+ /* Validate */
++ start_p = start;
++ end_p = end;
+ nft_pipapo_for_each_field(f, i, m) {
+- const u8 *start_p = start, *end_p = end;
+-
+ if (f->rules >= (unsigned long)NFT_PIPAPO_RULE0_MAX)
+ return -ENOSPC;
+
+diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
+index 282c51051dccd..994a0a1efb589 100644
+--- a/net/nfc/nci/ntf.c
++++ b/net/nfc/nci/ntf.c
+@@ -240,6 +240,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ target->sens_res = nfca_poll->sens_res;
+ target->sel_res = nfca_poll->sel_res;
+ target->nfcid1_len = nfca_poll->nfcid1_len;
++ if (target->nfcid1_len > ARRAY_SIZE(target->nfcid1))
++ return -EPROTO;
+ if (target->nfcid1_len > 0) {
+ memcpy(target->nfcid1, nfca_poll->nfcid1,
+ target->nfcid1_len);
+@@ -248,6 +250,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
+
+ target->sensb_res_len = nfcb_poll->sensb_res_len;
++ if (target->sensb_res_len > ARRAY_SIZE(target->sensb_res))
++ return -EPROTO;
+ if (target->sensb_res_len > 0) {
+ memcpy(target->sensb_res, nfcb_poll->sensb_res,
+ target->sensb_res_len);
+@@ -256,6 +260,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
+
+ target->sensf_res_len = nfcf_poll->sensf_res_len;
++ if (target->sensf_res_len > ARRAY_SIZE(target->sensf_res))
++ return -EPROTO;
+ if (target->sensf_res_len > 0) {
+ memcpy(target->sensf_res, nfcf_poll->sensf_res,
+ target->sensf_res_len);
+diff --git a/net/tipc/link.c b/net/tipc/link.c
+index e260c0d557f5c..b3ce24823f503 100644
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -2224,7 +2224,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
+ if (tipc_own_addr(l->net) > msg_prevnode(hdr))
+ l->net_plane = msg_net_plane(hdr);
+
+- skb_linearize(skb);
++ if (skb_linearize(skb))
++ goto exit;
++
+ hdr = buf_msg(skb);
+ data = msg_data(hdr);
+
+diff --git a/net/tipc/node.c b/net/tipc/node.c
+index b48d97cbbe29c..49ddc484c4fe7 100644
+--- a/net/tipc/node.c
++++ b/net/tipc/node.c
+@@ -1689,6 +1689,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
+ struct tipc_node *n;
+ struct sk_buff_head xmitq;
+ bool node_up = false;
++ struct net *peer_net;
+ int bearer_id;
+ int rc;
+
+@@ -1705,18 +1706,23 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
+ return -EHOSTUNREACH;
+ }
+
++ rcu_read_lock();
+ tipc_node_read_lock(n);
+ node_up = node_is_up(n);
+- if (node_up && n->peer_net && check_net(n->peer_net)) {
++ peer_net = n->peer_net;
++ tipc_node_read_unlock(n);
++ if (node_up && peer_net && check_net(peer_net)) {
+ /* xmit inner linux container */
+- tipc_lxc_xmit(n->peer_net, list);
++ tipc_lxc_xmit(peer_net, list);
+ if (likely(skb_queue_empty(list))) {
+- tipc_node_read_unlock(n);
++ rcu_read_unlock();
+ tipc_node_put(n);
+ return 0;
+ }
+ }
++ rcu_read_unlock();
+
++ tipc_node_read_lock(n);
+ bearer_id = n->active_links[selector & 1];
+ if (unlikely(bearer_id == INVALID_BEARER_ID)) {
+ tipc_node_read_unlock(n);
+diff --git a/net/unix/diag.c b/net/unix/diag.c
+index 105f522a89fe0..616b55c5b8908 100644
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -114,14 +114,16 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
+ return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql);
+ }
+
+-static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb)
++static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb,
++ struct user_namespace *user_ns)
+ {
+- uid_t uid = from_kuid_munged(sk_user_ns(nlskb->sk), sock_i_uid(sk));
++ uid_t uid = from_kuid_munged(user_ns, sock_i_uid(sk));
+ return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid);
+ }
+
+ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
+- u32 portid, u32 seq, u32 flags, int sk_ino)
++ struct user_namespace *user_ns,
++ u32 portid, u32 seq, u32 flags, int sk_ino)
+ {
+ struct nlmsghdr *nlh;
+ struct unix_diag_msg *rep;
+@@ -167,7 +169,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
+ goto out_nlmsg_trim;
+
+ if ((req->udiag_show & UDIAG_SHOW_UID) &&
+- sk_diag_dump_uid(sk, skb))
++ sk_diag_dump_uid(sk, skb, user_ns))
+ goto out_nlmsg_trim;
+
+ nlmsg_end(skb, nlh);
+@@ -179,7 +181,8 @@ out_nlmsg_trim:
+ }
+
+ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
+- u32 portid, u32 seq, u32 flags)
++ struct user_namespace *user_ns,
++ u32 portid, u32 seq, u32 flags)
+ {
+ int sk_ino;
+
+@@ -190,7 +193,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
+ if (!sk_ino)
+ return 0;
+
+- return sk_diag_fill(sk, skb, req, portid, seq, flags, sk_ino);
++ return sk_diag_fill(sk, skb, req, user_ns, portid, seq, flags, sk_ino);
+ }
+
+ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+@@ -214,7 +217,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ goto next;
+ if (!(req->udiag_states & (1 << sk->sk_state)))
+ goto next;
+- if (sk_diag_dump(sk, skb, req,
++ if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI) < 0) {
+@@ -282,7 +285,8 @@ again:
+ if (!rep)
+ goto out;
+
+- err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).portid,
++ err = sk_diag_fill(sk, rep, req, sk_user_ns(NETLINK_CB(in_skb).sk),
++ NETLINK_CB(in_skb).portid,
+ nlh->nlmsg_seq, 0, req->udiag_ino);
+ if (err < 0) {
+ nlmsg_free(rep);
+diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
+index b7aee23fc3876..47ef6bc30c0ee 100644
+--- a/sound/core/seq/seq_memory.c
++++ b/sound/core/seq/seq_memory.c
+@@ -113,15 +113,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event);
+ * expand the variable length event to linear buffer space.
+ */
+
+-static int seq_copy_in_kernel(char **bufptr, const void *src, int size)
++static int seq_copy_in_kernel(void *ptr, void *src, int size)
+ {
++ char **bufptr = ptr;
++
+ memcpy(*bufptr, src, size);
+ *bufptr += size;
+ return 0;
+ }
+
+-static int seq_copy_in_user(char __user **bufptr, const void *src, int size)
++static int seq_copy_in_user(void *ptr, void *src, int size)
+ {
++ char __user **bufptr = ptr;
++
+ if (copy_to_user(*bufptr, src, size))
+ return -EFAULT;
+ *bufptr += size;
+@@ -151,8 +155,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
+ return newlen;
+ }
+ err = snd_seq_dump_var_event(event,
+- in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel :
+- (snd_seq_dump_func_t)seq_copy_in_user,
++ in_kernel ? seq_copy_in_kernel : seq_copy_in_user,
+ &buf);
+ return err < 0 ? err : newlen;
+ }
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index bf58e98c7a699..d8c6af9e43ad6 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -18,6 +18,7 @@
+ #include <linux/module.h>
+ #include <linux/input.h>
+ #include <linux/leds.h>
++#include <linux/ctype.h>
+ #include <sound/core.h>
+ #include <sound/jack.h>
+ #include <sound/hda_codec.h>
+@@ -6704,23 +6705,51 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
+ }
+ }
+
++struct cs35l41_dev_name {
++ const char *bus;
++ const char *hid;
++ int index;
++};
++
++/* match the device name in a slightly relaxed manner */
++static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
++{
++ struct cs35l41_dev_name *p = data;
++ const char *d = dev_name(dev);
++ int n = strlen(p->bus);
++ char tmp[32];
++
++ /* check the bus name */
++ if (strncmp(d, p->bus, n))
++ return 0;
++ /* skip the bus number */
++ if (isdigit(d[n]))
++ n++;
++ /* the rest must be exact matching */
++ snprintf(tmp, sizeof(tmp), "-%s:00-cs35l41-hda.%d", p->hid, p->index);
++ return !strcmp(d + n, tmp);
++}
++
+ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
+ const char *hid, int count)
+ {
+ struct device *dev = hda_codec_dev(cdc);
+ struct alc_spec *spec = cdc->spec;
+- char *name;
++ struct cs35l41_dev_name *rec;
+ int ret, i;
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ for (i = 0; i < count; i++) {
+- name = devm_kasprintf(dev, GFP_KERNEL,
+- "%s-%s:00-cs35l41-hda.%d", bus, hid, i);
+- if (!name)
++ rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL);
++ if (!rec)
+ return;
++ rec->bus = bus;
++ rec->hid = hid;
++ rec->index = i;
+ spec->comps[i].codec = cdc;
+- component_match_add(dev, &spec->match, component_compare_dev_name, name);
++ component_match_add(dev, &spec->match,
++ comp_match_cs35l41_dev_name, rec);
+ }
+ ret = component_master_add_with_match(dev, &comp_master_ops, spec->match);
+ if (ret)
+@@ -6738,17 +6767,12 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup
+
+ static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+- cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2);
+-}
+-
+-static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+-{
+- cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2);
++ cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 2);
+ }
+
+ static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+- cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
++ cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 4);
+ }
+
+ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
+@@ -7137,8 +7161,6 @@ enum {
+ ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ ALC245_FIXUP_CS35L41_SPI_2,
+ ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
+- ALC245_FIXUP_CS35L41_SPI1_2,
+- ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED,
+ ALC245_FIXUP_CS35L41_SPI_4,
+ ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
+ ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+@@ -8988,16 +9010,6 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC285_FIXUP_HP_GPIO_LED,
+ },
+- [ALC245_FIXUP_CS35L41_SPI1_2] = {
+- .type = HDA_FIXUP_FUNC,
+- .v.func = cs35l41_fixup_spi1_two,
+- },
+- [ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = {
+- .type = HDA_FIXUP_FUNC,
+- .v.func = cs35l41_fixup_spi1_two,
+- .chained = true,
+- .chain_id = ALC285_FIXUP_HP_GPIO_LED,
+- },
+ [ALC245_FIXUP_CS35L41_SPI_4] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_spi_four,
+@@ -9361,7 +9373,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED),
+- SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index a085b2f530aa1..31e77d462ef34 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -230,7 +230,7 @@ static int rt711_sdca_read_prop(struct sdw_slave *slave)
+ }
+
+ /* set the timeout values */
+- prop->clk_stop_timeout = 20;
++ prop->clk_stop_timeout = 700;
+
+ /* wake-up event */
+ prop->wake_capable = 1;
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 6df06fba43778..ee1cad5af5353 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -2503,6 +2503,14 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
+ snd_soc_component_update_bits(component, WM8962_CLOCKING2,
+ WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
+
++ /* DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate
++ * correct frequency of LRCLK and BCLK. Sometimes the read-only value
++ * can't be updated timely after enabling SYSCLK. This results in wrong
++ * calculation values. Delay is introduced here to wait for newest
++ * value from register. The time of the delay should be at least
++ * 500~1000us according to test.
++ */
++ usleep_range(500, 1000);
+ dspclk = snd_soc_component_read(component, WM8962_CLOCKING1);
+
+ if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index f6a996f0f9c74..f000a7168afc6 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1242,6 +1242,8 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
+ return;
+
+ be_substream = snd_soc_dpcm_get_substream(be, stream);
++ if (!be_substream)
++ return;
+
+ for_each_dpcm_fe(be, stream, dpcm) {
+ if (dpcm->fe == fe)
+diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
+index ead7963b9bf0b..bd89198cd8176 100644
+--- a/tools/testing/selftests/net/config
++++ b/tools/testing/selftests/net/config
+@@ -43,5 +43,5 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
+ CONFIG_NET_ACT_MIRRED=m
+ CONFIG_BAREUDP=m
+ CONFIG_IPV6_IOAM6_LWTUNNEL=y
+-CONFIG_CRYPTO_SM4=y
++CONFIG_CRYPTO_SM4_GENERIC=y
+ CONFIG_AMT=m
+diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
+index 31c3b6ebd388b..21ca91473c095 100755
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -4196,10 +4196,13 @@ elif [ "$TESTS" = "ipv6" ]; then
+ TESTS="$TESTS_IPV6"
+ fi
+
+-which nettest >/dev/null
+-if [ $? -ne 0 ]; then
+- echo "'nettest' command not found; skipping tests"
+- exit $ksft_skip
++# nettest can be run from PATH or from same directory as this selftest
++if ! which nettest >/dev/null; then
++ PATH=$PWD:$PATH
++ if ! which nettest >/dev/null; then
++ echo "'nettest' command not found; skipping tests"
++ exit $ksft_skip
++ fi
+ fi
+
+ declare -i nfail=0
+diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
+index 2271a8727f623..5637b5dadabdb 100755
+--- a/tools/testing/selftests/net/fib_tests.sh
++++ b/tools/testing/selftests/net/fib_tests.sh
+@@ -1711,13 +1711,21 @@ ipv4_del_addr_test()
+
+ $IP addr add dev dummy1 172.16.104.1/24
+ $IP addr add dev dummy1 172.16.104.11/24
++ $IP addr add dev dummy1 172.16.104.12/24
++ $IP addr add dev dummy1 172.16.104.13/24
+ $IP addr add dev dummy2 172.16.104.1/24
+ $IP addr add dev dummy2 172.16.104.11/24
++ $IP addr add dev dummy2 172.16.104.12/24
+ $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
++ $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
++ $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
+ $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
++ $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
+ set +e
+
+ # removing address from device in vrf should only remove route from vrf table
++ echo " Regular FIB info"
++
+ $IP addr del dev dummy2 172.16.104.11/24
+ $IP ro ls vrf red | grep -q 172.16.105.0/24
+ log_test $? 1 "Route removed from VRF when source address deleted"
+@@ -1735,6 +1743,35 @@ ipv4_del_addr_test()
+ $IP ro ls vrf red | grep -q 172.16.105.0/24
+ log_test $? 0 "Route in VRF is not removed by address delete"
+
++ # removing address from device in vrf should only remove route from vrf
++ # table even when the associated fib info only differs in table ID
++ echo " Identical FIB info with different table ID"
++
++ $IP addr del dev dummy2 172.16.104.12/24
++ $IP ro ls vrf red | grep -q 172.16.106.0/24
++ log_test $? 1 "Route removed from VRF when source address deleted"
++
++ $IP ro ls | grep -q 172.16.106.0/24
++ log_test $? 0 "Route in default VRF not removed"
++
++ $IP addr add dev dummy2 172.16.104.12/24
++ $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
++
++ $IP addr del dev dummy1 172.16.104.12/24
++ $IP ro ls | grep -q 172.16.106.0/24
++ log_test $? 1 "Route removed in default VRF when source address deleted"
++
++ $IP ro ls vrf red | grep -q 172.16.106.0/24
++ log_test $? 0 "Route in VRF is not removed by address delete"
++
++ # removing address from device in default vrf should remove route from
++ # the default vrf even when route was inserted with a table ID of 0.
++ echo " Table ID 0"
++
++ $IP addr del dev dummy1 172.16.104.13/24
++ $IP ro ls | grep -q 172.16.107.0/24
++ log_test $? 1 "Route removed in default VRF when source address deleted"
++
+ $IP li del dummy1
+ $IP li del dummy2
+ cleanup
+diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
+index 736e358dc549d..dfe3d287f01d2 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -686,10 +686,12 @@ setup_xfrm() {
+ }
+
+ setup_nettest_xfrm() {
+- which nettest >/dev/null
+- if [ $? -ne 0 ]; then
+- echo "'nettest' command not found; skipping tests"
+- return 1
++ if ! which nettest >/dev/null; then
++ PATH=$PWD:$PATH
++ if ! which nettest >/dev/null; then
++ echo "'nettest' command not found; skipping tests"
++ return 1
++ fi
+ fi
+
+ [ ${1} -eq 6 ] && proto="-6" || proto=""
+diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
+index 0900c5438fbb6..275491be3da2f 100755
+--- a/tools/testing/selftests/net/rtnetlink.sh
++++ b/tools/testing/selftests/net/rtnetlink.sh
+@@ -782,7 +782,7 @@ kci_test_ipsec_offload()
+ tmpl proto esp src $srcip dst $dstip spi 9 \
+ mode transport reqid 42
+ check_err $?
+- ip x p add dir out src $dstip/24 dst $srcip/24 \
++ ip x p add dir in src $dstip/24 dst $srcip/24 \
+ tmpl proto esp src $dstip dst $srcip spi 9 \
+ mode transport reqid 42
+ check_err $?
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-14 12:51 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-14 12:51 UTC (permalink / raw
To: gentoo-commits
commit: f112e38167272c5ea2abb110c2151fa0c9f8ddbd
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 14 12:51:13 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Dec 14 12:51:13 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f112e381
Remove redundant patch
Removed:
2010_netfilter-ctnetlink-compilation-fix.patch
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 --
2010_netfilter-ctnetlink-compilation-fix.patch | 90 --------------------------
2 files changed, 94 deletions(-)
diff --git a/0000_README b/0000_README
index a5d5308b..78a95ddc 100644
--- a/0000_README
+++ b/0000_README
@@ -111,10 +111,6 @@ Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
-Patch: 2010_netfilter-ctnetlink-compilation-fix.patch
-From: https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
-Desc: netfilter: ctnetlink: fix compilation warning after data race fixes in ct mark
-
Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
From: https://bugs.gentoo.org/710790
Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
diff --git a/2010_netfilter-ctnetlink-compilation-fix.patch b/2010_netfilter-ctnetlink-compilation-fix.patch
deleted file mode 100644
index b7bd4dee..00000000
--- a/2010_netfilter-ctnetlink-compilation-fix.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 1feeae071507ad65cf9f462a1bdd543a4bf89e71 Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Mon, 28 Nov 2022 10:58:53 +0100
-Subject: netfilter: ctnetlink: fix compilation warning after data race fixes
- in ct mark
-
-All warnings (new ones prefixed by >>):
-
- net/netfilter/nf_conntrack_netlink.c: In function '__ctnetlink_glue_build':
->> net/netfilter/nf_conntrack_netlink.c:2674:13: warning: unused variable 'mark' [-Wunused-variable]
- 2674 | u32 mark;
- | ^~~~
-
-Fixes: 52d1aa8b8249 ("netfilter: conntrack: Fix data-races around ct mark")
-Reported-by: kernel test robot <lkp@intel.com>
-Tested-by: Ivan Babrou <ivan@ivan.computer>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
- net/netfilter/nf_conntrack_netlink.c | 19 ++++++++++---------
- 1 file changed, 10 insertions(+), 9 deletions(-)
-
-diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
-index d71150a40fb08..1286ae7d46096 100644
---- a/net/netfilter/nf_conntrack_netlink.c
-+++ b/net/netfilter/nf_conntrack_netlink.c
-@@ -328,8 +328,13 @@ nla_put_failure:
- }
-
- #ifdef CONFIG_NF_CONNTRACK_MARK
--static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
-+static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
- {
-+ u32 mark = READ_ONCE(ct->mark);
-+
-+ if (!mark)
-+ return 0;
-+
- if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
- goto nla_put_failure;
- return 0;
-@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
- static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
- {
- if (ctnetlink_dump_status(skb, ct) < 0 ||
-- ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
-+ ctnetlink_dump_mark(skb, ct) < 0 ||
- ctnetlink_dump_secctx(skb, ct) < 0 ||
- ctnetlink_dump_id(skb, ct) < 0 ||
- ctnetlink_dump_use(skb, ct) < 0 ||
-@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
- struct sk_buff *skb;
- unsigned int type;
- unsigned int flags = 0, group;
-- u32 mark;
- int err;
-
- if (events & (1 << IPCT_DESTROY)) {
-@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
- }
-
- #ifdef CONFIG_NF_CONNTRACK_MARK
-- mark = READ_ONCE(ct->mark);
-- if ((events & (1 << IPCT_MARK) || mark) &&
-- ctnetlink_dump_mark(skb, mark) < 0)
-+ if (events & (1 << IPCT_MARK) &&
-+ ctnetlink_dump_mark(skb, ct) < 0)
- goto nla_put_failure;
- #endif
- nlmsg_end(skb, nlh);
-@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
- {
- const struct nf_conntrack_zone *zone;
- struct nlattr *nest_parms;
-- u32 mark;
-
- zone = nf_ct_zone(ct);
-
-@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
- goto nla_put_failure;
-
- #ifdef CONFIG_NF_CONNTRACK_MARK
-- mark = READ_ONCE(ct->mark);
-- if (mark && ctnetlink_dump_mark(skb, mark) < 0)
-+ if (ctnetlink_dump_mark(skb, ct) < 0)
- goto nla_put_failure;
- #endif
- if (ctnetlink_dump_labels(skb, ct) < 0)
---
-cgit
-
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-16 19:56 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-16 19:56 UTC (permalink / raw
To: gentoo-commits
commit: 9367223686e9f04be347f8f929183e3bc40882ea
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Dec 16 19:56:24 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Dec 16 19:56:24 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=93672236
Update CPU Optimization patch
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
5010_enable-cpu-optimizations-universal.patch | 217 +++++++++++++++++++-------
1 file changed, 159 insertions(+), 58 deletions(-)
diff --git a/5010_enable-cpu-optimizations-universal.patch b/5010_enable-cpu-optimizations-universal.patch
index b9c03cb6..0841340b 100644
--- a/5010_enable-cpu-optimizations-universal.patch
+++ b/5010_enable-cpu-optimizations-universal.patch
@@ -1,10 +1,7 @@
-From b5892719c43f739343c628e3d357471a3bdaa368 Mon Sep 17 00:00:00 2001
-From: graysky <graysky@archlinux.us>
-Date: Tue, 15 Mar 2022 05:58:43 -0400
+From a0825feea3f100656d58446885b5f190284fd219
+From: graysky <therealgraysky@proton.me>
+Date: Fri, 4 Nov 2022 15:34:36 -0400
Subject: [PATCH] more uarches for kernel 5.17+
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
FEATURES
This patch adds additional CPU options to the Linux kernel accessible under:
@@ -36,6 +33,7 @@ CPU-specific microarchitectures include:
• AMD Family 17h (Zen)
• AMD Family 17h (Zen 2)
• AMD Family 19h (Zen 3)†
+• AMD Family 19h (Zen 4)§
• Intel Silvermont low-power processors
• Intel Goldmont low-power processors (Apollo Lake and Denverton)
• Intel Goldmont Plus low-power processors (Gemini Lake)
@@ -55,11 +53,14 @@ CPU-specific microarchitectures include:
• Intel 3rd Gen 10nm++ Xeon (Sapphire Rapids)‡
• Intel 11th Gen i3/i5/i7/i9-family (Rocket Lake)‡
• Intel 12th Gen i3/i5/i7/i9-family (Alder Lake)‡
+• Intel 13th Gen i3/i5/i7/i9-family (Raptor Lake)§
+• Intel 14th Gen i3/i5/i7/i9-family (Meteor Lake)§
Notes: If not otherwise noted, gcc >=9.1 is required for support.
*Requires gcc >=10.1 or clang >=10.0
†Required gcc >=10.3 or clang >=12.0
‡Required gcc >=11.1 or clang >=12.0
+ §Required gcc >=13.0 or clang >=15.0.5
It also offers to compile passing the 'native' option which, "selects the CPU
to generate code for at compilation time by determining the processor type of
@@ -99,20 +100,19 @@ REFERENCES
4. https://github.com/graysky2/kernel_gcc_patch/issues/15
5. http://www.linuxforge.net/docs/linux/linux-gcc.php
-Signed-off-by: graysky <graysky@archlinux.us>
---
- arch/x86/Kconfig.cpu | 332 ++++++++++++++++++++++++++++++--
- arch/x86/Makefile | 40 +++-
- arch/x86/include/asm/vermagic.h | 66 +++++++
- 3 files changed, 424 insertions(+), 14 deletions(-)
+ arch/x86/Kconfig.cpu | 416 ++++++++++++++++++++++++++++++--
+ arch/x86/Makefile | 43 +++-
+ arch/x86/include/asm/vermagic.h | 72 ++++++
+ 3 files changed, 514 insertions(+), 17 deletions(-)
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
-index 542377cd419d..22b919cdb6d1 100644
+index 542377cd419d..08d887d1220d 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -157,7 +157,7 @@ config MPENTIUM4
-
-
+
+
config MK6
- bool "K6/K6-II/K6-III"
+ bool "AMD K6/K6-II/K6-III"
@@ -121,16 +121,16 @@ index 542377cd419d..22b919cdb6d1 100644
Select this for an AMD K6-family processor. Enables use of
@@ -165,7 +165,7 @@ config MK6
flags to GCC.
-
+
config MK7
- bool "Athlon/Duron/K7"
+ bool "AMD Athlon/Duron/K7"
depends on X86_32
help
Select this for an AMD Athlon K7-family processor. Enables use of
-@@ -173,12 +173,98 @@ config MK7
+@@ -173,12 +173,106 @@ config MK7
flags to GCC.
-
+
config MK8
- bool "Opteron/Athlon64/Hammer/K8"
+ bool "AMD Opteron/Athlon64/Hammer/K8"
@@ -138,7 +138,7 @@ index 542377cd419d..22b919cdb6d1 100644
Select this for an AMD Opteron or Athlon64 Hammer-family processor.
Enables use of some extended instructions, and passes appropriate
optimization flags to GCC.
-
+
+config MK8SSE3
+ bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
+ help
@@ -224,32 +224,40 @@ index 542377cd419d..22b919cdb6d1 100644
+ Select this for AMD Family 19h Zen 3 processors.
+
+ Enables -march=znver3
++
++config MZEN4
++ bool "AMD Zen 4"
++ depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++ help
++ Select this for AMD Family 19h Zen 4 processors.
++
++ Enables -march=znver4
+
config MCRUSOE
bool "Crusoe"
depends on X86_32
-@@ -270,7 +356,7 @@ config MPSC
+@@ -270,7 +364,7 @@ config MPSC
in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
-
+
config MCORE2
- bool "Core 2/newer Xeon"
+ bool "Intel Core 2"
help
-
+
Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
-@@ -278,6 +364,8 @@ config MCORE2
+@@ -278,6 +372,8 @@ config MCORE2
family in /proc/cpuinfo. Newer ones have 6 and older ones 15
(not a typo)
-
+
+ Enables -march=core2
+
config MATOM
bool "Intel Atom"
help
-@@ -287,6 +375,182 @@ config MATOM
+@@ -287,6 +383,202 @@ config MATOM
accordingly optimized code. Use a recent GCC with specific Atom
support in order to fully benefit from selecting this option.
-
+
+config MNEHALEM
+ bool "Intel Nehalem"
+ select X86_P6_NOP
@@ -425,14 +433,34 @@ index 542377cd419d..22b919cdb6d1 100644
+ Select this for twelfth-generation processors in the Alder Lake family.
+
+ Enables -march=alderlake
++
++config MRAPTORLAKE
++ bool "Intel Raptor Lake"
++ depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++ select X86_P6_NOP
++ help
++
++ Select this for thirteenth-generation processors in the Raptor Lake family.
++
++ Enables -march=raptorlake
++
++config MMETEORLAKE
++ bool "Intel Meteor Lake"
++ depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++ select X86_P6_NOP
++ help
++
++ Select this for fourteenth-generation processors in the Meteor Lake family.
++
++ Enables -march=meteorlake
+
config GENERIC_CPU
bool "Generic-x86-64"
depends on X86_64
-@@ -294,6 +558,50 @@ config GENERIC_CPU
+@@ -294,6 +586,50 @@ config GENERIC_CPU
Generic x86-64 CPU.
Run equally well on all x86-64 CPUs.
-
+
+config GENERIC_CPU2
+ bool "Generic-x86-64-v2"
+ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
@@ -478,68 +506,133 @@ index 542377cd419d..22b919cdb6d1 100644
+ Enables -march=native
+
endchoice
-
+
config X86_GENERIC
-@@ -318,7 +626,7 @@ config X86_INTERNODE_CACHE_SHIFT
+@@ -318,9 +654,17 @@ config X86_INTERNODE_CACHE_SHIFT
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
- default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
-+ default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 || GENERIC_CPU4
++ default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 \
++ || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER \
++ || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT \
++ || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL \
++ || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++ || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE \
++ || MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 \
++ || GENERIC_CPU4
default "4" if MELAN || M486SX || M486 || MGEODEGX1
- default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-
-@@ -336,11 +644,11 @@ config X86_ALIGNMENT_16
-
+- default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
++ default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII \
++ || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
+
+ config X86_F00F_BUG
+ def_bool y
+@@ -332,15 +676,27 @@ config X86_INVD_BUG
+
+ config X86_ALIGNMENT_16
+ def_bool y
+- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486SX || M486 || MVIAC3_2 || MGEODEGX1
++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC \
++ || M586 || M486SX || M486 || MVIAC3_2 || MGEODEGX1
+
config X86_INTEL_USERCOPY
def_bool y
- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
-+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL
-
++ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC \
++ || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++ || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX \
++ || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS \
++ || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL
+
config X86_USE_PPRO_CHECKSUM
def_bool y
- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
-+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
-
++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM \
++ || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX \
++ || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER \
++ || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM \
++ || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE \
++ || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE \
++ || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE \
++ || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
#
# P6_NOPs are a relatively minor optimization that require a family >=
-@@ -356,26 +664,26 @@ config X86_USE_PPRO_CHECKSUM
+@@ -356,32 +712,62 @@ config X86_USE_PPRO_CHECKSUM
config X86_P6_NOP
def_bool y
depends on X86_64
- depends on (MCORE2 || MPENTIUM4 || MPSC)
-+ depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL)
-
++ depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++ || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE \
++ || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE \
++ || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL)
+
config X86_TSC
def_bool y
- depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
-+ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD) || X86_64
-
++ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM \
++ || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 \
++ || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER \
++ || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM \
++ || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL \
++ || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++ || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL \
++ || MNATIVE_AMD) || X86_64
+
config X86_CMPXCHG64
def_bool y
- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8
-+ depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
-
++ depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++ || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 \
++ || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN \
++ || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS \
++ || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE \
++ || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE \
++ || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
# this should be set for all -march=.. options where the compiler
# generates cmov.
config X86_CMOV
def_bool y
- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
-+ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
-
++ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++ || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 \
++ || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR \
++ || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++ || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX \
++ || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS \
++ || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+
config X86_MINIMUM_CPU_FAMILY
int
default "64" if X86_64
- default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8)
-+ default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
++ default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++ || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 || MK8SSE3 \
++ || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER \
++ || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT \
++ || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL \
++ || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++ || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MRAPTORLAKE \
++ || MNATIVE_INTEL || MNATIVE_AMD)
default "5" if X86_32 && X86_CMPXCHG64
default "4"
-
+
+ config X86_DEBUGCTLMSR
+ def_bool y
+- depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486SX || M486) && !UML
++ depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 \
++ || M486SX || M486) && !UML
+
+ config IA32_FEAT_CTL
+ def_bool y
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
-index e84cdd409b64..7d3bbf060079 100644
+index bafbd905e6e7..7fae52788560 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
-@@ -131,8 +131,44 @@ else
+@@ -150,8 +150,47 @@ else
# FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
cflags-$(CONFIG_MK8) += -march=k8
cflags-$(CONFIG_MPSC) += -march=nocona
@@ -557,6 +650,7 @@ index e84cdd409b64..7d3bbf060079 100644
+ cflags-$(CONFIG_MZEN) += -march=znver1
+ cflags-$(CONFIG_MZEN2) += -march=znver2
+ cflags-$(CONFIG_MZEN3) += -march=znver3
++ cflags-$(CONFIG_MZEN4) += -march=znver4
+ cflags-$(CONFIG_MNATIVE_INTEL) += -march=native
+ cflags-$(CONFIG_MNATIVE_AMD) += -march=native
+ cflags-$(CONFIG_MATOM) += -march=bonnell
@@ -580,17 +674,19 @@ index e84cdd409b64..7d3bbf060079 100644
+ cflags-$(CONFIG_MSAPPHIRERAPIDS) += -march=sapphirerapids
+ cflags-$(CONFIG_MROCKETLAKE) += -march=rocketlake
+ cflags-$(CONFIG_MALDERLAKE) += -march=alderlake
++ cflags-$(CONFIG_MRAPTORLAKE) += -march=raptorlake
++ cflags-$(CONFIG_MMETEORLAKE) += -march=meteorlake
+ cflags-$(CONFIG_GENERIC_CPU2) += -march=x86-64-v2
+ cflags-$(CONFIG_GENERIC_CPU3) += -march=x86-64-v3
+ cflags-$(CONFIG_GENERIC_CPU4) += -march=x86-64-v4
cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic
KBUILD_CFLAGS += $(cflags-y)
-
+
diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h
-index 75884d2cdec3..4e6a08d4c7e5 100644
+index 75884d2cdec3..18021e8c0c28 100644
--- a/arch/x86/include/asm/vermagic.h
+++ b/arch/x86/include/asm/vermagic.h
-@@ -17,6 +17,48 @@
+@@ -17,6 +17,52 @@
#define MODULE_PROC_FAMILY "586MMX "
#elif defined CONFIG_MCORE2
#define MODULE_PROC_FAMILY "CORE2 "
@@ -636,10 +732,14 @@ index 75884d2cdec3..4e6a08d4c7e5 100644
+#define MODULE_PROC_FAMILY "ROCKETLAKE "
+#elif defined CONFIG_MALDERLAKE
+#define MODULE_PROC_FAMILY "ALDERLAKE "
++#elif defined CONFIG_MRAPTORLAKE
++#define MODULE_PROC_FAMILY "RAPTORLAKE "
++#elif defined CONFIG_MMETEORLAKE
++#define MODULE_PROC_FAMILY "METEORLAKE "
#elif defined CONFIG_MATOM
#define MODULE_PROC_FAMILY "ATOM "
#elif defined CONFIG_M686
-@@ -35,6 +77,30 @@
+@@ -35,6 +81,32 @@
#define MODULE_PROC_FAMILY "K7 "
#elif defined CONFIG_MK8
#define MODULE_PROC_FAMILY "K8 "
@@ -667,9 +767,10 @@ index 75884d2cdec3..4e6a08d4c7e5 100644
+#define MODULE_PROC_FAMILY "ZEN2 "
+#elif defined CONFIG_MZEN3
+#define MODULE_PROC_FAMILY "ZEN3 "
++#elif defined CONFIG_MZEN4
++#define MODULE_PROC_FAMILY "ZEN4 "
#elif defined CONFIG_MELAN
#define MODULE_PROC_FAMILY "ELAN "
#elif defined CONFIG_MCRUSOE
---
-2.35.1
-
+--
+2.38.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-19 12:23 Alice Ferrazzi
0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-19 12:23 UTC (permalink / raw
To: gentoo-commits
commit: a8d06a5181b19f2342dcd759b90907c15ac15b3d
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 19 12:17:11 2022 +0000
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Mon Dec 19 12:18:23 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a8d06a51
Linux patch 6.0.14
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>
0000_README | 4 +
1013_linux-6.0.14.patch | 421 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 425 insertions(+)
diff --git a/0000_README b/0000_README
index 78a95ddc..578f9e3d 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch: 1012_linux-6.0.13.patch
From: http://www.kernel.org
Desc: Linux 6.0.13
+Patch: 1013_linux-6.0.14.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.14
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1013_linux-6.0.14.patch b/1013_linux-6.0.14.patch
new file mode 100644
index 00000000..89b4e23c
--- /dev/null
+++ b/1013_linux-6.0.14.patch
@@ -0,0 +1,421 @@
+diff --git a/Makefile b/Makefile
+index bf00f3240b3a3..a3c02b45fb575 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 13
++SUBLEVEL = 14
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S
+index 4bf48462fca7a..e8c60ae7a7c83 100644
+--- a/arch/x86/entry/vdso/vdso.lds.S
++++ b/arch/x86/entry/vdso/vdso.lds.S
+@@ -27,7 +27,9 @@ VERSION {
+ __vdso_time;
+ clock_getres;
+ __vdso_clock_getres;
++#ifdef CONFIG_X86_SGX
+ __vdso_sgx_enter_enclave;
++#endif
+ local: *;
+ };
+ }
+diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
+index 218b098b261df..47619e9cb0055 100644
+--- a/drivers/net/can/usb/mcba_usb.c
++++ b/drivers/net/can/usb/mcba_usb.c
+@@ -47,6 +47,10 @@
+ #define MCBA_VER_REQ_USB 1
+ #define MCBA_VER_REQ_CAN 2
+
++/* Drive the CAN_RES signal LOW "0" to activate R24 and R25 */
++#define MCBA_VER_TERMINATION_ON 0
++#define MCBA_VER_TERMINATION_OFF 1
++
+ #define MCBA_SIDL_EXID_MASK 0x8
+ #define MCBA_DLC_MASK 0xf
+ #define MCBA_DLC_RTR_MASK 0x40
+@@ -463,7 +467,7 @@ static void mcba_usb_process_ka_usb(struct mcba_priv *priv,
+ priv->usb_ka_first_pass = false;
+ }
+
+- if (msg->termination_state)
++ if (msg->termination_state == MCBA_VER_TERMINATION_ON)
+ priv->can.termination = MCBA_TERMINATION_ENABLED;
+ else
+ priv->can.termination = MCBA_TERMINATION_DISABLED;
+@@ -785,9 +789,9 @@ static int mcba_set_termination(struct net_device *netdev, u16 term)
+ };
+
+ if (term == MCBA_TERMINATION_ENABLED)
+- usb_msg.termination = 1;
++ usb_msg.termination = MCBA_VER_TERMINATION_ON;
+ else
+- usb_msg.termination = 0;
++ usb_msg.termination = MCBA_VER_TERMINATION_OFF;
+
+ mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg);
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 5aa254eaa8d02..5945632ded2d6 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -72,7 +72,7 @@
+ #include "fec.h"
+
+ static void set_multicast_list(struct net_device *ndev);
+-static void fec_enet_itr_coal_init(struct net_device *ndev);
++static void fec_enet_itr_coal_set(struct net_device *ndev);
+
+ #define DRIVER_NAME "fec"
+
+@@ -1164,8 +1164,8 @@ fec_restart(struct net_device *ndev)
+ writel(0, fep->hwp + FEC_IMASK);
+
+ /* Init the interrupt coalescing */
+- fec_enet_itr_coal_init(ndev);
+-
++ if (fep->quirks & FEC_QUIRK_HAS_COALESCE)
++ fec_enet_itr_coal_set(ndev);
+ }
+
+ static void fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
+@@ -2771,19 +2771,6 @@ static int fec_enet_set_coalesce(struct net_device *ndev,
+ return 0;
+ }
+
+-static void fec_enet_itr_coal_init(struct net_device *ndev)
+-{
+- struct ethtool_coalesce ec;
+-
+- ec.rx_coalesce_usecs = FEC_ITR_ICTT_DEFAULT;
+- ec.rx_max_coalesced_frames = FEC_ITR_ICFT_DEFAULT;
+-
+- ec.tx_coalesce_usecs = FEC_ITR_ICTT_DEFAULT;
+- ec.tx_max_coalesced_frames = FEC_ITR_ICFT_DEFAULT;
+-
+- fec_enet_set_coalesce(ndev, &ec, NULL, NULL);
+-}
+-
+ static int fec_enet_get_tunable(struct net_device *netdev,
+ const struct ethtool_tunable *tuna,
+ void *data)
+@@ -3538,6 +3525,10 @@ static int fec_enet_init(struct net_device *ndev)
+ fep->rx_align = 0x3;
+ fep->tx_align = 0x3;
+ #endif
++ fep->rx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
++ fep->tx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
++ fep->rx_time_itr = FEC_ITR_ICTT_DEFAULT;
++ fep->tx_time_itr = FEC_ITR_ICTT_DEFAULT;
+
+ /* Check mask of the streaming and coherent API */
+ ret = dma_set_mask_and_coherent(&fep->pdev->dev, DMA_BIT_MASK(32));
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 0f34114c4596d..6867620bcc986 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -804,6 +804,8 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev,
+ cmnd->dptr.prp1 = cpu_to_le64(iod->first_dma);
+ if (bv->bv_len > first_prp_len)
+ cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma + first_prp_len);
++ else
++ cmnd->dptr.prp2 = 0;
+ return BLK_STS_OK;
+ }
+
+diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
+index f7b54a5517641..c24583bffa99d 100644
+--- a/drivers/pinctrl/mediatek/mtk-eint.c
++++ b/drivers/pinctrl/mediatek/mtk-eint.c
+@@ -287,12 +287,15 @@ static struct irq_chip mtk_eint_irq_chip = {
+
+ static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
+ {
+- void __iomem *reg = eint->base + eint->regs->dom_en;
++ void __iomem *dom_en = eint->base + eint->regs->dom_en;
++ void __iomem *mask_set = eint->base + eint->regs->mask_set;
+ unsigned int i;
+
+ for (i = 0; i < eint->hw->ap_num; i += 32) {
+- writel(0xffffffff, reg);
+- reg += 4;
++ writel(0xffffffff, dom_en);
++ writel(0xffffffff, mask_set);
++ dom_en += 4;
++ mask_set += 4;
+ }
+
+ return 0;
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index bdb1df843c78d..58cc2bae2f8a0 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1233,6 +1233,9 @@ static u32 rtc_handler(void *context)
+
+ static inline void rtc_wake_setup(struct device *dev)
+ {
++ if (acpi_disabled)
++ return;
++
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+ /*
+ * After the RTC handler is installed, the Fixed_RTC event should
+@@ -1286,7 +1289,6 @@ static void cmos_wake_setup(struct device *dev)
+
+ use_acpi_alarm_quirks();
+
+- rtc_wake_setup(dev);
+ acpi_rtc_info.wake_on = rtc_wake_on;
+ acpi_rtc_info.wake_off = rtc_wake_off;
+
+@@ -1344,6 +1346,9 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ {
+ }
+
++static void rtc_wake_setup(struct device *dev)
++{
++}
+ #endif
+
+ #ifdef CONFIG_PNP
+@@ -1352,10 +1357,12 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
++ int irq, ret;
++
+ cmos_wake_setup(&pnp->dev);
+
+ if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+- unsigned int irq = 0;
++ irq = 0;
+ #ifdef CONFIG_X86
+ /* Some machines contain a PNP entry for the RTC, but
+ * don't define the IRQ. It should always be safe to
+@@ -1364,13 +1371,17 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ if (nr_legacy_irqs())
+ irq = RTC_IRQ;
+ #endif
+- return cmos_do_probe(&pnp->dev,
+- pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+ } else {
+- return cmos_do_probe(&pnp->dev,
+- pnp_get_resource(pnp, IORESOURCE_IO, 0),
+- pnp_irq(pnp, 0));
++ irq = pnp_irq(pnp, 0);
+ }
++
++ ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
++ if (ret)
++ return ret;
++
++ rtc_wake_setup(&pnp->dev);
++
++ return 0;
+ }
+
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1454,7 +1465,7 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+ struct resource *resource;
+- int irq;
++ int irq, ret;
+
+ cmos_of_init(pdev);
+ cmos_wake_setup(&pdev->dev);
+@@ -1467,7 +1478,13 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+ if (irq < 0)
+ irq = -1;
+
+- return cmos_do_probe(&pdev->dev, resource, irq);
++ ret = cmos_do_probe(&pdev->dev, resource, irq);
++ if (ret)
++ return ret;
++
++ rtc_wake_setup(&pdev->dev);
++
++ return 0;
+ }
+
+ static int cmos_platform_remove(struct platform_device *pdev)
+diff --git a/include/linux/can/platform/sja1000.h b/include/linux/can/platform/sja1000.h
+index 5755ae5a47122..6a869682c1207 100644
+--- a/include/linux/can/platform/sja1000.h
++++ b/include/linux/can/platform/sja1000.h
+@@ -14,7 +14,7 @@
+ #define OCR_MODE_TEST 0x01
+ #define OCR_MODE_NORMAL 0x02
+ #define OCR_MODE_CLOCK 0x03
+-#define OCR_MODE_MASK 0x07
++#define OCR_MODE_MASK 0x03
+ #define OCR_TX0_INVERT 0x04
+ #define OCR_TX0_PULLDOWN 0x08
+ #define OCR_TX0_PULLUP 0x10
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 8dcbefd90b7f6..91473e9f88cd9 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2283,6 +2283,7 @@ event_sched_out(struct perf_event *event,
+ !event->pending_work) {
+ event->pending_work = 1;
+ dec = false;
++ WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount));
+ task_work_add(current, &event->pending_task, TWA_RESUME);
+ }
+ if (dec)
+@@ -2328,6 +2329,7 @@ group_sched_out(struct perf_event *group_event,
+
+ #define DETACH_GROUP 0x01UL
+ #define DETACH_CHILD 0x02UL
++#define DETACH_DEAD 0x04UL
+
+ /*
+ * Cross CPU call to remove a performance event
+@@ -2348,12 +2350,20 @@ __perf_remove_from_context(struct perf_event *event,
+ update_cgrp_time_from_cpuctx(cpuctx, false);
+ }
+
++ /*
++ * Ensure event_sched_out() switches to OFF, at the very least
++ * this avoids raising perf_pending_task() at this time.
++ */
++ if (flags & DETACH_DEAD)
++ event->pending_disable = 1;
+ event_sched_out(event, cpuctx, ctx);
+ if (flags & DETACH_GROUP)
+ perf_group_detach(event);
+ if (flags & DETACH_CHILD)
+ perf_child_detach(event);
+ list_del_event(event, ctx);
++ if (flags & DETACH_DEAD)
++ event->state = PERF_EVENT_STATE_DEAD;
+
+ if (!ctx->nr_events && ctx->is_active) {
+ if (ctx == &cpuctx->ctx)
+@@ -5113,9 +5123,7 @@ int perf_event_release_kernel(struct perf_event *event)
+
+ ctx = perf_event_ctx_lock(event);
+ WARN_ON_ONCE(ctx->parent_ctx);
+- perf_remove_from_context(event, DETACH_GROUP);
+
+- raw_spin_lock_irq(&ctx->lock);
+ /*
+ * Mark this event as STATE_DEAD, there is no external reference to it
+ * anymore.
+@@ -5127,8 +5135,7 @@ int perf_event_release_kernel(struct perf_event *event)
+ * Thus this guarantees that we will in fact observe and kill _ALL_
+ * child events.
+ */
+- event->state = PERF_EVENT_STATE_DEAD;
+- raw_spin_unlock_irq(&ctx->lock);
++ perf_remove_from_context(event, DETACH_GROUP|DETACH_DEAD);
+
+ perf_event_ctx_unlock(event, ctx);
+
+@@ -6569,6 +6576,8 @@ static void perf_pending_task(struct callback_head *head)
+ if (rctx >= 0)
+ perf_swevent_put_recursion_context(rctx);
+ preempt_enable_notrace();
++
++ put_event(event);
+ }
+
+ #ifdef CONFIG_GUEST_PERF_EVENTS
+diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
+index 51721edd8f53c..e88d9ff95cdfc 100644
+--- a/sound/soc/codecs/cs42l51.c
++++ b/sound/soc/codecs/cs42l51.c
+@@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
+ 0, 0xA0, 96, adc_att_tlv),
+ SOC_DOUBLE_R_SX_TLV("PGA Volume",
+ CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL,
+- 0, 0x19, 30, pga_tlv),
++ 0, 0x1A, 30, pga_tlv),
+ SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
+ SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
+ SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 79ef4e269bc95..4b86ef82fd930 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -194,6 +194,25 @@ static int fsl_micfil_reset(struct device *dev)
+ if (ret)
+ return ret;
+
++ /*
++ * SRES is self-cleared bit, but REG_MICFIL_CTRL1 is defined
++ * as non-volatile register, so SRES still remain in regmap
++ * cache after set, that every update of REG_MICFIL_CTRL1,
++ * software reset happens. so clear it explicitly.
++ */
++ ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
++ MICFIL_CTRL1_SRES);
++ if (ret)
++ return ret;
++
++ /*
++ * Set SRES should clear CHnF flags, But even add delay here
++ * the CHnF may not be cleared sometimes, so clear CHnF explicitly.
++ */
++ ret = regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 0xFF, 0xFF);
++ if (ret)
++ return ret;
++
+ return 0;
+ }
+
+diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
+index 47691119306fb..55b009d3c6815 100644
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -464,10 +464,15 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+ ret = err;
+
+ if (snd_soc_volsw_is_stereo(mc)) {
+- unsigned int val2;
++ unsigned int val2 = ucontrol->value.integer.value[1];
++
++ if (mc->platform_max && val2 > mc->platform_max)
++ return -EINVAL;
++ if (val2 > max)
++ return -EINVAL;
+
+ val_mask = mask << rshift;
+- val2 = (ucontrol->value.integer.value[1] + min) & mask;
++ val2 = (val2 + min) & mask;
+ val2 = val2 << rshift;
+
+ err = snd_soc_component_update_bits(component, reg2, val_mask,
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 4221f73a74d01..3937f66c7f8d6 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -1963,7 +1963,7 @@ static int btf_dump_struct_data(struct btf_dump *d,
+ {
+ const struct btf_member *m = btf_members(t);
+ __u16 n = btf_vlen(t);
+- int i, err;
++ int i, err = 0;
+
+ /* note that we increment depth before calling btf_dump_print() below;
+ * this is intentional. btf_dump_data_newline() will not print a
+diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
+index 6d495656f554c..29f7cde107418 100644
+--- a/tools/lib/bpf/libbpf_probes.c
++++ b/tools/lib/bpf/libbpf_probes.c
+@@ -233,7 +233,7 @@ static int probe_map_create(enum bpf_map_type map_type)
+ case BPF_MAP_TYPE_RINGBUF:
+ key_size = 0;
+ value_size = 0;
+- max_entries = 4096;
++ max_entries = sysconf(_SC_PAGE_SIZE);
+ break;
+ case BPF_MAP_TYPE_STRUCT_OPS:
+ /* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-21 18:50 Alice Ferrazzi
0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-21 18:50 UTC (permalink / raw
To: gentoo-commits
commit: 0d6ea46e3e6783a7f13b4a75e254ae727414acbc
Author: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 21 18:45:57 2022 +0000
Commit: Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Dec 21 18:46:42 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=0d6ea46e
Linux patch 6.0.15
Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>
0000_README | 4 +
1014_linux-6.0.15.patch | 1127 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1131 insertions(+)
diff --git a/0000_README b/0000_README
index 578f9e3d..302d8339 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch: 1013_linux-6.0.14.patch
From: http://www.kernel.org
Desc: Linux 6.0.14
+Patch: 1014_linux-6.0.15.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.15
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1014_linux-6.0.15.patch b/1014_linux-6.0.15.patch
new file mode 100644
index 00000000..2173b214
--- /dev/null
+++ b/1014_linux-6.0.15.patch
@@ -0,0 +1,1127 @@
+diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
+index 0bfb4c3397489..9bc9db8ec6517 100644
+--- a/Documentation/security/keys/trusted-encrypted.rst
++++ b/Documentation/security/keys/trusted-encrypted.rst
+@@ -350,7 +350,8 @@ Load an encrypted key "evm" from saved blob::
+
+ Instantiate an encrypted key "evm" using user-provided decrypted data::
+
+- $ keyctl add encrypted evm "new default user:kmk 32 `cat evm_decrypted_data.blob`" @u
++ $ evmkey=$(dd if=/dev/urandom bs=1 count=32 | xxd -c32 -p)
++ $ keyctl add encrypted evm "new default user:kmk 32 $evmkey" @u
+ 794890253
+
+ $ keyctl print 794890253
+diff --git a/Makefile b/Makefile
+index a3c02b45fb575..0c7ae314ad3d5 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 2796e81d27260..ea46649b2ed3e 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -7522,7 +7522,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+ {
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+- u32 reg, msgbuf[3];
++ u32 reg, msgbuf[3] = {};
+ u8 *addr = (u8 *)(&msgbuf[1]);
+
+ /* process all the same items cleared in a function level reset */
+diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
+index 14e8d04cb4347..2e9742952c4e9 100644
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -211,7 +211,7 @@ static __net_init int loopback_net_init(struct net *net)
+ int err;
+
+ err = -ENOMEM;
+- dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
++ dev = alloc_netdev(0, "lo", NET_NAME_PREDICTABLE, loopback_setup);
+ if (!dev)
+ goto out;
+
+diff --git a/drivers/pci/controller/pcie-mt7621.c b/drivers/pci/controller/pcie-mt7621.c
+index 33eb37a2225c1..0f02f191946a0 100644
+--- a/drivers/pci/controller/pcie-mt7621.c
++++ b/drivers/pci/controller/pcie-mt7621.c
+@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(struct pci_host_bridge *host)
+ }
+
+ static const struct soc_device_attribute mt7621_pcie_quirks_match[] = {
+- { .soc_id = "mt7621", .revision = "E2" }
++ { .soc_id = "mt7621", .revision = "E2" },
++ { /* sentinel */ }
+ };
+
+ static int mt7621_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 4ee4ca09873af..9d3bbbb33dcf3 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -44,7 +44,7 @@
+ #define PCI_DEVICE_ID_INTEL_ADLP 0x51ee
+ #define PCI_DEVICE_ID_INTEL_ADLM 0x54ee
+ #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1
+-#define PCI_DEVICE_ID_INTEL_RPL 0x460e
++#define PCI_DEVICE_ID_INTEL_RPL 0xa70e
+ #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61
+ #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1
+ #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 7ec223849d949..4d3f62d754789 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -216,8 +216,9 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
+
+ memset(&v4l2_event, 0, sizeof(v4l2_event));
+ v4l2_event.type = UVC_EVENT_DATA;
+- uvc_event->data.length = req->actual;
+- memcpy(&uvc_event->data.data, req->buf, req->actual);
++ uvc_event->data.length = min_t(unsigned int, req->actual,
++ sizeof(uvc_event->data.data));
++ memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length);
+ v4l2_event_queue(&uvc->vdev, &v4l2_event);
+ }
+ }
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 0a8d37c5af030..7191cacba2274 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -59,6 +59,7 @@
+ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
+ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
+ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
++#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed
+
+ #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
+@@ -246,7 +247,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ xhci->quirks |= XHCI_MISSING_CAS;
+
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+- pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)
++ (pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI ||
++ pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI))
+ xhci->quirks |= XHCI_RESET_TO_DEFAULT;
+
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index a34957c4b64c0..0fd3a9d76beba 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -195,6 +195,8 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+ { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
+ { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
++ { USB_DEVICE(0x17A8, 0x0011) }, /* Kamstrup 444 MHz RF sniffer */
++ { USB_DEVICE(0x17A8, 0x0013) }, /* Kamstrup 870 MHz RF sniffer */
+ { USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */
+ { USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */
+ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
+diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
+index d9f20256a6a8e..b8cf21bec334e 100644
+--- a/drivers/usb/serial/f81232.c
++++ b/drivers/usb/serial/f81232.c
+@@ -130,9 +130,6 @@ static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
+
+ static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
+ {
+- if (!baudrate)
+- return 0;
+-
+ return DIV_ROUND_CLOSEST(clockrate, baudrate);
+ }
+
+@@ -498,9 +495,14 @@ static void f81232_set_baudrate(struct tty_struct *tty,
+ speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
+
+ for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
+- idx = f81232_find_clk(baud_list[i]);
++ baudrate = baud_list[i];
++ if (baudrate == 0) {
++ tty_encode_baud_rate(tty, 0, 0);
++ return;
++ }
++
++ idx = f81232_find_clk(baudrate);
+ if (idx >= 0) {
+- baudrate = baud_list[i];
+ tty_encode_baud_rate(tty, baudrate, baudrate);
+ break;
+ }
+diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
+index d789c1ec87b35..f331d39c3b267 100644
+--- a/drivers/usb/serial/f81534.c
++++ b/drivers/usb/serial/f81534.c
+@@ -536,9 +536,6 @@ static int f81534_submit_writer(struct usb_serial_port *port, gfp_t mem_flags)
+
+ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate)
+ {
+- if (!baudrate)
+- return 0;
+-
+ /* Round to nearest divisor */
+ return DIV_ROUND_CLOSEST(clockrate, baudrate);
+ }
+@@ -568,9 +565,14 @@ static int f81534_set_port_config(struct usb_serial_port *port,
+ u32 baud_list[] = {baudrate, old_baudrate, F81534_DEFAULT_BAUD_RATE};
+
+ for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
+- idx = f81534_find_clk(baud_list[i]);
++ baudrate = baud_list[i];
++ if (baudrate == 0) {
++ tty_encode_baud_rate(tty, 0, 0);
++ return 0;
++ }
++
++ idx = f81534_find_clk(baudrate);
+ if (idx >= 0) {
+- baudrate = baud_list[i];
+ tty_encode_baud_rate(tty, baudrate, baudrate);
+ break;
+ }
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c3b7f1d98e781..dee79c7d82d5c 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -255,6 +255,7 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_EP06 0x0306
+ #define QUECTEL_PRODUCT_EM05G 0x030a
+ #define QUECTEL_PRODUCT_EM060K 0x030b
++#define QUECTEL_PRODUCT_EM05G_SG 0x0311
+ #define QUECTEL_PRODUCT_EM12 0x0512
+ #define QUECTEL_PRODUCT_RM500Q 0x0800
+ #define QUECTEL_PRODUCT_RM520N 0x0801
+@@ -1160,6 +1161,8 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+ { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff),
+ .driver_info = RSVD(6) | ZLP },
++ { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff),
++ .driver_info = RSVD(6) | ZLP },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index a7987fc764cc6..eabe519013e78 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1270,8 +1270,9 @@ err:
+ return ret;
+ }
+
+-int ucsi_resume(struct ucsi *ucsi)
++static void ucsi_resume_work(struct work_struct *work)
+ {
++ struct ucsi *ucsi = container_of(work, struct ucsi, resume_work);
+ struct ucsi_connector *con;
+ u64 command;
+ int ret;
+@@ -1279,15 +1280,21 @@ int ucsi_resume(struct ucsi *ucsi)
+ /* Restore UCSI notification enable mask after system resume */
+ command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+ ret = ucsi_send_command(ucsi, command, NULL, 0);
+- if (ret < 0)
+- return ret;
++ if (ret < 0) {
++ dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret);
++ return;
++ }
+
+ for (con = ucsi->connector; con->port; con++) {
+ mutex_lock(&con->lock);
+- ucsi_check_connection(con);
++ ucsi_partner_task(con, ucsi_check_connection, 1, 0);
+ mutex_unlock(&con->lock);
+ }
++}
+
++int ucsi_resume(struct ucsi *ucsi)
++{
++ queue_work(system_long_wq, &ucsi->resume_work);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(ucsi_resume);
+@@ -1347,6 +1354,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
+ if (!ucsi)
+ return ERR_PTR(-ENOMEM);
+
++ INIT_WORK(&ucsi->resume_work, ucsi_resume_work);
+ INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work);
+ mutex_init(&ucsi->ppm_lock);
+ ucsi->dev = dev;
+@@ -1401,6 +1409,7 @@ void ucsi_unregister(struct ucsi *ucsi)
+
+ /* Make sure that we are not in the middle of driver initialization */
+ cancel_delayed_work_sync(&ucsi->work);
++ cancel_work_sync(&ucsi->resume_work);
+
+ /* Disable notifications */
+ ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index 8eb391e3e592c..c968474ee5473 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -287,6 +287,7 @@ struct ucsi {
+ struct ucsi_capability cap;
+ struct ucsi_connector *connector;
+
++ struct work_struct resume_work;
+ struct delayed_work work;
+ int work_count;
+ #define UCSI_ROLE_SWITCH_RETRY_PER_HZ 10
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index 8d06daed549f9..b9a83820e1adf 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -439,6 +439,12 @@ static int udf_get_block(struct inode *inode, sector_t block,
+ iinfo->i_next_alloc_goal++;
+ }
+
++ /*
++ * Block beyond EOF and prealloc extents? Just discard preallocation
++ * as it is not useful and complicates things.
++ */
++ if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents)
++ udf_discard_prealloc(inode);
+ udf_clear_extent_cache(inode);
+ phys = inode_getblk(inode, block, &err, &new);
+ if (!phys)
+@@ -488,8 +494,6 @@ static int udf_do_extend_file(struct inode *inode,
+ uint32_t add;
+ int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ struct super_block *sb = inode->i_sb;
+- struct kernel_lb_addr prealloc_loc = {};
+- uint32_t prealloc_len = 0;
+ struct udf_inode_info *iinfo;
+ int err;
+
+@@ -510,19 +514,6 @@ static int udf_do_extend_file(struct inode *inode,
+ ~(sb->s_blocksize - 1);
+ }
+
+- /* Last extent are just preallocated blocks? */
+- if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
+- EXT_NOT_RECORDED_ALLOCATED) {
+- /* Save the extent so that we can reattach it to the end */
+- prealloc_loc = last_ext->extLocation;
+- prealloc_len = last_ext->extLength;
+- /* Mark the extent as a hole */
+- last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+- (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+- last_ext->extLocation.logicalBlockNum = 0;
+- last_ext->extLocation.partitionReferenceNum = 0;
+- }
+-
+ /* Can we merge with the previous extent? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
+ EXT_NOT_RECORDED_NOT_ALLOCATED) {
+@@ -550,7 +541,7 @@ static int udf_do_extend_file(struct inode *inode,
+ * more extents, we may need to enter possible following
+ * empty indirect extent.
+ */
+- if (new_block_bytes || prealloc_len)
++ if (new_block_bytes)
+ udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
+ }
+
+@@ -584,17 +575,6 @@ static int udf_do_extend_file(struct inode *inode,
+ }
+
+ out:
+- /* Do we have some preallocated blocks saved? */
+- if (prealloc_len) {
+- err = udf_add_aext(inode, last_pos, &prealloc_loc,
+- prealloc_len, 1);
+- if (err)
+- return err;
+- last_ext->extLocation = prealloc_loc;
+- last_ext->extLength = prealloc_len;
+- count++;
+- }
+-
+ /* last_pos should point to the last written extent... */
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+ last_pos->offset -= sizeof(struct short_ad);
+@@ -610,13 +590,17 @@ out:
+ static void udf_do_extend_final_block(struct inode *inode,
+ struct extent_position *last_pos,
+ struct kernel_long_ad *last_ext,
+- uint32_t final_block_len)
++ uint32_t new_elen)
+ {
+- struct super_block *sb = inode->i_sb;
+ uint32_t added_bytes;
+
+- added_bytes = final_block_len -
+- (last_ext->extLength & (sb->s_blocksize - 1));
++ /*
++ * Extent already large enough? It may be already rounded up to block
++ * size...
++ */
++ if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
++ return;
++ added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
+ last_ext->extLength += added_bytes;
+ UDF_I(inode)->i_lenExtents += added_bytes;
+
+@@ -633,12 +617,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ int8_t etype;
+ struct super_block *sb = inode->i_sb;
+ sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
+- unsigned long partial_final_block;
++ loff_t new_elen;
+ int adsize;
+ struct udf_inode_info *iinfo = UDF_I(inode);
+ struct kernel_long_ad extent;
+ int err = 0;
+- int within_final_block;
++ bool within_last_ext;
+
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+ adsize = sizeof(struct short_ad);
+@@ -647,8 +631,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ else
+ BUG();
+
++ /*
++ * When creating hole in file, just don't bother with preserving
++ * preallocation. It likely won't be very useful anyway.
++ */
++ udf_discard_prealloc(inode);
++
+ etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+- within_final_block = (etype != -1);
++ within_last_ext = (etype != -1);
++ /* We don't expect extents past EOF... */
++ WARN_ON_ONCE(within_last_ext &&
++ elen > ((loff_t)offset + 1) << inode->i_blkbits);
+
+ if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
+ (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
+@@ -664,19 +657,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ extent.extLength |= etype << 30;
+ }
+
+- partial_final_block = newsize & (sb->s_blocksize - 1);
++ new_elen = ((loff_t)offset << inode->i_blkbits) |
++ (newsize & (sb->s_blocksize - 1));
+
+ /* File has extent covering the new size (could happen when extending
+ * inside a block)?
+ */
+- if (within_final_block) {
++ if (within_last_ext) {
+ /* Extending file within the last file block */
+- udf_do_extend_final_block(inode, &epos, &extent,
+- partial_final_block);
++ udf_do_extend_final_block(inode, &epos, &extent, new_elen);
+ } else {
+- loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
+- partial_final_block;
+- err = udf_do_extend_file(inode, &epos, &extent, add);
++ err = udf_do_extend_file(inode, &epos, &extent, new_elen);
+ }
+
+ if (err < 0)
+@@ -777,10 +768,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
+ goto out_free;
+ }
+
+- /* Are we beyond EOF? */
++ /* Are we beyond EOF and preallocated extent? */
+ if (etype == -1) {
+ int ret;
+ loff_t hole_len;
++
+ isBeyondEOF = true;
+ if (count) {
+ if (c)
+diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
+index 532cda99644ee..036ebd892b852 100644
+--- a/fs/udf/truncate.c
++++ b/fs/udf/truncate.c
+@@ -120,60 +120,42 @@ void udf_truncate_tail_extent(struct inode *inode)
+
+ void udf_discard_prealloc(struct inode *inode)
+ {
+- struct extent_position epos = { NULL, 0, {0, 0} };
++ struct extent_position epos = {};
++ struct extent_position prev_epos = {};
+ struct kernel_lb_addr eloc;
+ uint32_t elen;
+ uint64_t lbcount = 0;
+ int8_t etype = -1, netype;
+- int adsize;
+ struct udf_inode_info *iinfo = UDF_I(inode);
++ int bsize = 1 << inode->i_blkbits;
+
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
+- inode->i_size == iinfo->i_lenExtents)
++ ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize))
+ return;
+
+- if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+- adsize = sizeof(struct short_ad);
+- else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
+- adsize = sizeof(struct long_ad);
+- else
+- adsize = 0;
+-
+ epos.block = iinfo->i_location;
+
+ /* Find the last extent in the file */
+- while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
+- etype = netype;
++ while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 0)) != -1) {
++ brelse(prev_epos.bh);
++ prev_epos = epos;
++ if (prev_epos.bh)
++ get_bh(prev_epos.bh);
++
++ etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
+ lbcount += elen;
+ }
+ if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+- epos.offset -= adsize;
+ lbcount -= elen;
+- extent_trunc(inode, &epos, &eloc, etype, elen, 0);
+- if (!epos.bh) {
+- iinfo->i_lenAlloc =
+- epos.offset -
+- udf_file_entry_alloc_offset(inode);
+- mark_inode_dirty(inode);
+- } else {
+- struct allocExtDesc *aed =
+- (struct allocExtDesc *)(epos.bh->b_data);
+- aed->lengthAllocDescs =
+- cpu_to_le32(epos.offset -
+- sizeof(struct allocExtDesc));
+- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+- UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
+- udf_update_tag(epos.bh->b_data, epos.offset);
+- else
+- udf_update_tag(epos.bh->b_data,
+- sizeof(struct allocExtDesc));
+- mark_buffer_dirty_inode(epos.bh, inode);
+- }
++ udf_delete_aext(inode, prev_epos);
++ udf_free_blocks(inode->i_sb, inode, &eloc, 0,
++ DIV_ROUND_UP(elen, 1 << inode->i_blkbits));
+ }
+ /* This inode entry is in-memory only and thus we don't have to mark
+ * the inode dirty */
+ iinfo->i_lenExtents = lbcount;
+ brelse(epos.bh);
++ brelse(prev_epos.bh);
+ }
+
+ static void udf_update_alloc_ext_desc(struct inode *inode,
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 518296ea7f73a..e72db35fbf759 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -879,8 +879,17 @@ static inline bool module_sig_ok(struct module *module)
+ }
+ #endif /* CONFIG_MODULE_SIG */
+
++#if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS)
+ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *, unsigned long),
+ void *data);
++#else
++static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
++ struct module *, unsigned long),
++ void *data)
++{
++ return -EOPNOTSUPP;
++}
++#endif /* CONFIG_MODULES && CONFIG_KALLSYMS */
+
+ #endif /* _LINUX_MODULE_H */
+diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
+index f5c5c9175333d..4523f99b03589 100644
+--- a/kernel/module/kallsyms.c
++++ b/kernel/module/kallsyms.c
+@@ -494,7 +494,6 @@ unsigned long module_kallsyms_lookup_name(const char *name)
+ return ret;
+ }
+
+-#ifdef CONFIG_LIVEPATCH
+ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *, unsigned long),
+ void *data)
+@@ -531,4 +530,3 @@ out:
+ mutex_unlock(&module_mutex);
+ return ret;
+ }
+-#endif /* CONFIG_LIVEPATCH */
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index ec4b81007796c..da8e7b6951793 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2264,6 +2264,8 @@ struct bpf_kprobe_multi_link {
+ unsigned long *addrs;
+ u64 *cookies;
+ u32 cnt;
++ u32 mods_cnt;
++ struct module **mods;
+ };
+
+ struct bpf_kprobe_multi_run_ctx {
+@@ -2319,6 +2321,14 @@ error:
+ return err;
+ }
+
++static void kprobe_multi_put_modules(struct module **mods, u32 cnt)
++{
++ u32 i;
++
++ for (i = 0; i < cnt; i++)
++ module_put(mods[i]);
++}
++
+ static void free_user_syms(struct user_syms *us)
+ {
+ kvfree(us->syms);
+@@ -2331,6 +2341,7 @@ static void bpf_kprobe_multi_link_release(struct bpf_link *link)
+
+ kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
+ unregister_fprobe(&kmulti_link->fp);
++ kprobe_multi_put_modules(kmulti_link->mods, kmulti_link->mods_cnt);
+ }
+
+ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
+@@ -2340,6 +2351,7 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
+ kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
+ kvfree(kmulti_link->addrs);
+ kvfree(kmulti_link->cookies);
++ kfree(kmulti_link->mods);
+ kfree(kmulti_link);
+ }
+
+@@ -2362,7 +2374,7 @@ static void bpf_kprobe_multi_cookie_swap(void *a, void *b, int size, const void
+ swap(*cookie_a, *cookie_b);
+ }
+
+-static int __bpf_kprobe_multi_cookie_cmp(const void *a, const void *b)
++static int bpf_kprobe_multi_addrs_cmp(const void *a, const void *b)
+ {
+ const unsigned long *addr_a = a, *addr_b = b;
+
+@@ -2373,7 +2385,7 @@ static int __bpf_kprobe_multi_cookie_cmp(const void *a, const void *b)
+
+ static int bpf_kprobe_multi_cookie_cmp(const void *a, const void *b, const void *priv)
+ {
+- return __bpf_kprobe_multi_cookie_cmp(a, b);
++ return bpf_kprobe_multi_addrs_cmp(a, b);
+ }
+
+ static u64 bpf_kprobe_multi_cookie(struct bpf_run_ctx *ctx)
+@@ -2391,7 +2403,7 @@ static u64 bpf_kprobe_multi_cookie(struct bpf_run_ctx *ctx)
+ return 0;
+ entry_ip = run_ctx->entry_ip;
+ addr = bsearch(&entry_ip, link->addrs, link->cnt, sizeof(entry_ip),
+- __bpf_kprobe_multi_cookie_cmp);
++ bpf_kprobe_multi_addrs_cmp);
+ if (!addr)
+ return 0;
+ cookie = link->cookies + (addr - link->addrs);
+@@ -2475,6 +2487,71 @@ static void symbols_swap_r(void *a, void *b, int size, const void *priv)
+ }
+ }
+
++struct module_addr_args {
++ unsigned long *addrs;
++ u32 addrs_cnt;
++ struct module **mods;
++ int mods_cnt;
++ int mods_cap;
++};
++
++static int module_callback(void *data, const char *name,
++ struct module *mod, unsigned long addr)
++{
++ struct module_addr_args *args = data;
++ struct module **mods;
++
++ /* We iterate all modules symbols and for each we:
++ * - search for it in provided addresses array
++ * - if found we check if we already have the module pointer stored
++ * (we iterate modules sequentially, so we can check just the last
++ * module pointer)
++ * - take module reference and store it
++ */
++ if (!bsearch(&addr, args->addrs, args->addrs_cnt, sizeof(addr),
++ bpf_kprobe_multi_addrs_cmp))
++ return 0;
++
++ if (args->mods && args->mods[args->mods_cnt - 1] == mod)
++ return 0;
++
++ if (args->mods_cnt == args->mods_cap) {
++ args->mods_cap = max(16, args->mods_cap * 3 / 2);
++ mods = krealloc_array(args->mods, args->mods_cap, sizeof(*mods), GFP_KERNEL);
++ if (!mods)
++ return -ENOMEM;
++ args->mods = mods;
++ }
++
++ if (!try_module_get(mod))
++ return -EINVAL;
++
++ args->mods[args->mods_cnt] = mod;
++ args->mods_cnt++;
++ return 0;
++}
++
++static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u32 addrs_cnt)
++{
++ struct module_addr_args args = {
++ .addrs = addrs,
++ .addrs_cnt = addrs_cnt,
++ };
++ int err;
++
++ /* We return either err < 0 in case of error, ... */
++ err = module_kallsyms_on_each_symbol(module_callback, &args);
++ if (err) {
++ kprobe_multi_put_modules(args.mods, args.mods_cnt);
++ kfree(args.mods);
++ return err;
++ }
++
++ /* or number of modules found if everything is ok. */
++ *mods = args.mods;
++ return args.mods_cnt;
++}
++
+ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
+ {
+ struct bpf_kprobe_multi_link *link = NULL;
+@@ -2585,10 +2662,25 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
+ bpf_kprobe_multi_cookie_cmp,
+ bpf_kprobe_multi_cookie_swap,
+ link);
++ } else {
++ /*
++ * We need to sort addrs array even if there are no cookies
++ * provided, to allow bsearch in get_modules_for_addrs.
++ */
++ sort(addrs, cnt, sizeof(*addrs),
++ bpf_kprobe_multi_addrs_cmp, NULL);
++ }
++
++ err = get_modules_for_addrs(&link->mods, addrs, cnt);
++ if (err < 0) {
++ bpf_link_cleanup(&link_primer);
++ return err;
+ }
++ link->mods_cnt = err;
+
+ err = register_fprobe_ips(&link->fp, addrs, cnt);
+ if (err) {
++ kprobe_multi_put_modules(link->mods, link->mods_cnt);
+ bpf_link_cleanup(&link_primer);
+ return err;
+ }
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 9e6231f4a04f7..768306ec3c941 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -8261,6 +8261,10 @@ struct kallsyms_data {
+ size_t found;
+ };
+
++/* This function gets called for all kernel and module symbols
++ * and returns 1 in case we resolved all the requested symbols,
++ * 0 otherwise.
++ */
+ static int kallsyms_callback(void *data, const char *name,
+ struct module *mod, unsigned long addr)
+ {
+@@ -8304,17 +8308,19 @@ static int kallsyms_callback(void *data, const char *name,
+ int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
+ {
+ struct kallsyms_data args;
+- int err;
++ int found_all;
+
+ memset(addrs, 0, sizeof(*addrs) * cnt);
+ args.addrs = addrs;
+ args.syms = sorted_syms;
+ args.cnt = cnt;
+ args.found = 0;
+- err = kallsyms_on_each_symbol(kallsyms_callback, &args);
+- if (err < 0)
+- return err;
+- return args.found == args.cnt ? 0 : -ESRCH;
++
++ found_all = kallsyms_on_each_symbol(kallsyms_callback, &args);
++ if (found_all)
++ return 0;
++ found_all = module_kallsyms_on_each_symbol(kallsyms_callback, &args);
++ return found_all ? 0 : -ESRCH;
+ }
+
+ #ifdef CONFIG_SYSCTL
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 9c24947aa41ef..9fdede5fe71c7 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4453,7 +4453,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
+
+ chan->ident = cmd->ident;
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
+- chan->num_conf_rsp++;
++ if (chan->num_conf_rsp < L2CAP_CONF_MAX_CONF_RSP)
++ chan->num_conf_rsp++;
+
+ /* Reset config buffer. */
+ chan->conf_len = 0;
+diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
+index e05cfc2e49aeb..1e313982af02a 100644
+--- a/security/keys/encrypted-keys/encrypted.c
++++ b/security/keys/encrypted-keys/encrypted.c
+@@ -627,7 +627,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
+ pr_err("encrypted key: instantiation of keys using provided decrypted data is disabled since CONFIG_USER_DECRYPTED_DATA is set to false\n");
+ return ERR_PTR(-EINVAL);
+ }
+- if (strlen(decrypted_data) != decrypted_datalen) {
++ if (strlen(decrypted_data) != decrypted_datalen * 2) {
+ pr_err("encrypted key: decrypted data provided does not match decrypted data length provided\n");
+ return ERR_PTR(-EINVAL);
+ }
+@@ -791,8 +791,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
+ ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
+ } else if (decrypted_data) {
+ get_random_bytes(epayload->iv, ivsize);
+- memcpy(epayload->decrypted_data, decrypted_data,
+- epayload->decrypted_datalen);
++ ret = hex2bin(epayload->decrypted_data, decrypted_data,
++ epayload->decrypted_datalen);
+ } else {
+ get_random_bytes(epayload->iv, ivsize);
+ get_random_bytes(epayload->decrypted_data, epayload->decrypted_datalen);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d8c6af9e43ad6..ce6ea8819562b 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9376,6 +9376,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++ SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
+ SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+index 792cb15bac40f..ac5d7c1396fb4 100644
+--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
++++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+@@ -88,6 +88,23 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
+ }
+ }
+
++noinline int bpf_testmod_fentry_test1(int a)
++{
++ return a + 1;
++}
++
++noinline int bpf_testmod_fentry_test2(int a, u64 b)
++{
++ return a + b;
++}
++
++noinline int bpf_testmod_fentry_test3(char a, int b, u64 c)
++{
++ return a + b + c;
++}
++
++int bpf_testmod_fentry_ok;
++
+ noinline ssize_t
+ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+@@ -119,6 +136,13 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ return snprintf(buf, len, "%d\n", writable.val);
+ }
+
++ if (bpf_testmod_fentry_test1(1) != 2 ||
++ bpf_testmod_fentry_test2(2, 3) != 5 ||
++ bpf_testmod_fentry_test3(4, 5, 6) != 15)
++ goto out;
++
++ bpf_testmod_fentry_ok = 1;
++out:
+ return -EIO; /* always fail */
+ }
+ EXPORT_SYMBOL(bpf_testmod_test_read);
+diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c
+new file mode 100644
+index 0000000000000..1fbe7e4ac00ab
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c
+@@ -0,0 +1,89 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <test_progs.h>
++#include "kprobe_multi.skel.h"
++#include "trace_helpers.h"
++#include "bpf/libbpf_internal.h"
++
++static void kprobe_multi_testmod_check(struct kprobe_multi *skel)
++{
++ ASSERT_EQ(skel->bss->kprobe_testmod_test1_result, 1, "kprobe_test1_result");
++ ASSERT_EQ(skel->bss->kprobe_testmod_test2_result, 1, "kprobe_test2_result");
++ ASSERT_EQ(skel->bss->kprobe_testmod_test3_result, 1, "kprobe_test3_result");
++
++ ASSERT_EQ(skel->bss->kretprobe_testmod_test1_result, 1, "kretprobe_test1_result");
++ ASSERT_EQ(skel->bss->kretprobe_testmod_test2_result, 1, "kretprobe_test2_result");
++ ASSERT_EQ(skel->bss->kretprobe_testmod_test3_result, 1, "kretprobe_test3_result");
++}
++
++static void test_testmod_attach_api(struct bpf_kprobe_multi_opts *opts)
++{
++ struct kprobe_multi *skel = NULL;
++
++ skel = kprobe_multi__open_and_load();
++ if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
++ return;
++
++ skel->bss->pid = getpid();
++
++ skel->links.test_kprobe_testmod = bpf_program__attach_kprobe_multi_opts(
++ skel->progs.test_kprobe_testmod,
++ NULL, opts);
++ if (!skel->links.test_kprobe_testmod)
++ goto cleanup;
++
++ opts->retprobe = true;
++ skel->links.test_kretprobe_testmod = bpf_program__attach_kprobe_multi_opts(
++ skel->progs.test_kretprobe_testmod,
++ NULL, opts);
++ if (!skel->links.test_kretprobe_testmod)
++ goto cleanup;
++
++ ASSERT_OK(trigger_module_test_read(1), "trigger_read");
++ kprobe_multi_testmod_check(skel);
++
++cleanup:
++ kprobe_multi__destroy(skel);
++}
++
++static void test_testmod_attach_api_addrs(void)
++{
++ LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
++ unsigned long long addrs[3];
++
++ addrs[0] = ksym_get_addr("bpf_testmod_fentry_test1");
++ ASSERT_NEQ(addrs[0], 0, "ksym_get_addr");
++ addrs[1] = ksym_get_addr("bpf_testmod_fentry_test2");
++ ASSERT_NEQ(addrs[1], 0, "ksym_get_addr");
++ addrs[2] = ksym_get_addr("bpf_testmod_fentry_test3");
++ ASSERT_NEQ(addrs[2], 0, "ksym_get_addr");
++
++ opts.addrs = (const unsigned long *) addrs;
++ opts.cnt = ARRAY_SIZE(addrs);
++
++ test_testmod_attach_api(&opts);
++}
++
++static void test_testmod_attach_api_syms(void)
++{
++ LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
++ const char *syms[3] = {
++ "bpf_testmod_fentry_test1",
++ "bpf_testmod_fentry_test2",
++ "bpf_testmod_fentry_test3",
++ };
++
++ opts.syms = syms;
++ opts.cnt = ARRAY_SIZE(syms);
++ test_testmod_attach_api(&opts);
++}
++
++void serial_test_kprobe_multi_testmod_test(void)
++{
++ if (!ASSERT_OK(load_kallsyms_refresh(), "load_kallsyms_refresh"))
++ return;
++
++ if (test__start_subtest("testmod_attach_api_syms"))
++ test_testmod_attach_api_syms();
++ if (test__start_subtest("testmod_attach_api_addrs"))
++ test_testmod_attach_api_addrs();
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/module_attach.c b/tools/testing/selftests/bpf/prog_tests/module_attach.c
+index 6d0e50dcf47cc..7fc01ff490db7 100644
+--- a/tools/testing/selftests/bpf/prog_tests/module_attach.c
++++ b/tools/testing/selftests/bpf/prog_tests/module_attach.c
+@@ -103,6 +103,13 @@ void test_module_attach(void)
+ ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
+ bpf_link__destroy(link);
+
++ link = bpf_program__attach(skel->progs.kprobe_multi);
++ if (!ASSERT_OK_PTR(link, "attach_kprobe_multi"))
++ goto cleanup;
++
++ ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
++ bpf_link__destroy(link);
++
+ cleanup:
+ test_module_attach__destroy(skel);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+index 98c3399e15c03..9e1ca8e34913c 100644
+--- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
++++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+@@ -110,3 +110,53 @@ int test_kretprobe_manual(struct pt_regs *ctx)
+ kprobe_multi_check(ctx, true);
+ return 0;
+ }
++
++extern const void bpf_testmod_fentry_test1 __ksym;
++extern const void bpf_testmod_fentry_test2 __ksym;
++extern const void bpf_testmod_fentry_test3 __ksym;
++
++__u64 kprobe_testmod_test1_result = 0;
++__u64 kprobe_testmod_test2_result = 0;
++__u64 kprobe_testmod_test3_result = 0;
++
++__u64 kretprobe_testmod_test1_result = 0;
++__u64 kretprobe_testmod_test2_result = 0;
++__u64 kretprobe_testmod_test3_result = 0;
++
++static void kprobe_multi_testmod_check(void *ctx, bool is_return)
++{
++ if (bpf_get_current_pid_tgid() >> 32 != pid)
++ return;
++
++ __u64 addr = bpf_get_func_ip(ctx);
++
++ if (is_return) {
++ if ((const void *) addr == &bpf_testmod_fentry_test1)
++ kretprobe_testmod_test1_result = 1;
++ if ((const void *) addr == &bpf_testmod_fentry_test2)
++ kretprobe_testmod_test2_result = 1;
++ if ((const void *) addr == &bpf_testmod_fentry_test3)
++ kretprobe_testmod_test3_result = 1;
++ } else {
++ if ((const void *) addr == &bpf_testmod_fentry_test1)
++ kprobe_testmod_test1_result = 1;
++ if ((const void *) addr == &bpf_testmod_fentry_test2)
++ kprobe_testmod_test2_result = 1;
++ if ((const void *) addr == &bpf_testmod_fentry_test3)
++ kprobe_testmod_test3_result = 1;
++ }
++}
++
++SEC("kprobe.multi")
++int test_kprobe_testmod(struct pt_regs *ctx)
++{
++ kprobe_multi_testmod_check(ctx, false);
++ return 0;
++}
++
++SEC("kretprobe.multi")
++int test_kretprobe_testmod(struct pt_regs *ctx)
++{
++ kprobe_multi_testmod_check(ctx, true);
++ return 0;
++}
+diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
+index 08628afedb779..8a1b50f3a002d 100644
+--- a/tools/testing/selftests/bpf/progs/test_module_attach.c
++++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
+@@ -110,4 +110,10 @@ int BPF_PROG(handle_fmod_ret,
+ return 0; /* don't override the exit code */
+ }
+
++SEC("kprobe.multi/bpf_testmod_test_read")
++int BPF_PROG(kprobe_multi)
++{
++ return 0;
++}
++
+ char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
+index 9c4be2cdb21a0..09a16a77bae4b 100644
+--- a/tools/testing/selftests/bpf/trace_helpers.c
++++ b/tools/testing/selftests/bpf/trace_helpers.c
+@@ -23,7 +23,7 @@ static int ksym_cmp(const void *p1, const void *p2)
+ return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
+ }
+
+-int load_kallsyms(void)
++int load_kallsyms_refresh(void)
+ {
+ FILE *f;
+ char func[256], buf[256];
+@@ -31,12 +31,7 @@ int load_kallsyms(void)
+ void *addr;
+ int i = 0;
+
+- /*
+- * This is called/used from multiplace places,
+- * load symbols just once.
+- */
+- if (sym_cnt)
+- return 0;
++ sym_cnt = 0;
+
+ f = fopen("/proc/kallsyms", "r");
+ if (!f)
+@@ -57,6 +52,17 @@ int load_kallsyms(void)
+ return 0;
+ }
+
++int load_kallsyms(void)
++{
++ /*
++ * This is called/used from multiplace places,
++ * load symbols just once.
++ */
++ if (sym_cnt)
++ return 0;
++ return load_kallsyms_refresh();
++}
++
+ struct ksym *ksym_search(long key)
+ {
+ int start = 0, end = sym_cnt;
+diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
+index 238a9c98cde27..53efde0e2998e 100644
+--- a/tools/testing/selftests/bpf/trace_helpers.h
++++ b/tools/testing/selftests/bpf/trace_helpers.h
+@@ -10,6 +10,8 @@ struct ksym {
+ };
+
+ int load_kallsyms(void);
++int load_kallsyms_refresh(void);
++
+ struct ksym *ksym_search(long key);
+ long ksym_get_addr(const char *name);
+
+diff --git a/tools/testing/selftests/net/toeplitz.sh b/tools/testing/selftests/net/toeplitz.sh
+index 0a49907cd4fef..da5bfd834effe 100755
+--- a/tools/testing/selftests/net/toeplitz.sh
++++ b/tools/testing/selftests/net/toeplitz.sh
+@@ -32,7 +32,7 @@ DEV="eth0"
+ # This is determined by reading the RSS indirection table using ethtool.
+ get_rss_cfg_num_rxqs() {
+ echo $(ethtool -x "${DEV}" |
+- egrep [[:space:]]+[0-9]+:[[:space:]]+ |
++ grep -E [[:space:]]+[0-9]+:[[:space:]]+ |
+ cut -d: -f2- |
+ awk '{$1=$1};1' |
+ tr ' ' '\n' |
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-31 15:29 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-31 15:29 UTC (permalink / raw
To: gentoo-commits
commit: 47bebee42dd8af1585608157960c0bcf25816035
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 31 15:29:16 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Dec 31 15:29:16 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47bebee4
Linux patch 6.0.16
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1015_linux-6.0.16.patch | 45617 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45621 insertions(+)
diff --git a/0000_README b/0000_README
index 302d8339..44fc4c7e 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch: 1014_linux-6.0.15.patch
From: http://www.kernel.org
Desc: Linux 6.0.15
+Patch: 1015_linux-6.0.16.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.16
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1015_linux-6.0.16.patch b/1015_linux-6.0.16.patch
new file mode 100644
index 00000000..e72ee462
--- /dev/null
+++ b/1015_linux-6.0.16.patch
@@ -0,0 +1,45617 @@
+diff --git a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
+index d76cd3946434d..e9ef69aef20b1 100644
+--- a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
++++ b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
+@@ -5,6 +5,9 @@ Contact: linux-mtd@lists.infradead.org
+ Description: (RO) The JEDEC ID of the SPI NOR flash as reported by the
+ flash device.
+
++ The attribute is not present if the flash doesn't support
++ the "Read JEDEC ID" command (9Fh). This is the case for
++ non-JEDEC compliant flashes.
+
+ What: /sys/bus/spi/devices/.../spi-nor/manufacturer
+ Date: April 2021
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index ee6572b1edada..66d1b23ca64fe 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -1298,6 +1298,29 @@ watchdog work to be queued by the watchdog timer function, otherwise the NMI
+ watchdog — if enabled — can detect a hard lockup condition.
+
+
++split_lock_mitigate (x86 only)
++==============================
++
++On x86, each "split lock" imposes a system-wide performance penalty. On larger
++systems, large numbers of split locks from unprivileged users can result in
++denials of service to well-behaved and potentially more important users.
++
++The kernel mitigates these bad users by detecting split locks and imposing
++penalties: forcing them to wait and only allowing one core to execute split
++locks at a time.
++
++These mitigations can make those bad applications unbearably slow. Setting
++split_lock_mitigate=0 may restore some application performance, but will also
++increase system exposure to denial of service attacks from split lock users.
++
++= ===================================================================
++0 Disable the mitigation mode - just warns the split lock on kernel log
++ and exposes the system to denials of service from the split lockers.
++1 Enable the mitigation mode (this is the default) - penalizes the split
++ lockers with intentional performance degradation.
++= ===================================================================
++
++
+ stack_erasing
+ =============
+
+diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
+index bad9135489de5..1d20cdcc69ff8 100644
+--- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
++++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
+@@ -22,6 +22,8 @@ properties:
+
+ clock-names: true
+
++ reg: true
++
+ compatible:
+ enum:
+ - qcom,sc7280-lpassaoncc
+@@ -38,8 +40,8 @@ properties:
+ '#power-domain-cells':
+ const: 1
+
+- reg:
+- maxItems: 1
++ '#reset-cells':
++ const: 1
+
+ required:
+ - compatible
+@@ -69,6 +71,11 @@ allOf:
+ items:
+ - const: bi_tcxo
+ - const: lpass_aon_cc_main_rcg_clk_src
++
++ reg:
++ items:
++ - description: lpass core cc register
++ - description: lpass audio csr register
+ - if:
+ properties:
+ compatible:
+@@ -90,6 +97,8 @@ allOf:
+ - const: bi_tcxo_ao
+ - const: iface
+
++ reg:
++ maxItems: 1
+ - if:
+ properties:
+ compatible:
+@@ -108,6 +117,8 @@ allOf:
+ items:
+ - const: bi_tcxo
+
++ reg:
++ maxItems: 1
+ examples:
+ - |
+ #include <dt-bindings/clock/qcom,rpmh.h>
+@@ -116,13 +127,15 @@ examples:
+ #include <dt-bindings/clock/qcom,lpasscorecc-sc7280.h>
+ lpass_audiocc: clock-controller@3300000 {
+ compatible = "qcom,sc7280-lpassaudiocc";
+- reg = <0x3300000 0x30000>;
++ reg = <0x3300000 0x30000>,
++ <0x32a9000 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>;
+ clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src";
+ power-domains = <&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
++ #reset-cells = <1>;
+ };
+
+ - |
+diff --git a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+index 02e605fac408d..9ddba7f2e7aa6 100644
+--- a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
++++ b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+@@ -473,9 +473,6 @@ patternProperties:
+ Specifies whether the event is to be interpreted as a key (1)
+ or a switch (5).
+
+- required:
+- - linux,code
+-
+ additionalProperties: false
+
+ dependencies:
+@@ -501,7 +498,7 @@ patternProperties:
+
+ azoteq,slider-size:
+ $ref: /schemas/types.yaml#/definitions/uint32
+- minimum: 0
++ minimum: 1
+ maximum: 65535
+ description:
+ Specifies the slider's one-dimensional resolution, equal to the
+@@ -575,9 +572,9 @@ patternProperties:
+ linux,code: true
+
+ azoteq,gesture-max-ms:
+- multipleOf: 4
++ multipleOf: 16
+ minimum: 0
+- maximum: 1020
++ maximum: 4080
+ description:
+ Specifies the length of time (in ms) within which a tap, swipe
+ or flick gesture must be completed in order to be acknowledged
+@@ -585,9 +582,9 @@ patternProperties:
+ gesture applies to all remaining swipe or flick gestures.
+
+ azoteq,gesture-min-ms:
+- multipleOf: 4
++ multipleOf: 16
+ minimum: 0
+- maximum: 124
++ maximum: 496
+ description:
+ Specifies the length of time (in ms) for which a tap gesture must
+ be held in order to be acknowledged by the device.
+@@ -620,9 +617,6 @@ patternProperties:
+ GPIO, they must all be of the same type (proximity, touch or
+ slider gesture).
+
+- required:
+- - linux,code
+-
+ additionalProperties: false
+
+ required:
+@@ -693,6 +687,7 @@ allOf:
+ properties:
+ azoteq,slider-size:
+ multipleOf: 16
++ minimum: 16
+ maximum: 4080
+
+ azoteq,top-speed:
+@@ -935,14 +930,14 @@ examples:
+
+ event-tap {
+ linux,code = <KEY_PLAYPAUSE>;
+- azoteq,gesture-max-ms = <600>;
+- azoteq,gesture-min-ms = <24>;
++ azoteq,gesture-max-ms = <400>;
++ azoteq,gesture-min-ms = <32>;
+ };
+
+ event-flick-pos {
+ linux,code = <KEY_NEXTSONG>;
+- azoteq,gesture-max-ms = <600>;
+- azoteq,gesture-dist = <816>;
++ azoteq,gesture-max-ms = <800>;
++ azoteq,gesture-dist = <800>;
+ };
+
+ event-flick-neg {
+diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+index 65cbc6dee545e..2a5bafe0660a0 100644
+--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
++++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+@@ -92,6 +92,10 @@ properties:
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+
++ pwm:
++ type: object
++ $ref: /schemas/leds/leds-qcom-lpg.yaml#
++
+ patternProperties:
+ "^adc@[0-9a-f]+$":
+ type: object
+@@ -117,10 +121,6 @@ patternProperties:
+ type: object
+ $ref: /schemas/power/reset/qcom,pon.yaml#
+
+- "pwm@[0-9a-f]+$":
+- type: object
+- $ref: /schemas/leds/leds-qcom-lpg.yaml#
+-
+ "^rtc@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
+diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+index 376e739bcad40..49b4f7a32e71e 100644
+--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
++++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+@@ -14,9 +14,6 @@ description: |+
+ This PCIe host controller is based on the Synopsys DesignWare PCIe IP
+ and thus inherits all the common properties defined in snps,dw-pcie.yaml.
+
+-allOf:
+- - $ref: /schemas/pci/snps,dw-pcie.yaml#
+-
+ properties:
+ compatible:
+ enum:
+@@ -61,7 +58,7 @@ properties:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_phy
+- - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
++ - enum: [ pcie_inbound_axi, pcie_aux ]
+
+ num-lanes:
+ const: 1
+@@ -175,6 +172,47 @@ required:
+ - clocks
+ - clock-names
+
++allOf:
++ - $ref: /schemas/pci/snps,dw-pcie.yaml#
++ - if:
++ properties:
++ compatible:
++ contains:
++ const: fsl,imx6sx-pcie
++ then:
++ properties:
++ clock-names:
++ items:
++ - {}
++ - {}
++ - {}
++ - const: pcie_inbound_axi
++ - if:
++ properties:
++ compatible:
++ contains:
++ const: fsl,imx8mq-pcie
++ then:
++ properties:
++ clock-names:
++ items:
++ - {}
++ - {}
++ - {}
++ - const: pcie_aux
++ - if:
++ properties:
++ compatible:
++ not:
++ contains:
++ enum:
++ - fsl,imx6sx-pcie
++ - fsl,imx8mq-pcie
++ then:
++ properties:
++ clock-names:
++ maxItems: 3
++
+ unevaluatedProperties: false
+
+ examples:
+diff --git a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
+index 30b6396d83c83..aea0e2bcdd778 100644
+--- a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
++++ b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
+@@ -36,7 +36,7 @@ properties:
+ - const: mpu
+
+ interrupts:
+- maxItems: 1
++ maxItems: 2
+
+ clocks:
+ items:
+@@ -94,8 +94,9 @@ examples:
+ #interrupt-cells = <1>;
+ ranges = <0x81000000 0 0x40000000 0 0x40000000 0 0x00010000>,
+ <0x82000000 0 0x50000000 0 0x50000000 0 0x20000000>;
+- interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "intr";
++ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "msi", "intr";
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map =
+ <0 0 0 1 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
+diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
+index 4eadea55df10f..41abfa94877fb 100644
+--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
+@@ -87,6 +87,8 @@ patternProperties:
+ "wifi_led" "led" 1, 2
+ "i2c" "i2c" 3, 4
+ "uart1_0" "uart" 7, 8, 9, 10
++ "uart1_rx_tx" "uart" 42, 43
++ "uart1_cts_rts" "uart" 44, 45
+ "pcie_clk" "pcie" 9
+ "pcie_wake" "pcie" 10
+ "spi1_0" "spi" 11, 12, 13, 14
+@@ -98,9 +100,11 @@ patternProperties:
+ "emmc_45" "emmc" 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32
+ "spi1_1" "spi" 23, 24, 25, 26
+- "uart1_2" "uart" 29, 30, 31, 32
++ "uart1_2_rx_tx" "uart" 29, 30
++ "uart1_2_cts_rts" "uart" 31, 32
+ "uart1_1" "uart" 23, 24, 25, 26
+- "uart2_0" "uart" 29, 30, 31, 32
++ "uart2_0_rx_tx" "uart" 29, 30
++ "uart2_0_cts_rts" "uart" 31, 32
+ "spi0" "spi" 33, 34, 35, 36
+ "spi0_wp_hold" "spi" 37, 38
+ "uart1_3_rx_tx" "uart" 35, 36
+@@ -153,7 +157,7 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [emmc, emmc_rst]
++ enum: [emmc_45, emmc_51]
+ - if:
+ properties:
+ function:
+@@ -217,8 +221,12 @@ patternProperties:
+ then:
+ properties:
+ groups:
+- enum: [uart1_0, uart1_1, uart1_2, uart1_3_rx_tx,
+- uart1_3_cts_rts, uart2_0, uart2_1, uart0, uart1, uart2]
++ items:
++ enum: [uart1_0, uart1_rx_tx, uart1_cts_rts, uart1_1,
++ uart1_2_rx_tx, uart1_2_cts_rts, uart1_3_rx_tx,
++ uart1_3_cts_rts, uart2_0_rx_tx, uart2_0_cts_rts,
++ uart2_1, uart0, uart1, uart2]
++ maxItems: 2
+ - if:
+ properties:
+ function:
+@@ -348,6 +356,27 @@ examples:
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+
++ pcie_pins: pcie-pins {
++ mux {
++ function = "pcie";
++ groups = "pcie_clk", "pcie_wake", "pcie_pereset";
++ };
++ };
++
++ pwm_pins: pwm-pins {
++ mux {
++ function = "pwm";
++ groups = "pwm0", "pwm1_0";
++ };
++ };
++
++ spi0_pins: spi0-pins {
++ mux {
++ function = "spi";
++ groups = "spi0", "spi0_wp_hold";
++ };
++ };
++
+ uart1_pins: uart1-pins {
+ mux {
+ function = "uart";
+@@ -355,6 +384,13 @@ examples:
+ };
+ };
+
++ uart1_3_pins: uart1-3-pins {
++ mux {
++ function = "uart";
++ groups = "uart1_3_rx_tx", "uart1_3_cts_rts";
++ };
++ };
++
+ uart2_pins: uart2-pins {
+ mux {
+ function = "uart";
+diff --git a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
+index a7fae1772a81b..cd8e9a8907f84 100644
+--- a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
++++ b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
+@@ -30,7 +30,9 @@ properties:
+ maxItems: 1
+
+ "#pwm-cells":
+- const: 2
++ enum: [2, 3]
++ description:
++ The only flag supported by the controller is PWM_POLARITY_INVERTED.
+
+ microchip,sync-update-mask:
+ description: |
+diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+index 5d6ea66a863fe..1f75feec3dec6 100644
+--- a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
++++ b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+@@ -109,7 +109,7 @@ audio-codec@1{
+ reg = <1 0>;
+ interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "intr2"
+- reset-gpios = <&msmgpio 64 0>;
++ reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>;
+ slim-ifc-dev = <&wc9335_ifd>;
+ clock-names = "mclk", "native";
+ clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
+diff --git a/Documentation/devicetree/bindings/sound/rt5682.txt b/Documentation/devicetree/bindings/sound/rt5682.txt
+index c5f2b8febceec..6b87db68337c2 100644
+--- a/Documentation/devicetree/bindings/sound/rt5682.txt
++++ b/Documentation/devicetree/bindings/sound/rt5682.txt
+@@ -46,7 +46,7 @@ Optional properties:
+
+ - realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out.
+
+-- #sound-dai-cells: Should be set to '<0>'.
++- #sound-dai-cells: Should be set to '<1>'.
+
+ Pins on the device (for linking into audio routes) for RT5682:
+
+diff --git a/Documentation/driver-api/spi.rst b/Documentation/driver-api/spi.rst
+index f64cb666498aa..f28887045049d 100644
+--- a/Documentation/driver-api/spi.rst
++++ b/Documentation/driver-api/spi.rst
+@@ -25,8 +25,8 @@ hardware, which may be as simple as a set of GPIO pins or as complex as
+ a pair of FIFOs connected to dual DMA engines on the other side of the
+ SPI shift register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and expose
+-the SPI side of their device as a :c:type:`struct spi_master
+-<spi_master>`. SPI devices are children of that master,
++the SPI side of their device as a :c:type:`struct spi_controller
++<spi_controller>`. SPI devices are children of that master,
+ represented as a :c:type:`struct spi_device <spi_device>` and
+ manufactured from :c:type:`struct spi_board_info
+ <spi_board_info>` descriptors which are usually provided by
+diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst
+index 17779a2772e51..5f6454b9dbd4d 100644
+--- a/Documentation/fault-injection/fault-injection.rst
++++ b/Documentation/fault-injection/fault-injection.rst
+@@ -83,9 +83,7 @@ configuration of fault-injection capabilities.
+ - /sys/kernel/debug/fail*/times:
+
+ specifies how many times failures may happen at most. A value of -1
+- means "no limit". Note, though, that this file only accepts unsigned
+- values. So, if you want to specify -1, you better use 'printf' instead
+- of 'echo', e.g.: $ printf %#x -1 > times
++ means "no limit".
+
+ - /sys/kernel/debug/fail*/space:
+
+@@ -284,7 +282,7 @@ Application Examples
+ echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
+ echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+ echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++ echo -1 > /sys/kernel/debug/$FAILTYPE/times
+ echo 0 > /sys/kernel/debug/$FAILTYPE/space
+ echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+ echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -338,7 +336,7 @@ Application Examples
+ echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+ echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+ echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++ echo -1 > /sys/kernel/debug/$FAILTYPE/times
+ echo 0 > /sys/kernel/debug/$FAILTYPE/space
+ echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+ echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -369,7 +367,7 @@ Application Examples
+ echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+ echo 100 > /sys/kernel/debug/$FAILTYPE/probability
+ echo 0 > /sys/kernel/debug/$FAILTYPE/interval
+- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++ echo -1 > /sys/kernel/debug/$FAILTYPE/times
+ echo 0 > /sys/kernel/debug/$FAILTYPE/space
+ echo 1 > /sys/kernel/debug/$FAILTYPE/verbose
+
+diff --git a/Makefile b/Makefile
+index 0c7ae314ad3d5..ff8d88b113919 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 15
++SUBLEVEL = 16
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 8b311e400ec14..732a4680e733e 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -629,7 +629,7 @@ config ARCH_SUPPORTS_SHADOW_CALL_STACK
+ config SHADOW_CALL_STACK
+ bool "Shadow Call Stack"
+ depends on ARCH_SUPPORTS_SHADOW_CALL_STACK
+- depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
++ depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
+ help
+ This option enables the compiler's Shadow Call Stack, which
+ uses a shadow stack to protect function return addresses from
+diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
+index fdc485d7787a6..084c27cb0c707 100644
+--- a/arch/alpha/include/asm/thread_info.h
++++ b/arch/alpha/include/asm/thread_info.h
+@@ -75,7 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
+
+ /* Work to do on interrupt/exception return. */
+ #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+- _TIF_NOTIFY_RESUME)
++ _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)
+
+ /* Work to do on any return to userspace. */
+ #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
+diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
+index e227f3a29a43c..c41a5a9c3b9f2 100644
+--- a/arch/alpha/kernel/entry.S
++++ b/arch/alpha/kernel/entry.S
+@@ -469,8 +469,10 @@ entSys:
+ #ifdef CONFIG_AUDITSYSCALL
+ lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ and $3, $6, $3
+-#endif
+ bne $3, strace
++#else
++ blbs $3, strace /* check for SYSCALL_TRACE in disguise */
++#endif
+ beq $4, 1f
+ ldq $27, 0($5)
+ 1: jsr $26, ($27), sys_ni_syscall
+diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
+index 46e6d3ed8f35a..c042c416a94a3 100644
+--- a/arch/arm/boot/dts/armada-370.dtsi
++++ b/arch/arm/boot/dts/armada-370.dtsi
+@@ -74,7 +74,7 @@
+
+ pcie2: pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
+index 7f2f24a29e6c1..352a2f7ba3114 100644
+--- a/arch/arm/boot/dts/armada-375.dtsi
++++ b/arch/arm/boot/dts/armada-375.dtsi
+@@ -582,7 +582,7 @@
+
+ pcie1: pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
+index cff1269f3fbfd..7146cc8f082af 100644
+--- a/arch/arm/boot/dts/armada-380.dtsi
++++ b/arch/arm/boot/dts/armada-380.dtsi
+@@ -79,7 +79,7 @@
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -98,7 +98,7 @@
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index a41902e3815cd..0b64d7505dca0 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -23,6 +23,12 @@
+ stdout-path = &uart0;
+ };
+
++ aliases {
++ ethernet0 = ð0;
++ ethernet1 = ð1;
++ ethernet2 = ð2;
++ };
++
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1024 MB */
+@@ -455,7 +461,17 @@
+ };
+ };
+
+- /* port 6 is connected to eth0 */
++ ports@6 {
++ reg = <6>;
++ label = "cpu";
++ ethernet = <ð0>;
++ phy-mode = "rgmii-id";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++ };
+ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
+index 83392b92dae28..be8d607c59b21 100644
+--- a/arch/arm/boot/dts/armada-385.dtsi
++++ b/arch/arm/boot/dts/armada-385.dtsi
+@@ -93,7 +93,7 @@
+ /* x1 port */
+ pcie2: pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -121,7 +121,7 @@
+ /* x1 port */
+ pcie3: pcie@3,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -152,7 +152,7 @@
+ */
+ pcie4: pcie@4,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
+index e0b7c20998312..9525e7b7f4360 100644
+--- a/arch/arm/boot/dts/armada-39x.dtsi
++++ b/arch/arm/boot/dts/armada-39x.dtsi
+@@ -453,7 +453,7 @@
+ /* x1 port */
+ pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -472,7 +472,7 @@
+ /* x1 port */
+ pcie@3,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -494,7 +494,7 @@
+ */
+ pcie@4,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+index 8558bf6bb54c6..d55fe162fc7f0 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+@@ -97,7 +97,7 @@
+
+ pcie2: pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -115,7 +115,7 @@
+
+ pcie3: pcie@3,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -133,7 +133,7 @@
+
+ pcie4: pcie@4,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -151,7 +151,7 @@
+
+ pcie5: pcie@5,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+index 2d85fe8ac3272..fdcc818199401 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+@@ -112,7 +112,7 @@
+
+ pcie2: pcie@2,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -130,7 +130,7 @@
+
+ pcie3: pcie@3,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -148,7 +148,7 @@
+
+ pcie4: pcie@4,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -166,7 +166,7 @@
+
+ pcie5: pcie@5,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -184,7 +184,7 @@
+
+ pcie6: pcie@6,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
++ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
+ reg = <0x3000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -202,7 +202,7 @@
+
+ pcie7: pcie@7,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
++ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
+ reg = <0x3800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -220,7 +220,7 @@
+
+ pcie8: pcie@8,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
++ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
+ reg = <0x4000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+@@ -238,7 +238,7 @@
+
+ pcie9: pcie@9,0 {
+ device_type = "pci";
+- assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
++ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+index a6a2bc3b855c2..fcc890e3ad735 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+@@ -162,16 +162,9 @@
+ #size-cells = <1>;
+ ranges;
+
+- /* LPC FW cycle bridge region requires natural alignment */
+- flash_memory: region@b8000000 {
+- no-map;
+- reg = <0xb8000000 0x04000000>; /* 64M */
+- };
+-
+- /* 48MB region from the end of flash to start of vga memory */
+- ramoops@bc000000 {
++ ramoops@b3e00000 {
+ compatible = "ramoops";
+- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
+ record-size = <0x8000>;
+ console-size = <0x8000>;
+ ftrace-size = <0x8000>;
+@@ -179,6 +172,12 @@
+ max-reason = <3>; /* KMSG_DUMP_EMERG */
+ };
+
++ /* LPC FW cycle bridge region requires natural alignment */
++ flash_memory: region@b4000000 {
++ no-map;
++ reg = <0xb4000000 0x04000000>; /* 64M */
++ };
++
+ /* VGA region is dictated by hardware strapping */
+ vga_memory: region@bf000000 {
+ no-map;
+diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+index bf59a9962379d..4879da4cdbd25 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+@@ -95,14 +95,9 @@
+ #size-cells = <1>;
+ ranges;
+
+- flash_memory: region@b8000000 {
+- no-map;
+- reg = <0xb8000000 0x04000000>; /* 64M */
+- };
+-
+- ramoops@bc000000 {
++ ramoops@b3e00000 {
+ compatible = "ramoops";
+- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
+ record-size = <0x8000>;
+ console-size = <0x8000>;
+ ftrace-size = <0x8000>;
+@@ -110,6 +105,13 @@
+ max-reason = <3>; /* KMSG_DUMP_EMERG */
+ };
+
++ /* LPC FW cycle bridge region requires natural alignment */
++ flash_memory: region@b4000000 {
++ no-map;
++ reg = <0xb4000000 0x04000000>; /* 64M */
++ };
++
++ /* VGA region is dictated by hardware strapping */
+ vga_memory: region@bf000000 {
+ no-map;
+ compatible = "shared-dma-pool";
+diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
+index 89e0bdaf3a85f..726d353eda686 100644
+--- a/arch/arm/boot/dts/dove.dtsi
++++ b/arch/arm/boot/dts/dove.dtsi
+@@ -129,7 +129,7 @@
+ pcie1: pcie@2 {
+ device_type = "pci";
+ status = "disabled";
+- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ clocks = <&gate_clk 5>;
+ marvell,pcie-port = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
+index d10669fcd527d..9e9eba8bad5e4 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
+@@ -366,7 +366,7 @@
+ spi-max-frequency = <20000000>;
+ spi-rx-bus-width = <2>;
+ label = "bmc";
+- partitions@80000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
+index 491606c4f044d..2a394cc15284c 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
+@@ -142,7 +142,7 @@
+ reg = <0>;
+ spi-rx-bus-width = <2>;
+
+- partitions@80000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
+index a0c2d76526258..f7b38bee039bc 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
+@@ -388,7 +388,7 @@
+ spi-max-frequency = <5000000>;
+ spi-rx-bus-width = <2>;
+ label = "bmc";
+- partitions@80000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -422,7 +422,7 @@
+ reg = <1>;
+ spi-max-frequency = <5000000>;
+ spi-rx-bus-width = <2>;
+- partitions@88000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -447,7 +447,7 @@
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ spi-rx-bus-width = <2>;
+- partitions@A0000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+index 3dad32834e5ea..f53d45fa1de87 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+@@ -74,7 +74,7 @@
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+- partitions@80000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -135,7 +135,7 @@
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+- partitions@A0000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+index 132e702281fc5..87359ab05db3e 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+@@ -107,7 +107,7 @@
+ reg = <0>;
+ spi-rx-bus-width = <2>;
+
+- partitions@80000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -146,7 +146,7 @@
+ reg = <1>;
+ npcm,fiu-rx-bus-width = <2>;
+
+- partitions@88000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -173,7 +173,7 @@
+ reg = <0>;
+ spi-rx-bus-width = <2>;
+
+- partitions@A0000000 {
++ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index ada4c828bf2f4..095849423de1d 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -1580,7 +1580,7 @@
+ };
+
+ etb@1a01000 {
+- compatible = "coresight-etb10", "arm,primecell";
++ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0x1a01000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
+index fd41243a0b2c0..9d5a04a46b14e 100644
+--- a/arch/arm/boot/dts/spear600.dtsi
++++ b/arch/arm/boot/dts/spear600.dtsi
+@@ -47,7 +47,7 @@
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0xfc200000 0x1000>;
+ interrupt-parent = <&vic1>;
+- interrupts = <12>;
++ interrupts = <13>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+index 2e3c9fbb4eb36..275167f26fd9d 100644
+--- a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
++++ b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+@@ -13,7 +13,6 @@
+ /dts-v1/;
+
+ #include "stm32mp157.dtsi"
+-#include "stm32mp15xc.dtsi"
+ #include "stm32mp15xx-dhcor-som.dtsi"
+ #include "stm32mp15xx-dhcor-avenger96.dtsi"
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index 90933077d66de..b6957cbdeff5f 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -100,7 +100,7 @@
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>;
++ gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
+index 41b2e8abc9e69..708816caf859c 100644
+--- a/arch/arm/mach-mmp/time.c
++++ b/arch/arm/mach-mmp/time.c
+@@ -43,18 +43,21 @@
+ static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+
+ /*
+- * FIXME: the timer needs some delay to stablize the counter capture
++ * Read the timer through the CVWR register. Delay is required after requesting
++ * a read. The CR register cannot be directly read due to metastability issues
++ * documented in the PXA168 software manual.
+ */
+ static inline uint32_t timer_read(void)
+ {
+- int delay = 100;
++ uint32_t val;
++ int delay = 3;
+
+ __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
+
+ while (delay--)
+- cpu_relax();
++ val = __raw_readl(mmp_timer_base + TMR_CVWR(1));
+
+- return __raw_readl(mmp_timer_base + TMR_CVWR(1));
++ return val;
+ }
+
+ static u64 notrace mmp_read_sched_clock(void)
+diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
+index 51a63b29d4045..a4d195e9eb8c8 100644
+--- a/arch/arm64/boot/dts/apple/t8103.dtsi
++++ b/arch/arm64/boot/dts/apple/t8103.dtsi
+@@ -412,7 +412,7 @@
+ resets = <&ps_ans2>;
+ };
+
+- pcie0_dart_0: dart@681008000 {
++ pcie0_dart_0: iommu@681008000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x6 0x81008000 0x0 0x4000>;
+ #iommu-cells = <1>;
+@@ -421,7 +421,7 @@
+ power-domains = <&ps_apcie_gp>;
+ };
+
+- pcie0_dart_1: dart@682008000 {
++ pcie0_dart_1: iommu@682008000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x6 0x82008000 0x0 0x4000>;
+ #iommu-cells = <1>;
+@@ -430,7 +430,7 @@
+ power-domains = <&ps_apcie_gp>;
+ };
+
+- pcie0_dart_2: dart@683008000 {
++ pcie0_dart_2: iommu@683008000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x6 0x83008000 0x0 0x4000>;
+ #iommu-cells = <1>;
+diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+index ada164d423f3d..200f97e1c4c9c 100644
+--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+@@ -125,9 +125,12 @@
+ /delete-property/ mrvl,i2c-fast-mode;
+ status = "okay";
+
++ /* MCP7940MT-I/MNY RTC */
+ rtc@6f {
+ compatible = "microchip,mcp7940x";
+ reg = <0x6f>;
++ interrupt-parent = <&gpiosb>;
++ interrupts = <5 0>; /* GPIO2_5 */
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+index 9b1af9c801308..d31a194124c91 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+@@ -26,14 +26,14 @@
+ stdout-path = "serial0:921600n8";
+ };
+
+- cpus_fixed_vproc0: fixedregulator@0 {
++ cpus_fixed_vproc0: regulator-vproc-buck0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vproc_buck0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+- cpus_fixed_vproc1: fixedregulator@1 {
++ cpus_fixed_vproc1: regulator-vproc-buck1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vproc_buck1";
+ regulator-min-microvolt = <1000000>;
+@@ -50,7 +50,7 @@
+ id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>;
+ };
+
+- usb_p0_vbus: regulator@2 {
++ usb_p0_vbus: regulator-usb-p0-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "p0_vbus";
+ regulator-min-microvolt = <5000000>;
+@@ -59,7 +59,7 @@
+ enable-active-high;
+ };
+
+- usb_p1_vbus: regulator@3 {
++ usb_p1_vbus: regulator-usb-p1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "p1_vbus";
+ regulator-min-microvolt = <5000000>;
+@@ -68,7 +68,7 @@
+ enable-active-high;
+ };
+
+- usb_p2_vbus: regulator@4 {
++ usb_p2_vbus: regulator-usb-p2-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "p2_vbus";
+ regulator-min-microvolt = <5000000>;
+@@ -77,7 +77,7 @@
+ enable-active-high;
+ };
+
+- usb_p3_vbus: regulator@5 {
++ usb_p3_vbus: regulator-usb-p3-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "p3_vbus";
+ regulator-min-microvolt = <5000000>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+index 4797537cb3683..2ebefd144d6f5 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+@@ -160,70 +160,70 @@
+ #clock-cells = <0>;
+ };
+
+- clk26m: oscillator@0 {
++ clk26m: oscillator-26m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "clk26m";
+ };
+
+- clk32k: oscillator@1 {
++ clk32k: oscillator-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "clk32k";
+ };
+
+- clkfpc: oscillator@2 {
++ clkfpc: oscillator-50m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ clock-output-names = "clkfpc";
+ };
+
+- clkaud_ext_i_0: oscillator@3 {
++ clkaud_ext_i_0: oscillator-aud0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <6500000>;
+ clock-output-names = "clkaud_ext_i_0";
+ };
+
+- clkaud_ext_i_1: oscillator@4 {
++ clkaud_ext_i_1: oscillator-aud1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <196608000>;
+ clock-output-names = "clkaud_ext_i_1";
+ };
+
+- clkaud_ext_i_2: oscillator@5 {
++ clkaud_ext_i_2: oscillator-aud2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <180633600>;
+ clock-output-names = "clkaud_ext_i_2";
+ };
+
+- clki2si0_mck_i: oscillator@6 {
++ clki2si0_mck_i: oscillator-i2s0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <30000000>;
+ clock-output-names = "clki2si0_mck_i";
+ };
+
+- clki2si1_mck_i: oscillator@7 {
++ clki2si1_mck_i: oscillator-i2s1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <30000000>;
+ clock-output-names = "clki2si1_mck_i";
+ };
+
+- clki2si2_mck_i: oscillator@8 {
++ clki2si2_mck_i: oscillator-i2s2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <30000000>;
+ clock-output-names = "clki2si2_mck_i";
+ };
+
+- clktdmin_mclk_i: oscillator@9 {
++ clktdmin_mclk_i: oscillator-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <30000000>;
+@@ -266,7 +266,7 @@
+ reg = <0 0x10005000 0 0x1000>;
+ };
+
+- pio: pinctrl@10005000 {
++ pio: pinctrl@1000b000 {
+ compatible = "mediatek,mt2712-pinctrl";
+ reg = <0 0x1000b000 0 0x1000>;
+ mediatek,pctl-regmap = <&syscfg_pctl_a>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+index 9bdf5145966c5..dde9ce137b4f1 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+@@ -88,14 +88,14 @@
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW 0>;
+ };
+
+- clk26m: oscillator@0 {
++ clk26m: oscillator-26m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "clk26m";
+ };
+
+- clk32k: oscillator@1 {
++ clk32k: oscillator-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+@@ -117,7 +117,7 @@
+ compatible = "simple-bus";
+ ranges;
+
+- gic: interrupt-controller@0c000000 {
++ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <4>;
+ interrupt-parent = <&gic>;
+@@ -138,7 +138,7 @@
+
+ };
+
+- sysirq: intpol-controller@0c53a650 {
++ sysirq: intpol-controller@c53a650 {
+ compatible = "mediatek,mt6779-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+index 15616231022a2..c3677d77e0a45 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+@@ -95,7 +95,7 @@
+ };
+ };
+
+- clk26m: oscillator@0 {
++ clk26m: oscillator-26m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+index e3a407d03551f..25b297bbb1b02 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -13,7 +13,7 @@
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+- clk40m: oscillator@0 {
++ clk40m: oscillator-40m {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ #clock-cells = <0>;
+@@ -162,7 +162,7 @@
+ #clock-cells = <1>;
+ };
+
+- trng: trng@1020f000 {
++ trng: rng@1020f000 {
+ compatible = "mediatek,mt7986-rng",
+ "mediatek,mt7623-rng";
+ reg = <0 0x1020f000 0 0x100>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+index 9d32871973a29..85fb61324be8d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+@@ -1670,7 +1670,7 @@
+ <GIC_SPI 278 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "job", "mmu", "gpu";
+
+- clocks = <&topckgen CLK_TOP_MFGPLL_CK>;
++ clocks = <&mfgcfg CLK_MFG_BG3D>;
+
+ power-domains =
+ <&spm MT8183_POWER_DOMAIN_MFG_CORE0>,
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+index 066c14989708a..e694ddb74f7d5 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+@@ -27,7 +27,7 @@
+ reg = <0x000>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- capacity-dmips-mhz = <578>;
++ capacity-dmips-mhz = <308>;
+ cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ next-level-cache = <&l2_0>;
+ #cooling-cells = <2>;
+@@ -39,7 +39,7 @@
+ reg = <0x100>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- capacity-dmips-mhz = <578>;
++ capacity-dmips-mhz = <308>;
+ cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ next-level-cache = <&l2_0>;
+ #cooling-cells = <2>;
+@@ -51,7 +51,7 @@
+ reg = <0x200>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- capacity-dmips-mhz = <578>;
++ capacity-dmips-mhz = <308>;
+ cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ next-level-cache = <&l2_0>;
+ #cooling-cells = <2>;
+@@ -63,7 +63,7 @@
+ reg = <0x300>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- capacity-dmips-mhz = <578>;
++ capacity-dmips-mhz = <308>;
+ cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ next-level-cache = <&l2_0>;
+ #cooling-cells = <2>;
+diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+index 8ee1529683a34..ec8dfb3d1c6d6 100644
+--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+@@ -17,7 +17,7 @@
+ };
+
+ firmware {
+- optee: optee@4fd00000 {
++ optee: optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+@@ -209,7 +209,7 @@
+ };
+ };
+
+- i2c0_pins_a: i2c0@0 {
++ i2c0_pins_a: i2c0 {
+ pins1 {
+ pinmux = <MT8516_PIN_58_SDA0__FUNC_SDA0_0>,
+ <MT8516_PIN_59_SCL0__FUNC_SCL0_0>;
+@@ -217,7 +217,7 @@
+ };
+ };
+
+- i2c2_pins_a: i2c2@0 {
++ i2c2_pins_a: i2c2 {
+ pins1 {
+ pinmux = <MT8516_PIN_60_SDA2__FUNC_SDA2_0>,
+ <MT8516_PIN_61_SCL2__FUNC_SCL2_0>;
+diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+index 567b331065560..92f264891d84b 100644
+--- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
++++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+@@ -368,7 +368,7 @@
+
+ bus-width = <4>;
+
+- cd-gpios = <&tlmm 38 0x1>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ vmmc-supply = <&vreg_l21a_2p95>;
+ vqmmc-supply = <&vreg_l13a_2p95>;
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+index 1ba2eca33c7b6..6a716c83e5f1d 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
++++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+@@ -37,6 +37,8 @@
+
+ &blsp1_spi1 {
+ cs-select = <0>;
++ pinctrl-0 = <&spi_0_pins>;
++ pinctrl-names = "default";
+ status = "okay";
+
+ flash@0 {
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 48bc2e09128d9..863a60b636416 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1331,7 +1331,7 @@
+ };
+
+ mpss: remoteproc@4080000 {
+- compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil";
++ compatible = "qcom,msm8916-mss-pil";
+ reg = <0x04080000 0x100>,
+ <0x04020000 0x040>;
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+index f430d797196f5..ff60b7004d260 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+@@ -471,7 +471,7 @@
+ &sdhc2 {
+ status = "okay";
+
+- cd-gpios = <&tlmm 100 0>;
++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&pm8994_l21>;
+ vqmmc-supply = <&pm8994_l13>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+index 8bc6c070e3066..86ef0091cafff 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -6,6 +6,7 @@
+ #include <dt-bindings/clock/qcom,gcc-msm8994.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8994.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
++#include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+
+ / {
+@@ -502,7 +503,7 @@
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+- cd-gpios = <&tlmm 100 0>;
++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 742eac4ce9b35..5cf04c350a62c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -7,6 +7,7 @@
+ #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
+ #include <dt-bindings/interconnect/qcom,msm8996.h>
++#include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+ #include <dt-bindings/soc/qcom,apr.h>
+ #include <dt-bindings/thermal/thermal.h>
+@@ -143,82 +144,92 @@
+ /* Nominal fmax for now */
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-422400000 {
+ opp-hz = /bits/ 64 <422400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-844800000 {
+ opp-hz = /bits/ 64 <844800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1228800000 {
+ opp-hz = /bits/ 64 <1228800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x5>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1363200000 {
++ opp-hz = /bits/ 64 <1363200000>;
++ opp-supported-hw = <0x2>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x5>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1497600000 {
++ opp-hz = /bits/ 64 <1497600000>;
++ opp-supported-hw = <0x04>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1593600000 {
+ opp-hz = /bits/ 64 <1593600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ };
+@@ -231,127 +242,137 @@
+ /* Nominal fmax for now */
+ opp-307200000 {
+ opp-hz = /bits/ 64 <307200000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-403200000 {
+ opp-hz = /bits/ 64 <403200000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-556800000 {
+ opp-hz = /bits/ 64 <556800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-729600000 {
+ opp-hz = /bits/ 64 <729600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-806400000 {
+ opp-hz = /bits/ 64 <806400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-883200000 {
+ opp-hz = /bits/ 64 <883200000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-940800000 {
+ opp-hz = /bits/ 64 <940800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1036800000 {
+ opp-hz = /bits/ 64 <1036800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1190400000 {
+ opp-hz = /bits/ 64 <1190400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1248000000 {
+ opp-hz = /bits/ 64 <1248000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1401600000 {
+ opp-hz = /bits/ 64 <1401600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1478400000 {
+ opp-hz = /bits/ 64 <1478400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1555200000 {
+ opp-hz = /bits/ 64 <1555200000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1632000000 {
+ opp-hz = /bits/ 64 <1632000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1708800000 {
+ opp-hz = /bits/ 64 <1708800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1785600000 {
+ opp-hz = /bits/ 64 <1785600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x7>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1804800000 {
++ opp-hz = /bits/ 64 <1804800000>;
++ opp-supported-hw = <0x6>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1824000000 {
+ opp-hz = /bits/ 64 <1824000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1900800000 {
++ opp-hz = /bits/ 64 <1900800000>;
++ opp-supported-hw = <0x4>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1920000000 {
+ opp-hz = /bits/ 64 <1920000000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2073600000 {
+ opp-hz = /bits/ 64 <2073600000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ opp-2150400000 {
+ opp-hz = /bits/ 64 <2150400000>;
+- opp-supported-hw = <0x77>;
++ opp-supported-hw = <0x1>;
+ clock-latency-ns = <200000>;
+ };
+ };
+@@ -1208,17 +1229,17 @@
+ compatible = "operating-points-v2";
+
+ /*
+- * 624Mhz and 560Mhz are only available on speed
+- * bin (1 << 0). All the rest are available on
+- * all bins of the hardware
++ * 624Mhz is only available on speed bins 0 and 3.
++ * 560Mhz is only available on speed bins 0, 2 and 3.
++ * All the rest are available on all bins of the hardware.
+ */
+ opp-624000000 {
+ opp-hz = /bits/ 64 <624000000>;
+- opp-supported-hw = <0x01>;
++ opp-supported-hw = <0x09>;
+ };
+ opp-560000000 {
+ opp-hz = /bits/ 64 <560000000>;
+- opp-supported-hw = <0x01>;
++ opp-supported-hw = <0x0d>;
+ };
+ opp-510000000 {
+ opp-hz = /bits/ 64 <510000000>;
+@@ -3337,7 +3358,7 @@
+ interrupt-names = "intr1", "intr2";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
+
+ slim-ifc-dev = <&tasha_ifd>;
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996pro.dtsi b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi
+new file mode 100644
+index 0000000000000..63e1b4ec7a360
+--- /dev/null
++++ b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi
+@@ -0,0 +1,266 @@
++// SPDX-License-Identifier: BSD-3-Clause
++/*
++ * Copyright (c) 2022, Linaro Limited
++ */
++
++#include "msm8996.dtsi"
++
++/ {
++ /delete-node/ opp-table-cluster0;
++ /delete-node/ opp-table-cluster1;
++
++ /*
++ * On MSM8996 Pro the cpufreq driver shifts speed bins into the high
++ * nibble of supported hw, so speed bin 0 becomes 0x10, speed bin 1
++ * becomes 0x20, speed 2 becomes 0x40.
++ */
++
++ cluster0_opp: opp-table-cluster0 {
++ compatible = "operating-points-v2-kryo-cpu";
++ nvmem-cells = <&speedbin_efuse>;
++ opp-shared;
++
++ opp-307200000 {
++ opp-hz = /bits/ 64 <307200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-384000000 {
++ opp-hz = /bits/ 64 <384000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-460800000 {
++ opp-hz = /bits/ 64 <460800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-537600000 {
++ opp-hz = /bits/ 64 <537600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-614400000 {
++ opp-hz = /bits/ 64 <614400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-691200000 {
++ opp-hz = /bits/ 64 <691200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-768000000 {
++ opp-hz = /bits/ 64 <768000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-844800000 {
++ opp-hz = /bits/ 64 <844800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-902400000 {
++ opp-hz = /bits/ 64 <902400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-979200000 {
++ opp-hz = /bits/ 64 <979200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1056000000 {
++ opp-hz = /bits/ 64 <1056000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1132800000 {
++ opp-hz = /bits/ 64 <1132800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1209600000 {
++ opp-hz = /bits/ 64 <1209600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1286400000 {
++ opp-hz = /bits/ 64 <1286400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1363200000 {
++ opp-hz = /bits/ 64 <1363200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1440000000 {
++ opp-hz = /bits/ 64 <1440000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1516800000 {
++ opp-hz = /bits/ 64 <1516800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1593600000 {
++ opp-hz = /bits/ 64 <1593600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1996800000 {
++ opp-hz = /bits/ 64 <1996800000>;
++ opp-supported-hw = <0x20>;
++ clock-latency-ns = <200000>;
++ };
++ opp-2188800000 {
++ opp-hz = /bits/ 64 <2188800000>;
++ opp-supported-hw = <0x10>;
++ clock-latency-ns = <200000>;
++ };
++ };
++
++ cluster1_opp: opp-table-cluster1 {
++ compatible = "operating-points-v2-kryo-cpu";
++ nvmem-cells = <&speedbin_efuse>;
++ opp-shared;
++
++ opp-307200000 {
++ opp-hz = /bits/ 64 <307200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-384000000 {
++ opp-hz = /bits/ 64 <384000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-460800000 {
++ opp-hz = /bits/ 64 <460800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-537600000 {
++ opp-hz = /bits/ 64 <537600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-614400000 {
++ opp-hz = /bits/ 64 <614400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-691200000 {
++ opp-hz = /bits/ 64 <691200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-748800000 {
++ opp-hz = /bits/ 64 <748800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-825600000 {
++ opp-hz = /bits/ 64 <825600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-902400000 {
++ opp-hz = /bits/ 64 <902400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-979200000 {
++ opp-hz = /bits/ 64 <979200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1056000000 {
++ opp-hz = /bits/ 64 <1056000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1132800000 {
++ opp-hz = /bits/ 64 <1132800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1209600000 {
++ opp-hz = /bits/ 64 <1209600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1286400000 {
++ opp-hz = /bits/ 64 <1286400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1363200000 {
++ opp-hz = /bits/ 64 <1363200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1440000000 {
++ opp-hz = /bits/ 64 <1440000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1516800000 {
++ opp-hz = /bits/ 64 <1516800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1593600000 {
++ opp-hz = /bits/ 64 <1593600000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1670400000 {
++ opp-hz = /bits/ 64 <1670400000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1747200000 {
++ opp-hz = /bits/ 64 <1747200000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1824000000 {
++ opp-hz = /bits/ 64 <1824000000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1900800000 {
++ opp-hz = /bits/ 64 <1900800000>;
++ opp-supported-hw = <0x70>;
++ clock-latency-ns = <200000>;
++ };
++ opp-1977600000 {
++ opp-hz = /bits/ 64 <1977600000>;
++ opp-supported-hw = <0x30>;
++ clock-latency-ns = <200000>;
++ };
++ opp-2054400000 {
++ opp-hz = /bits/ 64 <2054400000>;
++ opp-supported-hw = <0x30>;
++ clock-latency-ns = <200000>;
++ };
++ opp-2150400000 {
++ opp-hz = /bits/ 64 <2150400000>;
++ opp-supported-hw = <0x30>;
++ clock-latency-ns = <200000>;
++ };
++ opp-2246400000 {
++ opp-hz = /bits/ 64 <2246400000>;
++ opp-supported-hw = <0x10>;
++ clock-latency-ns = <200000>;
++ };
++ opp-2342400000 {
++ opp-hz = /bits/ 64 <2342400000>;
++ opp-supported-hw = <0x10>;
++ clock-latency-ns = <200000>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/qcom/pm6350.dtsi b/arch/arm64/boot/dts/qcom/pm6350.dtsi
+index ecf9b99191828..68245d78d2b93 100644
+--- a/arch/arm64/boot/dts/qcom/pm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm6350.dtsi
+@@ -3,6 +3,7 @@
+ * Copyright (c) 2021, Luca Weiss <luca@z3ntu.xyz>
+ */
+
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/spmi/spmi.h>
+
+ &spmi_bus {
+diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
+index d0eefbb516634..d8c9ece20cd9a 100644
+--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
+@@ -163,7 +163,7 @@
+ qcom,pre-scaling = <1 3>;
+ };
+
+- vcoin: vcoin@83 {
++ vcoin: vcoin@85 {
+ reg = <ADC5_VCOIN>;
+ qcom,decimation = <1024>;
+ qcom,pre-scaling = <1 3>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+index 1bd6c7dcd9e91..bfab67f4a7c9c 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+@@ -194,6 +194,12 @@ ap_ts_pen_1v8: &i2c4 {
+ pins = "gpio49", "gpio50", "gpio51", "gpio52";
+ function = "mi2s_1";
+ };
++
++ pinconf {
++ pins = "gpio49", "gpio50", "gpio51", "gpio52";
++ drive-strength = <2>;
++ bias-pull-down;
++ };
+ };
+
+ &ts_reset_l {
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 1bc9091cad2a8..12f01815230bc 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -773,7 +773,7 @@
+ pins = "gpio17", "gpio18", "gpio19";
+ function = "gpio";
+ drive-strength = <2>;
+- bias-no-pull;
++ bias-disable;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+index b5eb8f7eca1d5..b5f11fbcc3004 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+@@ -1436,7 +1436,7 @@ ap_ts_i2c: &i2c14 {
+ config {
+ pins = "gpio126";
+ function = "gpio";
+- bias-no-pull;
++ bias-disable;
+ drive-strength = <2>;
+ output-low;
+ };
+@@ -1446,7 +1446,7 @@ ap_ts_i2c: &i2c14 {
+ config {
+ pins = "gpio126";
+ function = "gpio";
+- bias-no-pull;
++ bias-disable;
+ drive-strength = <2>;
+ output-high;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index c6e2c571b4527..b2eddcd875069 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -1081,7 +1081,7 @@
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+@@ -1255,7 +1255,7 @@
+ reg = <0x60>;
+
+ // CAM3_RST_N
+- enable-gpios = <&tlmm 21 0>;
++ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cam3_default>;
+ gpios = <&tlmm 16 0>,
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
+index 82c27f90d300d..0f470cf1ed1c1 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
+@@ -546,7 +546,7 @@
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index dba7c2693ff50..1cc477c309451 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -126,7 +126,7 @@
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+- gpio = <&tlmm 23 0>;
++ gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+@@ -628,7 +628,7 @@
+ };
+
+ wcd_intr_default: wcd-intr-default {
+- pins = "goui54";
++ pins = "gpio54";
+ function = "gpio";
+ input-enable;
+ bias-pull-down;
+@@ -712,7 +712,7 @@
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index a7af1bed43129..be59a8ba9c1fe 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -772,7 +772,7 @@
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+index b0315eeb13205..f954fe5cb61ab 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+@@ -704,7 +704,7 @@
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+- reset-gpios = <&tlmm 64 0>;
++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index 8c582a9e4ada4..0127224086823 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -458,7 +458,7 @@
+ sdhc_1: mmc@4744000 {
+ compatible = "qcom,sm6125-sdhci", "qcom,sdhci-msm-v5";
+ reg = <0x04744000 0x1000>, <0x04745000 0x1000>;
+- reg-names = "hc", "core";
++ reg-names = "hc", "cqhci";
+
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index d06aefdf3d9ed..76608c1d7f0c4 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -482,6 +482,7 @@
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
++ iommus = <&apps_smmu 0x60 0x0>;
+
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+@@ -928,6 +929,7 @@
+ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
++ iommus = <&apps_smmu 0x560 0x0>;
+
+ clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+ <&gcc GCC_SDCC2_APPS_CLK>,
+@@ -1005,15 +1007,11 @@
+ dp_phy: dp-phy@88ea200 {
+ reg = <0 0x088ea200 0 0x200>,
+ <0 0x088ea400 0 0x200>,
+- <0 0x088eac00 0 0x400>,
++ <0 0x088eaa00 0 0x200>,
+ <0 0x088ea600 0 0x200>,
+- <0 0x088ea800 0 0x200>,
+- <0 0x088eaa00 0 0x100>;
++ <0 0x088ea800 0 0x200>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+- clock-names = "pipe0";
+- clock-output-names = "usb3_phy_pipe_clk_src";
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 916f12b799b79..3df80dde92496 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -2038,11 +2038,11 @@
+ status = "disabled";
+
+ ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
++ reg = <0 0x01d87400 0 0x16c>,
++ <0 0x01d87600 0 0x200>,
++ <0 0x01d87c00 0 0x200>,
++ <0 0x01d87800 0 0x16c>,
++ <0 0x01d87a00 0 0x200>;
+ #phy-cells = <0>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
+index 7ab3627cc347d..a05fe468e0b41 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
+@@ -635,7 +635,7 @@
+ wcd938x: codec {
+ compatible = "qcom,wcd9380-codec";
+ #sound-dai-cells = <1>;
+- reset-gpios = <&tlmm 32 0>;
++ reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-rxtx-supply = <&vreg_s4a_1p8>;
+ vdd-io-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index 5428aab3058dd..e4769dcfaad7b 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -619,7 +619,7 @@
+ pins = "gpio39";
+ function = "gpio";
+ drive-strength = <2>;
+- bias-disabled;
++ bias-disable;
+ input-enable;
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 052b4dbc1ee44..652fb0231da0e 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -2172,11 +2172,11 @@
+ status = "disabled";
+
+ ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
++ reg = <0 0x01d87400 0 0x16c>,
++ <0 0x01d87600 0 0x200>,
++ <0 0x01d87c00 0 0x200>,
++ <0 0x01d87800 0 0x16c>,
++ <0 0x01d87a00 0 0x200>;
+ #phy-cells = <0>;
+ };
+ };
+@@ -2447,7 +2447,7 @@
+ pins = "gpio7";
+ function = "dmic1_data";
+ drive-strength = <2>;
+- pull-down;
++ bias-pull-down;
+ input-enable;
+ };
+ };
+@@ -2884,15 +2884,11 @@
+ dp_phy: dp-phy@88ea200 {
+ reg = <0 0x088ea200 0 0x200>,
+ <0 0x088ea400 0 0x200>,
+- <0 0x088eac00 0 0x400>,
++ <0 0x088eaa00 0 0x200>,
+ <0 0x088ea600 0 0x200>,
+- <0 0x088ea800 0 0x200>,
+- <0 0x088eaa00 0 0x100>;
++ <0 0x088ea800 0 0x200>;
+ #phy-cells = <0>;
+ #clock-cells = <1>;
+- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+- clock-names = "pipe0";
+- clock-output-names = "usb3_phy_pipe_clk_src";
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index d9b08dfc2980d..eace5b2ee3812 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -2142,11 +2142,11 @@
+ status = "disabled";
+
+ ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
++ reg = <0 0x01d87400 0 0x188>,
++ <0 0x01d87600 0 0x200>,
++ <0 0x01d87c00 0 0x200>,
++ <0 0x01d87800 0 0x188>,
++ <0 0x01d87a00 0 0x200>;
+ #phy-cells = <0>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 8a6c0f3e7bb70..ed3e1eff4f58f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -3131,11 +3131,11 @@
+ status = "disabled";
+
+ ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
++ reg = <0 0x01d87400 0 0x188>,
++ <0 0x01d87600 0 0x200>,
++ <0 0x01d87c00 0 0x200>,
++ <0 0x01d87800 0 0x188>,
++ <0 0x01d87a00 0 0x200>;
+ #phy-cells = <0>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+index 384817ffa4deb..d4f3ebfe841ab 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+@@ -442,7 +442,7 @@
+ reg = <0 0xe6540000 0 0x60>;
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 514>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x31>, <&dmac0 0x30>,
+@@ -459,7 +459,7 @@
+ reg = <0 0xe6550000 0 0x60>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 515>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x33>, <&dmac0 0x32>,
+@@ -476,7 +476,7 @@
+ reg = <0 0xe6560000 0 0x60>;
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 516>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x35>, <&dmac0 0x34>,
+@@ -493,7 +493,7 @@
+ reg = <0 0xe66a0000 0 0x60>;
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x37>, <&dmac0 0x36>,
+@@ -522,7 +522,7 @@
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 702>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x51>, <&dmac0 0x50>,
+@@ -539,7 +539,7 @@
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 703>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x53>, <&dmac0 0x52>,
+@@ -556,7 +556,7 @@
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 704>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x57>, <&dmac0 0x56>,
+@@ -573,7 +573,7 @@
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 705>,
+- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x59>, <&dmac0 0x58>,
+diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+index 1c15726cff8bf..4bd3cb107b38b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+@@ -87,7 +87,7 @@
+ reg = <0 0xe6540000 0 96>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 514>,
+- <&cpg CPG_CORE R8A779G0_CLK_S0D3_PER>,
++ <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+index d4cc5459fbb76..4ce0f39446492 100644
+--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+@@ -48,7 +48,7 @@
+ #size-cells = <2>;
+ ranges;
+
+- gic: interrupt-controller@82000000 {
++ gic: interrupt-controller@82010000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
+index d0abb9aa0e9ed..e3852c9463528 100644
+--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
+@@ -55,14 +55,14 @@
+ samsung,pins = "gpf5-0";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ ufs_refclk_out: ufs-refclk-out-pins {
+ samsung,pins = "gpf5-1";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+ };
+
+@@ -239,105 +239,105 @@
+ samsung,pins = "gpb6-1";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ pwm1_out: pwm1-out-pins {
+ samsung,pins = "gpb6-5";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c0_bus: hs-i2c0-bus-pins {
+ samsung,pins = "gpb0-0", "gpb0-1";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c1_bus: hs-i2c1-bus-pins {
+ samsung,pins = "gpb0-2", "gpb0-3";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c2_bus: hs-i2c2-bus-pins {
+ samsung,pins = "gpb0-4", "gpb0-5";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c3_bus: hs-i2c3-bus-pins {
+ samsung,pins = "gpb0-6", "gpb0-7";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c4_bus: hs-i2c4-bus-pins {
+ samsung,pins = "gpb1-0", "gpb1-1";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c5_bus: hs-i2c5-bus-pins {
+ samsung,pins = "gpb1-2", "gpb1-3";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c6_bus: hs-i2c6-bus-pins {
+ samsung,pins = "gpb1-4", "gpb1-5";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ hs_i2c7_bus: hs-i2c7-bus-pins {
+ samsung,pins = "gpb1-6", "gpb1-7";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ uart0_data: uart0-data-pins {
+ samsung,pins = "gpb7-0", "gpb7-1";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ uart1_data: uart1-data-pins {
+ samsung,pins = "gpb7-4", "gpb7-5";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ spi0_bus: spi0-bus-pins {
+ samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ spi1_bus: spi1-bus-pins {
+ samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+
+ spi2_bus: spi2-bus-pins {
+ samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+ samsung,pin-function = <FSD_PIN_FUNC_2>;
+ samsung,pin-pud = <FSD_PIN_PULL_UP>;
+- samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++ samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
+index 6ffbda3624930..c397d02208a08 100644
+--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
+@@ -16,9 +16,9 @@
+ #define FSD_PIN_PULL_UP 3
+
+ #define FSD_PIN_DRV_LV1 0
+-#define FSD_PIN_DRV_LV2 2
+-#define FSD_PIN_DRV_LV3 1
+-#define FSD_PIN_DRV_LV4 3
++#define FSD_PIN_DRV_LV2 1
++#define FSD_PIN_DRV_LV4 2
++#define FSD_PIN_DRV_LV6 3
+
+ #define FSD_PIN_FUNC_INPUT 0
+ #define FSD_PIN_FUNC_OUTPUT 1
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index 8919fede3cd76..ef960386c62cb 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -120,7 +120,6 @@
+ dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+ <&main_udmap 0x4001>;
+ dma-names = "tx", "rx1", "rx2";
+- dma-coherent;
+
+ rng: rng@4e10000 {
+ compatible = "inside-secure,safexcel-eip76";
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+index 43b6cf5791eee..75789c0f82bd3 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+@@ -337,7 +337,6 @@
+ dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+ <&main_udmap 0x4001>;
+ dma-names = "tx", "rx1", "rx2";
+- dma-coherent;
+
+ rng: rng@4e10000 {
+ compatible = "inside-secure,safexcel-eip76";
+diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+index 34e7d577ae13b..c89f28235812a 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+@@ -60,7 +60,7 @@
+ #interrupt-cells = <1>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <148>;
+- ti,interrupt-ranges = <8 360 56>;
++ ti,interrupt-ranges = <8 392 56>;
+ };
+
+ main_pmx0: pinctrl@11c000 {
+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 4d1bfabd1313a..f0644851602cd 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+@@ -65,7 +65,7 @@
+ #interrupt-cells = <1>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <125>;
+- ti,interrupt-ranges = <16 928 16>;
++ ti,interrupt-ranges = <16 960 16>;
+ };
+
+ mcu_conf: syscon@40f00000 {
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index 86eb0bfe3b380..d9144b6e078c8 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -308,13 +308,13 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
+ }
+ #endif
+
+-static inline bool is_ttbr0_addr(unsigned long addr)
++static __always_inline bool is_ttbr0_addr(unsigned long addr)
+ {
+ /* entry assembly clears tags for TTBR0 addrs */
+ return addr < TASK_SIZE;
+ }
+
+-static inline bool is_ttbr1_addr(unsigned long addr)
++static __always_inline bool is_ttbr1_addr(unsigned long addr)
+ {
+ /* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */
+ return arch_kasan_reset_tag(addr) >= PAGE_OFFSET;
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index c33f1fad27450..89628bd370d91 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -353,6 +353,11 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr)
+ return false;
+ }
+
++static bool is_translation_fault(unsigned long esr)
++{
++ return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
++}
++
+ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
+ struct pt_regs *regs)
+ {
+@@ -385,7 +390,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
+ } else if (addr < PAGE_SIZE) {
+ msg = "NULL pointer dereference";
+ } else {
+- if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
++ if (is_translation_fault(esr) &&
++ kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
+ return;
+
+ msg = "paging request";
+diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
+index 6e6756e8fa0a9..86a6e25908664 100644
+--- a/arch/mips/bcm63xx/clk.c
++++ b/arch/mips/bcm63xx/clk.c
+@@ -361,6 +361,8 @@ static struct clk clk_periph = {
+ */
+ int clk_enable(struct clk *clk)
+ {
++ if (!clk)
++ return 0;
+ mutex_lock(&clocks_mutex);
+ clk_enable_unlocked(clk);
+ mutex_unlock(&clocks_mutex);
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+index d09d0769f5496..0fd9ac76eb742 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+@@ -211,7 +211,7 @@ union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port)
+ {
+ union cvmx_helper_link_info result;
+
+- WARN(!octeon_is_simulation(),
++ WARN_ONCE(!octeon_is_simulation(),
+ "Using deprecated link status - please update your DT");
+
+ /* Unless we fix it later, all links are defaulted to down */
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+index 6f49fd9be1f3c..9abfc4bf9bd83 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+@@ -1096,7 +1096,7 @@ union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port)
+ if (index == 0)
+ result = __cvmx_helper_rgmii_link_get(ipd_port);
+ else {
+- WARN(1, "Using deprecated link status - please update your DT");
++ WARN_ONCE(1, "Using deprecated link status - please update your DT");
+ result.s.full_duplex = 1;
+ result.s.link_up = 1;
+ result.s.speed = 1000;
+diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
+index 6bbf082dd149e..79d5bb0e06d63 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7621.h
++++ b/arch/mips/include/asm/mach-ralink/mt7621.h
+@@ -7,10 +7,12 @@
+ #ifndef _MT7621_REGS_H_
+ #define _MT7621_REGS_H_
+
++#define IOMEM(x) ((void __iomem *)(KSEG1ADDR(x)))
++
+ #define MT7621_PALMBUS_BASE 0x1C000000
+ #define MT7621_PALMBUS_SIZE 0x03FFFFFF
+
+-#define MT7621_SYSC_BASE 0x1E000000
++#define MT7621_SYSC_BASE IOMEM(0x1E000000)
+
+ #define SYSC_REG_CHIP_NAME0 0x00
+ #define SYSC_REG_CHIP_NAME1 0x04
+diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c
+index e673603e11e5d..92140edb3ce3e 100644
+--- a/arch/mips/kernel/vpe-cmp.c
++++ b/arch/mips/kernel/vpe-cmp.c
+@@ -75,7 +75,6 @@ ATTRIBUTE_GROUPS(vpe);
+
+ static void vpe_device_release(struct device *cd)
+ {
+- kfree(cd);
+ }
+
+ static struct class vpe_class = {
+@@ -157,6 +156,7 @@ out_dev:
+ device_del(&vpe_device);
+
+ out_class:
++ put_device(&vpe_device);
+ class_unregister(&vpe_class);
+
+ out_chrdev:
+@@ -169,7 +169,7 @@ void __exit vpe_module_exit(void)
+ {
+ struct vpe *v, *n;
+
+- device_del(&vpe_device);
++ device_unregister(&vpe_device);
+ class_unregister(&vpe_class);
+ unregister_chrdev(major, VPE_MODULE_NAME);
+
+diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
+index bad6b0891b2b5..84a82b551ec35 100644
+--- a/arch/mips/kernel/vpe-mt.c
++++ b/arch/mips/kernel/vpe-mt.c
+@@ -313,7 +313,6 @@ ATTRIBUTE_GROUPS(vpe);
+
+ static void vpe_device_release(struct device *cd)
+ {
+- kfree(cd);
+ }
+
+ static struct class vpe_class = {
+@@ -497,6 +496,7 @@ out_dev:
+ device_del(&vpe_device);
+
+ out_class:
++ put_device(&vpe_device);
+ class_unregister(&vpe_class);
+
+ out_chrdev:
+@@ -509,7 +509,7 @@ void __exit vpe_module_exit(void)
+ {
+ struct vpe *v, *n;
+
+- device_del(&vpe_device);
++ device_unregister(&vpe_device);
+ class_unregister(&vpe_class);
+ unregister_chrdev(major, VPE_MODULE_NAME);
+
+diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
+index fb0565bc34fda..bbf5811afbf2c 100644
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -25,6 +25,7 @@
+ #define MT7621_MEM_TEST_PATTERN 0xaa5555aa
+
+ static u32 detect_magic __initdata;
++static struct ralink_soc_info *soc_info_ptr;
+
+ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+ {
+@@ -97,41 +98,83 @@ void __init ralink_of_remap(void)
+ panic("Failed to remap core resources");
+ }
+
+-static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
++static unsigned int __init mt7621_get_soc_name0(void)
++{
++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0);
++}
++
++static unsigned int __init mt7621_get_soc_name1(void)
++{
++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME1);
++}
++
++static bool __init mt7621_soc_valid(void)
++{
++ if (mt7621_get_soc_name0() == MT7621_CHIP_NAME0 &&
++ mt7621_get_soc_name1() == MT7621_CHIP_NAME1)
++ return true;
++ else
++ return false;
++}
++
++static const char __init *mt7621_get_soc_id(void)
++{
++ if (mt7621_soc_valid())
++ return "MT7621";
++ else
++ return "invalid";
++}
++
++static unsigned int __init mt7621_get_soc_rev(void)
++{
++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_REV);
++}
++
++static unsigned int __init mt7621_get_soc_ver(void)
++{
++ return (mt7621_get_soc_rev() >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK;
++}
++
++static unsigned int __init mt7621_get_soc_eco(void)
++{
++ return (mt7621_get_soc_rev() & CHIP_REV_ECO_MASK);
++}
++
++static const char __init *mt7621_get_soc_revision(void)
++{
++ if (mt7621_get_soc_rev() == 1 && mt7621_get_soc_eco() == 1)
++ return "E2";
++ else
++ return "E1";
++}
++
++static int __init mt7621_soc_dev_init(void)
+ {
+ struct soc_device *soc_dev;
+ struct soc_device_attribute *soc_dev_attr;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+- return;
++ return -ENOMEM;
+
+ soc_dev_attr->soc_id = "mt7621";
+ soc_dev_attr->family = "Ralink";
++ soc_dev_attr->revision = mt7621_get_soc_revision();
+
+- if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
+- (rev & CHIP_REV_ECO_MASK) == 1)
+- soc_dev_attr->revision = "E2";
+- else
+- soc_dev_attr->revision = "E1";
+-
+- soc_dev_attr->data = soc_info;
++ soc_dev_attr->data = soc_info_ptr;
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr);
+- return;
++ return PTR_ERR(soc_dev);
+ }
++
++ return 0;
+ }
++device_initcall(mt7621_soc_dev_init);
+
+ void __init prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+- void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+- unsigned char *name = NULL;
+- u32 n0;
+- u32 n1;
+- u32 rev;
+-
+ /* Early detection of CMP support */
+ mips_cm_probe();
+ mips_cpc_probe();
+@@ -154,27 +197,23 @@ void __init prom_soc_init(struct ralink_soc_info *soc_info)
+ __sync();
+ }
+
+- n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+- n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+-
+- if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
+- name = "MT7621";
++ if (mt7621_soc_valid())
+ soc_info->compatible = "mediatek,mt7621-soc";
+- } else {
+- panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+- }
++ else
++ panic("mt7621: unknown SoC, n0:%08x n1:%08x\n",
++ mt7621_get_soc_name0(),
++ mt7621_get_soc_name1());
+ ralink_soc = MT762X_SOC_MT7621AT;
+- rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "MediaTek %s ver:%u eco:%u",
+- name,
+- (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+- (rev & CHIP_REV_ECO_MASK));
++ mt7621_get_soc_id(),
++ mt7621_get_soc_ver(),
++ mt7621_get_soc_eco());
+
+ soc_info->mem_detect = mt7621_memory_detect;
+
+- soc_dev_init(soc_info, rev);
++ soc_info_ptr = soc_info;
+
+ if (!register_cps_smp_ops())
+ return;
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index ea8072acf8d94..01c132bc33d54 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -21,6 +21,7 @@
+ #include <asm/bootinfo.h>
+ #include <asm/addrspace.h>
+ #include <asm/prom.h>
++#include <asm/mach-ralink/ralink_regs.h>
+
+ #include "common.h"
+
+@@ -81,7 +82,8 @@ static int __init plat_of_setup(void)
+ __dt_register_buses(soc_info.compatible, "palmbus");
+
+ /* make sure that the reset controller is setup early */
+- ralink_rst_init();
++ if (ralink_soc != MT762X_SOC_MT7621AT)
++ ralink_rst_init();
+
+ return 0;
+ }
+diff --git a/arch/powerpc/boot/dts/turris1x.dts b/arch/powerpc/boot/dts/turris1x.dts
+index 045af668e9284..e9cda34a140e0 100644
+--- a/arch/powerpc/boot/dts/turris1x.dts
++++ b/arch/powerpc/boot/dts/turris1x.dts
+@@ -69,6 +69,20 @@
+ interrupt-parent = <&gpio>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>, /* GPIO12 - ALERT pin */
+ <13 IRQ_TYPE_LEVEL_LOW>; /* GPIO13 - CRIT pin */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* Local temperature sensor (SA56004ED internal) */
++ channel@0 {
++ reg = <0>;
++ label = "board";
++ };
++
++ /* Remote temperature sensor (D+/D- connected to P2020 CPU Temperature Diode) */
++ channel@1 {
++ reg = <1>;
++ label = "cpu";
++ };
+ };
+
+ /* DDR3 SPD/EEPROM */
+diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
+index 8abae463f6c12..95fd7f9485d55 100644
+--- a/arch/powerpc/include/asm/hvcall.h
++++ b/arch/powerpc/include/asm/hvcall.h
+@@ -79,7 +79,7 @@
+ #define H_NOT_ENOUGH_RESOURCES -44
+ #define H_R_STATE -45
+ #define H_RESCINDED -46
+-#define H_P1 -54
++#define H_ABORTED -54
+ #define H_P2 -55
+ #define H_P3 -56
+ #define H_P4 -57
+@@ -100,7 +100,6 @@
+ #define H_COP_HW -74
+ #define H_STATE -75
+ #define H_IN_USE -77
+-#define H_ABORTED -78
+ #define H_UNSUPPORTED_FLAG_START -256
+ #define H_UNSUPPORTED_FLAG_END -511
+ #define H_MULTI_THREADS_ACTIVE -9005
+diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
+index 082f6d0308a47..8718289c051dd 100644
+--- a/arch/powerpc/perf/callchain.c
++++ b/arch/powerpc/perf/callchain.c
+@@ -61,6 +61,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
+ next_sp = fp[0];
+
+ if (next_sp == sp + STACK_INT_FRAME_SIZE &&
++ validate_sp(sp, current, STACK_INT_FRAME_SIZE) &&
+ fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+ /*
+ * This looks like an interrupt frame for an
+diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h
+index 8965b4463d433..5e86371a20c78 100644
+--- a/arch/powerpc/perf/hv-gpci-requests.h
++++ b/arch/powerpc/perf/hv-gpci-requests.h
+@@ -79,6 +79,7 @@ REQUEST(__field(0, 8, partition_id)
+ )
+ #include I(REQUEST_END)
+
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ /*
+ * Not available for counter_info_version >= 0x8, use
+ * run_instruction_cycles_by_partition(0x100) instead.
+@@ -92,6 +93,7 @@ REQUEST(__field(0, 8, partition_id)
+ __count(0x10, 8, cycles)
+ )
+ #include I(REQUEST_END)
++#endif
+
+ #define REQUEST_NAME system_performance_capabilities
+ #define REQUEST_NUM 0x40
+@@ -103,6 +105,7 @@ REQUEST(__field(0, 1, perf_collect_privileged)
+ )
+ #include I(REQUEST_END)
+
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ #define REQUEST_NAME processor_bus_utilization_abc_links
+ #define REQUEST_NUM 0x50
+ #define REQUEST_IDX_KIND "hw_chip_id=?"
+@@ -194,6 +197,7 @@ REQUEST(__field(0, 4, phys_processor_idx)
+ __count(0x28, 8, instructions_completed)
+ )
+ #include I(REQUEST_END)
++#endif
+
+ /* Processor_core_power_mode (0x95) skipped, no counters */
+ /* Affinity_domain_information_by_virtual_processor (0xA0) skipped,
+diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
+index 5eb60ed5b5e8a..7ff8ff3509f5f 100644
+--- a/arch/powerpc/perf/hv-gpci.c
++++ b/arch/powerpc/perf/hv-gpci.c
+@@ -70,9 +70,9 @@ static const struct attribute_group format_group = {
+ .attrs = format_attrs,
+ };
+
+-static const struct attribute_group event_group = {
++static struct attribute_group event_group = {
+ .name = "events",
+- .attrs = hv_gpci_event_attrs,
++ /* .attrs is set in init */
+ };
+
+ #define HV_CAPS_ATTR(_name, _format) \
+@@ -330,6 +330,7 @@ static int hv_gpci_init(void)
+ int r;
+ unsigned long hret;
+ struct hv_perf_caps caps;
++ struct hv_gpci_request_buffer *arg;
+
+ hv_gpci_assert_offsets_correct();
+
+@@ -353,6 +354,36 @@ static int hv_gpci_init(void)
+ /* sampling not supported */
+ h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+
++ arg = (void *)get_cpu_var(hv_gpci_reqb);
++ memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
++
++ /*
++ * hcall H_GET_PERF_COUNTER_INFO populates the output
++ * counter_info_version value based on the system hypervisor.
++ * Pass the counter request 0x10 corresponds to request type
++ * 'Dispatch_timebase_by_processor', to get the supported
++ * counter_info_version.
++ */
++ arg->params.counter_request = cpu_to_be32(0x10);
++
++ r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
++ virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
++ if (r) {
++ pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r);
++ arg->params.counter_info_version_out = 0x8;
++ }
++
++ /*
++ * Use counter_info_version_out value to assign
++ * required hv-gpci event list.
++ */
++ if (arg->params.counter_info_version_out >= 0x8)
++ event_group.attrs = hv_gpci_event_attrs;
++ else
++ event_group.attrs = hv_gpci_event_attrs_v6;
++
++ put_cpu_var(hv_gpci_reqb);
++
+ r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
+ if (r)
+ return r;
+diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
+index 4d108262bed79..c72020912dea5 100644
+--- a/arch/powerpc/perf/hv-gpci.h
++++ b/arch/powerpc/perf/hv-gpci.h
+@@ -26,6 +26,7 @@ enum {
+ #define REQUEST_FILE "../hv-gpci-requests.h"
+ #define NAME_LOWER hv_gpci
+ #define NAME_UPPER HV_GPCI
++#define ENABLE_EVENTS_COUNTERINFO_V6
+ #include "req-gen/perf.h"
+ #undef REQUEST_FILE
+ #undef NAME_LOWER
+diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h
+index fa9bc804e67af..6b2a59fefffa7 100644
+--- a/arch/powerpc/perf/req-gen/perf.h
++++ b/arch/powerpc/perf/req-gen/perf.h
+@@ -139,6 +139,26 @@ PMU_EVENT_ATTR_STRING( \
+ #define REQUEST_(r_name, r_value, r_idx_1, r_fields) \
+ r_fields
+
++/* Generate event list for platforms with counter_info_version 0x6 or below */
++static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = {
++#include REQUEST_FILE
++ NULL
++};
++
++/*
++ * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci
++ * events were deprecated for platform firmware that supports
++ * counter_info_version 0x8 or above.
++ * Those deprecated events are still part of platform firmware that
++ * support counter_info_version 0x6 and below. As per the getPerfCountInfo
++ * v1.018 documentation there is no counter_info_version 0x7.
++ * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of
++ * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms
++ * that supports counter_info_version 0x8 or above.
++ */
++#undef ENABLE_EVENTS_COUNTERINFO_V6
++
++/* Generate event list for platforms with counter_info_version 0x8 or above*/
+ static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
+ #include REQUEST_FILE
+ NULL
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+index 48038aaedbd36..2875c206ac0f8 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+@@ -531,6 +531,7 @@ static int mpc52xx_lpbfifo_probe(struct platform_device *op)
+ err_bcom_rx_irq:
+ bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
+ err_bcom_rx:
++ free_irq(lpbfifo.irq, &lpbfifo);
+ err_irq:
+ iounmap(lpbfifo.regs);
+ lpbfifo.regs = NULL;
+diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+index bb8caa5071f8c..dddb5c6f81209 100644
+--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
++++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+@@ -107,7 +107,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+
+ goto next;
+ unreg:
+- platform_device_del(pdev);
++ platform_device_put(pdev);
+ err:
+ pr_err("%pOF: registration failed\n", np);
+ next:
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index 8e40ccac0f44e..e5a58a9b2fe9f 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -848,16 +848,7 @@ static int __init eeh_pseries_init(void)
+ }
+
+ /* Initialize error log size */
+- eeh_error_buf_size = rtas_token("rtas-error-log-max");
+- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
+- pr_info("%s: unknown EEH error log size\n",
+- __func__);
+- eeh_error_buf_size = 1024;
+- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
+- pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
+- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
+- eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
+- }
++ eeh_error_buf_size = rtas_get_error_log_max();
+
+ /* Set EEH probe mode */
+ eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
+diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
+index f4b5b5a64db3d..63a1e1fe01851 100644
+--- a/arch/powerpc/platforms/pseries/plpks.c
++++ b/arch/powerpc/platforms/pseries/plpks.c
+@@ -75,7 +75,7 @@ static int pseries_status_to_err(int rc)
+ case H_FUNCTION:
+ err = -ENXIO;
+ break;
+- case H_P1:
++ case H_PARAMETER:
+ case H_P2:
+ case H_P3:
+ case H_P4:
+@@ -111,7 +111,7 @@ static int pseries_status_to_err(int rc)
+ err = -EEXIST;
+ break;
+ case H_ABORTED:
+- err = -EINTR;
++ err = -EIO;
+ break;
+ default:
+ err = -EINVAL;
+@@ -366,22 +366,24 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
+ {
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+ struct plpks_auth *auth;
+- struct label *label;
++ struct label *label = NULL;
+ u8 *output;
+ int rc;
+
+ if (var->namelen > MAX_NAME_SIZE)
+ return -EINVAL;
+
+- auth = construct_auth(PKS_OS_OWNER);
++ auth = construct_auth(consumer);
+ if (IS_ERR(auth))
+ return PTR_ERR(auth);
+
+- label = construct_label(var->component, var->os, var->name,
+- var->namelen);
+- if (IS_ERR(label)) {
+- rc = PTR_ERR(label);
+- goto out_free_auth;
++ if (consumer == PKS_OS_OWNER) {
++ label = construct_label(var->component, var->os, var->name,
++ var->namelen);
++ if (IS_ERR(label)) {
++ rc = PTR_ERR(label);
++ goto out_free_auth;
++ }
+ }
+
+ output = kzalloc(maxobjsize, GFP_KERNEL);
+@@ -390,9 +392,15 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
+ goto out_free_label;
+ }
+
+- rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
+- virt_to_phys(label), label->size, virt_to_phys(output),
+- maxobjsize);
++ if (consumer == PKS_OS_OWNER)
++ rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
++ virt_to_phys(label), label->size, virt_to_phys(output),
++ maxobjsize);
++ else
++ rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
++ virt_to_phys(var->name), var->namelen, virt_to_phys(output),
++ maxobjsize);
++
+
+ if (rc != H_SUCCESS) {
+ pr_err("Failed to read variable %s for component %s with error %d\n",
+diff --git a/arch/powerpc/platforms/pseries/plpks.h b/arch/powerpc/platforms/pseries/plpks.h
+index c6a291367bb13..275ccd86bfb5e 100644
+--- a/arch/powerpc/platforms/pseries/plpks.h
++++ b/arch/powerpc/platforms/pseries/plpks.h
+@@ -17,7 +17,7 @@
+ #define WORLDREADABLE 0x08000000
+ #define SIGNEDUPDATE 0x01000000
+
+-#define PLPKS_VAR_LINUX 0x01
++#define PLPKS_VAR_LINUX 0x02
+ #define PLPKS_VAR_COMMON 0x04
+
+ struct plpks_var {
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
+index e2c8f93b535ba..e454192643910 100644
+--- a/arch/powerpc/sysdev/xive/spapr.c
++++ b/arch/powerpc/sysdev/xive/spapr.c
+@@ -439,6 +439,7 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
+
+ data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift);
+ if (!data->trig_mmio) {
++ iounmap(data->eoi_mmio);
+ pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq);
+ return -ENOMEM;
+ }
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index 26ef3388c24c4..df91dfc7ff727 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -1525,9 +1525,9 @@ bpt_cmds(void)
+ cmd = inchar();
+
+ switch (cmd) {
+- static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
+- int mode;
+- case 'd': /* bd - hardware data breakpoint */
++ case 'd': { /* bd - hardware data breakpoint */
++ static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
++ int mode;
+ if (xmon_is_ro) {
+ printf(xmon_ro_msg);
+ break;
+@@ -1560,6 +1560,7 @@ bpt_cmds(void)
+
+ force_enable_xmon();
+ break;
++ }
+
+ case 'i': /* bi - hardware instr breakpoint */
+ if (xmon_is_ro) {
+diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
+index a5c2ca1d1cd8b..ec19d6afc8965 100644
+--- a/arch/riscv/include/asm/hugetlb.h
++++ b/arch/riscv/include/asm/hugetlb.h
+@@ -5,4 +5,10 @@
+ #include <asm-generic/hugetlb.h>
+ #include <asm/page.h>
+
++static inline void arch_clear_hugepage_flags(struct page *page)
++{
++ clear_bit(PG_dcache_clean, &page->flags);
++}
++#define arch_clear_hugepage_flags arch_clear_hugepage_flags
++
+ #endif /* _ASM_RISCV_HUGETLB_H */
+diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
+index 92080a2279372..42497d487a174 100644
+--- a/arch/riscv/include/asm/io.h
++++ b/arch/riscv/include/asm/io.h
+@@ -135,4 +135,9 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
+
+ #include <asm-generic/io.h>
+
++#ifdef CONFIG_MMU
++#define arch_memremap_wb(addr, size) \
++ ((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL))
++#endif
++
+ #endif /* _ASM_RISCV_IO_H */
+diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
+index dc42375c23571..42a042c0e13ed 100644
+--- a/arch/riscv/include/asm/pgtable-64.h
++++ b/arch/riscv/include/asm/pgtable-64.h
+@@ -25,7 +25,11 @@ extern bool pgtable_l5_enabled;
+ #define PGDIR_MASK (~(PGDIR_SIZE - 1))
+
+ /* p4d is folded into pgd in case of 4-level page table */
+-#define P4D_SHIFT 39
++#define P4D_SHIFT_L3 30
++#define P4D_SHIFT_L4 39
++#define P4D_SHIFT_L5 39
++#define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \
++ (pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3))
+ #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT)
+ #define P4D_MASK (~(P4D_SIZE - 1))
+
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
+index 186abd146eaff..3221a9e5f3724 100644
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -263,12 +263,11 @@ ret_from_exception:
+ #endif
+ bnez s0, resume_kernel
+
+-resume_userspace:
+ /* Interrupts must be disabled here so flags are checked atomically */
+ REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */
+ andi s1, s0, _TIF_WORK_MASK
+- bnez s1, work_pending
+-
++ bnez s1, resume_userspace_slow
++resume_userspace:
+ #ifdef CONFIG_CONTEXT_TRACKING_USER
+ call user_enter_callable
+ #endif
+@@ -368,19 +367,12 @@ resume_kernel:
+ j restore_all
+ #endif
+
+-work_pending:
++resume_userspace_slow:
+ /* Enter slow path for supplementary processing */
+- la ra, ret_from_exception
+- andi s1, s0, _TIF_NEED_RESCHED
+- bnez s1, work_resched
+-work_notifysig:
+- /* Handle pending signals and notify-resume requests */
+- csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */
+ move a0, sp /* pt_regs */
+ move a1, s0 /* current_thread_info->flags */
+- tail do_notify_resume
+-work_resched:
+- tail schedule
++ call do_work_pending
++ j resume_userspace
+
+ /* Slow paths for ptrace. */
+ handle_syscall_trace_enter:
+diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
+index 5c591123c4409..bfb2afa4135f8 100644
+--- a/arch/riscv/kernel/signal.c
++++ b/arch/riscv/kernel/signal.c
+@@ -313,19 +313,27 @@ static void do_signal(struct pt_regs *regs)
+ }
+
+ /*
+- * notification of userspace execution resumption
+- * - triggered by the _TIF_WORK_MASK flags
++ * Handle any pending work on the resume-to-userspace path, as indicated by
++ * _TIF_WORK_MASK. Entered from assembly with IRQs off.
+ */
+-asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
+- unsigned long thread_info_flags)
++asmlinkage __visible void do_work_pending(struct pt_regs *regs,
++ unsigned long thread_info_flags)
+ {
+- if (thread_info_flags & _TIF_UPROBE)
+- uprobe_notify_resume(regs);
+-
+- /* Handle pending signal delivery */
+- if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+- do_signal(regs);
+-
+- if (thread_info_flags & _TIF_NOTIFY_RESUME)
+- resume_user_mode_work(regs);
++ do {
++ if (thread_info_flags & _TIF_NEED_RESCHED) {
++ schedule();
++ } else {
++ local_irq_enable();
++ if (thread_info_flags & _TIF_UPROBE)
++ uprobe_notify_resume(regs);
++ /* Handle pending signal delivery */
++ if (thread_info_flags & (_TIF_SIGPENDING |
++ _TIF_NOTIFY_SIGNAL))
++ do_signal(regs);
++ if (thread_info_flags & _TIF_NOTIFY_RESUME)
++ resume_user_mode_work(regs);
++ }
++ local_irq_disable();
++ thread_info_flags = read_thread_flags();
++ } while (thread_info_flags & _TIF_WORK_MASK);
+ }
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 6e8822446069e..026b458331582 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -211,7 +211,7 @@ static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],
+ * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used
+ * to get per-cpu overflow stack(get_overflow_stack).
+ */
+-long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)];
++long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16);
+ asmlinkage unsigned long get_overflow_stack(void)
+ {
+ return (unsigned long)this_cpu_ptr(overflow_stack) +
+diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
+index f692c0716aa7a..aa7ae63270449 100644
+--- a/arch/riscv/kvm/vcpu.c
++++ b/arch/riscv/kvm/vcpu.c
+@@ -286,12 +286,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
+ if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
+ return -EFAULT;
+
+- /* This ONE REG interface is only defined for single letter extensions */
+- if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
+- return -EINVAL;
+-
+ switch (reg_num) {
+ case KVM_REG_RISCV_CONFIG_REG(isa):
++ /*
++ * This ONE REG interface is only defined for
++ * single letter extensions.
++ */
++ if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
++ return -EINVAL;
++
+ if (!vcpu->arch.ran_atleast_once) {
+ /* Ignore the enable/disable request for certain extensions */
+ for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
+diff --git a/arch/riscv/mm/physaddr.c b/arch/riscv/mm/physaddr.c
+index 19cf25a74ee29..9b18bda74154e 100644
+--- a/arch/riscv/mm/physaddr.c
++++ b/arch/riscv/mm/physaddr.c
+@@ -22,7 +22,7 @@ EXPORT_SYMBOL(__virt_to_phys);
+ phys_addr_t __phys_addr_symbol(unsigned long x)
+ {
+ unsigned long kernel_start = kernel_map.virt_addr;
+- unsigned long kernel_end = (unsigned long)_end;
++ unsigned long kernel_end = kernel_start + kernel_map.size;
+
+ /*
+ * Boundary checking aginst the kernel image mapping.
+diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
+index 00df3a8f92acd..f2417ac54edd6 100644
+--- a/arch/riscv/net/bpf_jit_comp64.c
++++ b/arch/riscv/net/bpf_jit_comp64.c
+@@ -136,6 +136,25 @@ static bool in_auipc_jalr_range(s64 val)
+ val < ((1L << 31) - (1L << 11));
+ }
+
++/* Emit fixed-length instructions for address */
++static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx)
++{
++ u64 ip = (u64)(ctx->insns + ctx->ninsns);
++ s64 off = addr - ip;
++ s64 upper = (off + (1 << 11)) >> 12;
++ s64 lower = off & 0xfff;
++
++ if (extra_pass && !in_auipc_jalr_range(off)) {
++ pr_err("bpf-jit: target offset 0x%llx is out of range\n", off);
++ return -ERANGE;
++ }
++
++ emit(rv_auipc(rd, upper), ctx);
++ emit(rv_addi(rd, rd, lower), ctx);
++ return 0;
++}
++
++/* Emit variable-length instructions for 32-bit and 64-bit imm */
+ static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
+ {
+ /* Note that the immediate from the add is sign-extended,
+@@ -1050,7 +1069,15 @@ out_be:
+ u64 imm64;
+
+ imm64 = (u64)insn1.imm << 32 | (u32)imm;
+- emit_imm(rd, imm64, ctx);
++ if (bpf_pseudo_func(insn)) {
++ /* fixed-length insns for extra jit pass */
++ ret = emit_addr(rd, imm64, extra_pass, ctx);
++ if (ret)
++ return ret;
++ } else {
++ emit_imm(rd, imm64, ctx);
++ }
++
+ return 1;
+ }
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 4728d3f5d5c40..3fec0e9d92410 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -450,8 +450,8 @@ config X86_X2APIC
+
+ Some Intel systems circa 2022 and later are locked into x2APIC mode
+ and can not fall back to the legacy APIC modes if SGX or TDX are
+- enabled in the BIOS. They will be unable to boot without enabling
+- this option.
++ enabled in the BIOS. They will boot with very reduced functionality
++ without enabling this option.
+
+ If you don't know what to do here, say N.
+
+diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
+index 1ef4f7861e2ec..1f4869227efb9 100644
+--- a/arch/x86/events/intel/uncore_snb.c
++++ b/arch/x86/events/intel/uncore_snb.c
+@@ -1338,6 +1338,7 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box,
+ /* MCHBAR is disabled */
+ if (!(mch_bar & BIT(0))) {
+ pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n");
++ pci_dev_put(pdev);
+ return;
+ }
+ mch_bar &= ~BIT(0);
+@@ -1352,6 +1353,8 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box,
+ box->io_addr = ioremap(addr, type->mmio_map_size);
+ if (!box->io_addr)
+ pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
++
++ pci_dev_put(pdev);
+ }
+
+ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index ed869443efb21..fcd95e93f479a 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -2891,6 +2891,7 @@ static bool hswep_has_limit_sbox(unsigned int device)
+ return false;
+
+ pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
++ pci_dev_put(dev);
+ if (!hswep_get_chop(capid4))
+ return true;
+
+@@ -4492,6 +4493,8 @@ static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_map
+ type->topology = NULL;
+ }
+
++ pci_dev_put(dev);
++
+ return ret;
+ }
+
+@@ -4857,6 +4860,8 @@ static int snr_uncore_mmio_map(struct intel_uncore_box *box,
+
+ addr += box_ctl;
+
++ pci_dev_put(pdev);
++
+ box->io_addr = ioremap(addr, type->mmio_map_size);
+ if (!box->io_addr) {
+ pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index a0165df3c4d8c..d03561b2fffe6 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -536,8 +536,6 @@ void hyperv_cleanup(void)
+ {
+ union hv_x64_msr_hypercall_contents hypercall_msr;
+
+- unregister_syscore_ops(&hv_syscore_ops);
+-
+ /* Reset our OS id */
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+ hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
+diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
+index 3415321c8240c..3216da7074bad 100644
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -249,7 +249,6 @@ static inline u64 native_x2apic_icr_read(void)
+ extern int x2apic_mode;
+ extern int x2apic_phys;
+ extern void __init x2apic_set_max_apicid(u32 apicid);
+-extern void __init check_x2apic(void);
+ extern void x2apic_setup(void);
+ static inline int x2apic_enabled(void)
+ {
+@@ -258,13 +257,13 @@ static inline int x2apic_enabled(void)
+
+ #define x2apic_supported() (boot_cpu_has(X86_FEATURE_X2APIC))
+ #else /* !CONFIG_X86_X2APIC */
+-static inline void check_x2apic(void) { }
+ static inline void x2apic_setup(void) { }
+ static inline int x2apic_enabled(void) { return 0; }
+
+ #define x2apic_mode (0)
+ #define x2apic_supported() (0)
+ #endif /* !CONFIG_X86_X2APIC */
++extern void __init check_x2apic(void);
+
+ struct irq_data;
+
+diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
+index fd6f6e5b755a7..a336feef0af14 100644
+--- a/arch/x86/include/asm/realmode.h
++++ b/arch/x86/include/asm/realmode.h
+@@ -91,6 +91,7 @@ static inline void set_real_mode_mem(phys_addr_t mem)
+
+ void reserve_real_mode(void);
+ void load_trampoline_pgtable(void);
++void init_real_mode(void);
+
+ #endif /* __ASSEMBLY__ */
+
+diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
+index e9170457697e4..c1c8c581759d6 100644
+--- a/arch/x86/include/asm/x86_init.h
++++ b/arch/x86/include/asm/x86_init.h
+@@ -285,6 +285,8 @@ struct x86_hyper_runtime {
+ * possible in x86_early_init_platform_quirks() by
+ * only using the current x86_hardware_subarch
+ * semantics.
++ * @realmode_reserve: reserve memory for realmode trampoline
++ * @realmode_init: initialize realmode trampoline
+ * @hyper: x86 hypervisor specific runtime callbacks
+ */
+ struct x86_platform_ops {
+@@ -301,6 +303,8 @@ struct x86_platform_ops {
+ void (*apic_post_init)(void);
+ struct x86_legacy_features legacy;
+ void (*set_legacy_features)(void);
++ void (*realmode_reserve)(void);
++ void (*realmode_init)(void);
+ struct x86_hyper_runtime hyper;
+ struct x86_guest guest;
+ };
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index c6876d3ea4b17..20d9a604da7c4 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -1931,16 +1931,19 @@ void __init check_x2apic(void)
+ }
+ }
+ #else /* CONFIG_X86_X2APIC */
+-static int __init validate_x2apic(void)
++void __init check_x2apic(void)
+ {
+ if (!apic_is_x2apic_enabled())
+- return 0;
++ return;
+ /*
+- * Checkme: Can we simply turn off x2apic here instead of panic?
++ * Checkme: Can we simply turn off x2APIC here instead of disabling the APIC?
+ */
+- panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n");
++ pr_err("Kernel does not support x2APIC, please recompile with CONFIG_X86_X2APIC.\n");
++ pr_err("Disabling APIC, expect reduced performance and functionality.\n");
++
++ disable_apic = 1;
++ setup_clear_cpu_cap(X86_FEATURE_APIC);
+ }
+-early_initcall(validate_x2apic);
+
+ static inline void try_to_enable_x2apic(int remap_mode) { }
+ static inline void __x2apic_enable(void) { }
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
+index 2d7ea5480ec33..4278996504833 100644
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -1034,8 +1034,32 @@ static const struct {
+
+ static struct ratelimit_state bld_ratelimit;
+
++static unsigned int sysctl_sld_mitigate = 1;
+ static DEFINE_SEMAPHORE(buslock_sem);
+
++#ifdef CONFIG_PROC_SYSCTL
++static struct ctl_table sld_sysctls[] = {
++ {
++ .procname = "split_lock_mitigate",
++ .data = &sysctl_sld_mitigate,
++ .maxlen = sizeof(unsigned int),
++ .mode = 0644,
++ .proc_handler = proc_douintvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
++ {}
++};
++
++static int __init sld_mitigate_sysctl_init(void)
++{
++ register_sysctl_init("kernel", sld_sysctls);
++ return 0;
++}
++
++late_initcall(sld_mitigate_sysctl_init);
++#endif
++
+ static inline bool match_option(const char *arg, int arglen, const char *opt)
+ {
+ int len = strlen(opt), ratelimit;
+@@ -1146,12 +1170,20 @@ static void split_lock_init(void)
+ split_lock_verify_msr(sld_state != sld_off);
+ }
+
+-static void __split_lock_reenable(struct work_struct *work)
++static void __split_lock_reenable_unlock(struct work_struct *work)
+ {
+ sld_update_msr(true);
+ up(&buslock_sem);
+ }
+
++static DECLARE_DELAYED_WORK(sl_reenable_unlock, __split_lock_reenable_unlock);
++
++static void __split_lock_reenable(struct work_struct *work)
++{
++ sld_update_msr(true);
++}
++static DECLARE_DELAYED_WORK(sl_reenable, __split_lock_reenable);
++
+ /*
+ * If a CPU goes offline with pending delayed work to re-enable split lock
+ * detection then the delayed work will be executed on some other CPU. That
+@@ -1169,10 +1201,9 @@ static int splitlock_cpu_offline(unsigned int cpu)
+ return 0;
+ }
+
+-static DECLARE_DELAYED_WORK(split_lock_reenable, __split_lock_reenable);
+-
+ static void split_lock_warn(unsigned long ip)
+ {
++ struct delayed_work *work;
+ int cpu;
+
+ if (!current->reported_split_lock)
+@@ -1180,14 +1211,26 @@ static void split_lock_warn(unsigned long ip)
+ current->comm, current->pid, ip);
+ current->reported_split_lock = 1;
+
+- /* misery factor #1, sleep 10ms before trying to execute split lock */
+- if (msleep_interruptible(10) > 0)
+- return;
+- /* Misery factor #2, only allow one buslocked disabled core at a time */
+- if (down_interruptible(&buslock_sem) == -EINTR)
+- return;
++ if (sysctl_sld_mitigate) {
++ /*
++ * misery factor #1:
++ * sleep 10ms before trying to execute split lock.
++ */
++ if (msleep_interruptible(10) > 0)
++ return;
++ /*
++ * Misery factor #2:
++ * only allow one buslocked disabled core at a time.
++ */
++ if (down_interruptible(&buslock_sem) == -EINTR)
++ return;
++ work = &sl_reenable_unlock;
++ } else {
++ work = &sl_reenable;
++ }
++
+ cpu = get_cpu();
+- schedule_delayed_work_on(cpu, &split_lock_reenable, 2);
++ schedule_delayed_work_on(cpu, work, 2);
+
+ /* Disable split lock detection on this CPU to make progress */
+ sld_update_msr(false);
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 8bdeae2fc3091..6942a3d8b578c 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -677,11 +677,15 @@ const struct vm_operations_struct sgx_vm_ops = {
+ void sgx_encl_release(struct kref *ref)
+ {
+ struct sgx_encl *encl = container_of(ref, struct sgx_encl, refcount);
++ unsigned long max_page_index = PFN_DOWN(encl->base + encl->size - 1);
+ struct sgx_va_page *va_page;
+ struct sgx_encl_page *entry;
+- unsigned long index;
++ unsigned long count = 0;
++
++ XA_STATE(xas, &encl->page_array, PFN_DOWN(encl->base));
+
+- xa_for_each(&encl->page_array, index, entry) {
++ xas_lock(&xas);
++ xas_for_each(&xas, entry, max_page_index) {
+ if (entry->epc_page) {
+ /*
+ * The page and its radix tree entry cannot be freed
+@@ -696,9 +700,20 @@ void sgx_encl_release(struct kref *ref)
+ }
+
+ kfree(entry);
+- /* Invoke scheduler to prevent soft lockups. */
+- cond_resched();
++ /*
++ * Invoke scheduler on every XA_CHECK_SCHED iteration
++ * to prevent soft lockups.
++ */
++ if (!(++count % XA_CHECK_SCHED)) {
++ xas_pause(&xas);
++ xas_unlock(&xas);
++
++ cond_resched();
++
++ xas_lock(&xas);
++ }
+ }
++ xas_unlock(&xas);
+
+ xa_destroy(&encl->page_array);
+
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 216fee7144eef..892609cde4a20 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1175,7 +1175,7 @@ void __init setup_arch(char **cmdline_p)
+ * Moreover, on machines with SandyBridge graphics or in setups that use
+ * crashkernel the entire 1M is reserved anyway.
+ */
+- reserve_real_mode();
++ x86_platform.realmode_reserve();
+
+ init_mem_mapping();
+
+diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
+index b63cf8f7745ee..6c07f6daaa227 100644
+--- a/arch/x86/kernel/uprobes.c
++++ b/arch/x86/kernel/uprobes.c
+@@ -722,8 +722,9 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+ switch (opc1) {
+ case 0xeb: /* jmp 8 */
+ case 0xe9: /* jmp 32 */
+- case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */
+ break;
++ case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */
++ goto setup;
+
+ case 0xe8: /* call relative */
+ branch_clear_offset(auprobe, insn);
+@@ -753,6 +754,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+ return -ENOTSUPP;
+ }
+
++setup:
+ auprobe->branch.opc1 = opc1;
+ auprobe->branch.ilen = insn->length;
+ auprobe->branch.offs = insn->immediate.value;
+diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
+index e84ee5cdbd8c6..3a164fb0d4c3e 100644
+--- a/arch/x86/kernel/x86_init.c
++++ b/arch/x86/kernel/x86_init.c
+@@ -25,6 +25,7 @@
+ #include <asm/iommu.h>
+ #include <asm/mach_traps.h>
+ #include <asm/irqdomain.h>
++#include <asm/realmode.h>
+
+ void x86_init_noop(void) { }
+ void __init x86_init_uint_noop(unsigned int unused) { }
+@@ -145,6 +146,8 @@ struct x86_platform_ops x86_platform __ro_after_init = {
+ .get_nmi_reason = default_get_nmi_reason,
+ .save_sched_clock_state = tsc_save_sched_clock_state,
+ .restore_sched_clock_state = tsc_restore_sched_clock_state,
++ .realmode_reserve = reserve_real_mode,
++ .realmode_init = init_real_mode,
+ .hyper.pin_vcpu = x86_op_int_noop,
+
+ .guest = {
+diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
+index 41d7669a97ad1..af565816d2ba6 100644
+--- a/arch/x86/realmode/init.c
++++ b/arch/x86/realmode/init.c
+@@ -200,14 +200,18 @@ static void __init set_real_mode_permissions(void)
+ set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT);
+ }
+
+-static int __init init_real_mode(void)
++void __init init_real_mode(void)
+ {
+ if (!real_mode_header)
+ panic("Real mode trampoline was not allocated");
+
+ setup_real_mode();
+ set_real_mode_permissions();
++}
+
++static int __init do_init_real_mode(void)
++{
++ x86_platform.realmode_init();
+ return 0;
+ }
+-early_initcall(init_real_mode);
++early_initcall(do_init_real_mode);
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 9b1a58dda935b..807ab4fbe2c42 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -1224,6 +1224,8 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
+ xen_vcpu_info_reset(0);
+
+ x86_platform.get_nmi_reason = xen_get_nmi_reason;
++ x86_platform.realmode_reserve = x86_init_noop;
++ x86_platform.realmode_init = x86_init_noop;
+
+ x86_init.resources.memory_setup = xen_memory_setup;
+ x86_init.irqs.intr_mode_select = x86_init_noop;
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index c3e1f9a7d43aa..4b0d6fff88de5 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -32,30 +32,30 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
+
+ void xen_smp_intr_free(unsigned int cpu)
+ {
++ kfree(per_cpu(xen_resched_irq, cpu).name);
++ per_cpu(xen_resched_irq, cpu).name = NULL;
+ if (per_cpu(xen_resched_irq, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL);
+ per_cpu(xen_resched_irq, cpu).irq = -1;
+- kfree(per_cpu(xen_resched_irq, cpu).name);
+- per_cpu(xen_resched_irq, cpu).name = NULL;
+ }
++ kfree(per_cpu(xen_callfunc_irq, cpu).name);
++ per_cpu(xen_callfunc_irq, cpu).name = NULL;
+ if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL);
+ per_cpu(xen_callfunc_irq, cpu).irq = -1;
+- kfree(per_cpu(xen_callfunc_irq, cpu).name);
+- per_cpu(xen_callfunc_irq, cpu).name = NULL;
+ }
++ kfree(per_cpu(xen_debug_irq, cpu).name);
++ per_cpu(xen_debug_irq, cpu).name = NULL;
+ if (per_cpu(xen_debug_irq, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL);
+ per_cpu(xen_debug_irq, cpu).irq = -1;
+- kfree(per_cpu(xen_debug_irq, cpu).name);
+- per_cpu(xen_debug_irq, cpu).name = NULL;
+ }
++ kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
++ per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+ if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq,
+ NULL);
+ per_cpu(xen_callfuncsingle_irq, cpu).irq = -1;
+- kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
+- per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+ }
+ }
+
+@@ -65,6 +65,7 @@ int xen_smp_intr_init(unsigned int cpu)
+ char *resched_name, *callfunc_name, *debug_name;
+
+ resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu);
++ per_cpu(xen_resched_irq, cpu).name = resched_name;
+ rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
+ cpu,
+ xen_reschedule_interrupt,
+@@ -74,9 +75,9 @@ int xen_smp_intr_init(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_resched_irq, cpu).irq = rc;
+- per_cpu(xen_resched_irq, cpu).name = resched_name;
+
+ callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
++ per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+ rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
+ cpu,
+ xen_call_function_interrupt,
+@@ -86,10 +87,10 @@ int xen_smp_intr_init(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_callfunc_irq, cpu).irq = rc;
+- per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+
+ if (!xen_fifo_events) {
+ debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
++ per_cpu(xen_debug_irq, cpu).name = debug_name;
+ rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu,
+ xen_debug_interrupt,
+ IRQF_PERCPU | IRQF_NOBALANCING,
+@@ -97,10 +98,10 @@ int xen_smp_intr_init(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_debug_irq, cpu).irq = rc;
+- per_cpu(xen_debug_irq, cpu).name = debug_name;
+ }
+
+ callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
++ per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+ rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
+ cpu,
+ xen_call_function_single_interrupt,
+@@ -110,7 +111,6 @@ int xen_smp_intr_init(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_callfuncsingle_irq, cpu).irq = rc;
+- per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+
+ return 0;
+
+diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
+index ba7af2eca755b..cd80f8422e173 100644
+--- a/arch/x86/xen/smp_pv.c
++++ b/arch/x86/xen/smp_pv.c
+@@ -97,18 +97,18 @@ asmlinkage __visible void cpu_bringup_and_idle(void)
+
+ void xen_smp_intr_free_pv(unsigned int cpu)
+ {
++ kfree(per_cpu(xen_irq_work, cpu).name);
++ per_cpu(xen_irq_work, cpu).name = NULL;
+ if (per_cpu(xen_irq_work, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL);
+ per_cpu(xen_irq_work, cpu).irq = -1;
+- kfree(per_cpu(xen_irq_work, cpu).name);
+- per_cpu(xen_irq_work, cpu).name = NULL;
+ }
+
++ kfree(per_cpu(xen_pmu_irq, cpu).name);
++ per_cpu(xen_pmu_irq, cpu).name = NULL;
+ if (per_cpu(xen_pmu_irq, cpu).irq >= 0) {
+ unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL);
+ per_cpu(xen_pmu_irq, cpu).irq = -1;
+- kfree(per_cpu(xen_pmu_irq, cpu).name);
+- per_cpu(xen_pmu_irq, cpu).name = NULL;
+ }
+ }
+
+@@ -118,6 +118,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ char *callfunc_name, *pmu_name;
+
+ callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
++ per_cpu(xen_irq_work, cpu).name = callfunc_name;
+ rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
+ cpu,
+ xen_irq_work_interrupt,
+@@ -127,10 +128,10 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_irq_work, cpu).irq = rc;
+- per_cpu(xen_irq_work, cpu).name = callfunc_name;
+
+ if (is_xen_pmu) {
+ pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
++ per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+ rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
+ xen_pmu_irq_handler,
+ IRQF_PERCPU|IRQF_NOBALANCING,
+@@ -138,7 +139,6 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ if (rc < 0)
+ goto fail;
+ per_cpu(xen_pmu_irq, cpu).irq = rc;
+- per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+ }
+
+ return 0;
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
+index 043c73dfd2c98..5c6fc16e4b925 100644
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -75,6 +75,7 @@ void xen_init_lock_cpu(int cpu)
+ cpu, per_cpu(lock_kicker_irq, cpu));
+
+ name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
++ per_cpu(irq_name, cpu) = name;
+ irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
+ cpu,
+ dummy_handler,
+@@ -85,7 +86,6 @@ void xen_init_lock_cpu(int cpu)
+ if (irq >= 0) {
+ disable_irq(irq); /* make sure it's never delivered */
+ per_cpu(lock_kicker_irq, cpu) = irq;
+- per_cpu(irq_name, cpu) = name;
+ }
+
+ printk("cpu %d spinlock event irq %d\n", cpu, irq);
+@@ -98,6 +98,8 @@ void xen_uninit_lock_cpu(int cpu)
+ if (!xen_pvspin)
+ return;
+
++ kfree(per_cpu(irq_name, cpu));
++ per_cpu(irq_name, cpu) = NULL;
+ /*
+ * When booting the kernel with 'mitigations=auto,nosmt', the secondary
+ * CPUs are not activated, and lock_kicker_irq is not initialized.
+@@ -108,8 +110,6 @@ void xen_uninit_lock_cpu(int cpu)
+
+ unbind_from_irqhandler(irq, NULL);
+ per_cpu(lock_kicker_irq, cpu) = -1;
+- kfree(per_cpu(irq_name, cpu));
+- per_cpu(irq_name, cpu) = NULL;
+ }
+
+ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen);
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index c740b41fe0a49..528ca21044a57 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq);
+
+ void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
+ {
++ struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
++
++ /* Clear bic pointer if bfqq is detached from this bic */
++ if (old_bfqq && old_bfqq->bic == bic)
++ old_bfqq->bic = NULL;
++
+ /*
+ * If bfqq != NULL, then a non-stable queue merge between
+ * bic->bfqq and bfqq is happening here. This causes troubles
+@@ -5379,7 +5385,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfqd->lock, flags);
+- bfqq->bic = NULL;
+ bfq_exit_bfqq(bfqd, bfqq);
+ bic_set_bfqq(bic, NULL, is_sync);
+ spin_unlock_irqrestore(&bfqd->lock, flags);
+@@ -6786,6 +6791,12 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
+ bfqq = bfq_get_bfqq_handle_split(bfqd, bic, bio,
+ true, is_sync,
+ NULL);
++ if (unlikely(bfqq == &bfqd->oom_bfqq))
++ bfqq_already_existing = true;
++ } else
++ bfqq_already_existing = true;
++
++ if (!bfqq_already_existing) {
+ bfqq->waker_bfqq = old_bfqq->waker_bfqq;
+ bfqq->tentative_waker_bfqq = NULL;
+
+@@ -6799,8 +6810,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
+ if (bfqq->waker_bfqq)
+ hlist_add_head(&bfqq->woken_list_node,
+ &bfqq->waker_bfqq->woken_list);
+- } else
+- bfqq_already_existing = true;
++ }
+ }
+ }
+
+diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
+index 93997d297d427..4515288fbe351 100644
+--- a/block/blk-mq-sysfs.c
++++ b/block/blk-mq-sysfs.c
+@@ -185,7 +185,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+ {
+ struct request_queue *q = hctx->queue;
+ struct blk_mq_ctx *ctx;
+- int i, ret;
++ int i, j, ret;
+
+ if (!hctx->nr_ctx)
+ return 0;
+@@ -197,9 +197,16 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+ hctx_for_each_ctx(hctx, ctx, i) {
+ ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
+ if (ret)
+- break;
++ goto out;
+ }
+
++ return 0;
++out:
++ hctx_for_each_ctx(hctx, ctx, j) {
++ if (j < i)
++ kobject_del(&ctx->kobj);
++ }
++ kobject_del(&hctx->kobj);
+ return ret;
+ }
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 3f1f5e3e0951d..1a30f65802749 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1442,7 +1442,13 @@ static void blk_mq_rq_timed_out(struct request *req)
+ blk_add_timer(req);
+ }
+
+-static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
++struct blk_expired_data {
++ bool has_timedout_rq;
++ unsigned long next;
++ unsigned long timeout_start;
++};
++
++static bool blk_mq_req_expired(struct request *rq, struct blk_expired_data *expired)
+ {
+ unsigned long deadline;
+
+@@ -1452,13 +1458,13 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
+ return false;
+
+ deadline = READ_ONCE(rq->deadline);
+- if (time_after_eq(jiffies, deadline))
++ if (time_after_eq(expired->timeout_start, deadline))
+ return true;
+
+- if (*next == 0)
+- *next = deadline;
+- else if (time_after(*next, deadline))
+- *next = deadline;
++ if (expired->next == 0)
++ expired->next = deadline;
++ else if (time_after(expired->next, deadline))
++ expired->next = deadline;
+ return false;
+ }
+
+@@ -1472,7 +1478,7 @@ void blk_mq_put_rq_ref(struct request *rq)
+
+ static bool blk_mq_check_expired(struct request *rq, void *priv)
+ {
+- unsigned long *next = priv;
++ struct blk_expired_data *expired = priv;
+
+ /*
+ * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot
+@@ -1481,7 +1487,18 @@ static bool blk_mq_check_expired(struct request *rq, void *priv)
+ * it was completed and reallocated as a new request after returning
+ * from blk_mq_check_expired().
+ */
+- if (blk_mq_req_expired(rq, next))
++ if (blk_mq_req_expired(rq, expired)) {
++ expired->has_timedout_rq = true;
++ return false;
++ }
++ return true;
++}
++
++static bool blk_mq_handle_expired(struct request *rq, void *priv)
++{
++ struct blk_expired_data *expired = priv;
++
++ if (blk_mq_req_expired(rq, expired))
+ blk_mq_rq_timed_out(rq);
+ return true;
+ }
+@@ -1490,7 +1507,9 @@ static void blk_mq_timeout_work(struct work_struct *work)
+ {
+ struct request_queue *q =
+ container_of(work, struct request_queue, timeout_work);
+- unsigned long next = 0;
++ struct blk_expired_data expired = {
++ .timeout_start = jiffies,
++ };
+ struct blk_mq_hw_ctx *hctx;
+ unsigned long i;
+
+@@ -1510,10 +1529,23 @@ static void blk_mq_timeout_work(struct work_struct *work)
+ if (!percpu_ref_tryget(&q->q_usage_counter))
+ return;
+
+- blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &next);
++ /* check if there is any timed-out request */
++ blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &expired);
++ if (expired.has_timedout_rq) {
++ /*
++ * Before walking tags, we must ensure any submit started
++ * before the current time has finished. Since the submit
++ * uses srcu or rcu, wait for a synchronization point to
++ * ensure all running submits have finished
++ */
++ blk_mq_wait_quiesce_done(q);
++
++ expired.next = 0;
++ blk_mq_queue_tag_busy_iter(q, blk_mq_handle_expired, &expired);
++ }
+
+- if (next != 0) {
+- mod_timer(&q->timeout, next);
++ if (expired.next != 0) {
++ mod_timer(&q->timeout, expired.next);
+ } else {
+ /*
+ * Request timeouts are handled as a forward rolling timer. If
+diff --git a/block/genhd.c b/block/genhd.c
+index 044ff97381e33..28654723bc2b2 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -522,6 +522,7 @@ out_unregister_queue:
+ rq_qos_exit(disk->queue);
+ out_put_slave_dir:
+ kobject_put(disk->slave_dir);
++ disk->slave_dir = NULL;
+ out_put_holder_dir:
+ kobject_put(disk->part0->bd_holder_dir);
+ out_del_integrity:
+@@ -618,6 +619,7 @@ void del_gendisk(struct gendisk *disk)
+
+ kobject_put(disk->part0->bd_holder_dir);
+ kobject_put(disk->slave_dir);
++ disk->slave_dir = NULL;
+
+ part_stat_set_all(disk->part0, 0);
+ disk->part0->bd_stamp = 0;
+diff --git a/crypto/cryptd.c b/crypto/cryptd.c
+index 668095eca0faf..ca3a40fc7da91 100644
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -68,11 +68,12 @@ struct aead_instance_ctx {
+
+ struct cryptd_skcipher_ctx {
+ refcount_t refcnt;
+- struct crypto_sync_skcipher *child;
++ struct crypto_skcipher *child;
+ };
+
+ struct cryptd_skcipher_request_ctx {
+ crypto_completion_t complete;
++ struct skcipher_request req;
+ };
+
+ struct cryptd_hash_ctx {
+@@ -227,13 +228,13 @@ static int cryptd_skcipher_setkey(struct crypto_skcipher *parent,
+ const u8 *key, unsigned int keylen)
+ {
+ struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(parent);
+- struct crypto_sync_skcipher *child = ctx->child;
++ struct crypto_skcipher *child = ctx->child;
+
+- crypto_sync_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+- crypto_sync_skcipher_set_flags(child,
+- crypto_skcipher_get_flags(parent) &
+- CRYPTO_TFM_REQ_MASK);
+- return crypto_sync_skcipher_setkey(child, key, keylen);
++ crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
++ crypto_skcipher_set_flags(child,
++ crypto_skcipher_get_flags(parent) &
++ CRYPTO_TFM_REQ_MASK);
++ return crypto_skcipher_setkey(child, key, keylen);
+ }
+
+ static void cryptd_skcipher_complete(struct skcipher_request *req, int err)
+@@ -258,13 +259,13 @@ static void cryptd_skcipher_encrypt(struct crypto_async_request *base,
+ struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+- struct crypto_sync_skcipher *child = ctx->child;
+- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++ struct skcipher_request *subreq = &rctx->req;
++ struct crypto_skcipher *child = ctx->child;
+
+ if (unlikely(err == -EINPROGRESS))
+ goto out;
+
+- skcipher_request_set_sync_tfm(subreq, child);
++ skcipher_request_set_tfm(subreq, child);
+ skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+ NULL, NULL);
+ skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -286,13 +287,13 @@ static void cryptd_skcipher_decrypt(struct crypto_async_request *base,
+ struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+- struct crypto_sync_skcipher *child = ctx->child;
+- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++ struct skcipher_request *subreq = &rctx->req;
++ struct crypto_skcipher *child = ctx->child;
+
+ if (unlikely(err == -EINPROGRESS))
+ goto out;
+
+- skcipher_request_set_sync_tfm(subreq, child);
++ skcipher_request_set_tfm(subreq, child);
+ skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+ NULL, NULL);
+ skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -343,9 +344,10 @@ static int cryptd_skcipher_init_tfm(struct crypto_skcipher *tfm)
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+- ctx->child = (struct crypto_sync_skcipher *)cipher;
++ ctx->child = cipher;
+ crypto_skcipher_set_reqsize(
+- tfm, sizeof(struct cryptd_skcipher_request_ctx));
++ tfm, sizeof(struct cryptd_skcipher_request_ctx) +
++ crypto_skcipher_reqsize(cipher));
+ return 0;
+ }
+
+@@ -353,7 +355,7 @@ static void cryptd_skcipher_exit_tfm(struct crypto_skcipher *tfm)
+ {
+ struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+- crypto_free_sync_skcipher(ctx->child);
++ crypto_free_skcipher(ctx->child);
+ }
+
+ static void cryptd_skcipher_free(struct skcipher_instance *inst)
+@@ -931,7 +933,7 @@ struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm)
+ {
+ struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base);
+
+- return &ctx->child->base;
++ return ctx->child;
+ }
+ EXPORT_SYMBOL_GPL(cryptd_skcipher_child);
+
+diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
+index 59eb8ec366643..bc57b182f3047 100644
+--- a/crypto/tcrypt.c
++++ b/crypto/tcrypt.c
+@@ -1101,15 +1101,6 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
+ goto out_free_tfm;
+ }
+
+-
+- for (i = 0; i < num_mb; ++i)
+- if (testmgr_alloc_buf(data[i].xbuf)) {
+- while (i--)
+- testmgr_free_buf(data[i].xbuf);
+- goto out_free_tfm;
+- }
+-
+-
+ for (i = 0; i < num_mb; ++i) {
+ data[i].req = skcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!data[i].req) {
+@@ -1494,387 +1485,387 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
+ }
+
+ for (i = 1; i < 200; i++)
+- ret += do_test(NULL, 0, 0, i, num_mb);
++ ret = min(ret, do_test(NULL, 0, 0, i, num_mb));
+ break;
+
+ case 1:
+- ret += tcrypt_test("md5");
++ ret = min(ret, tcrypt_test("md5"));
+ break;
+
+ case 2:
+- ret += tcrypt_test("sha1");
++ ret = min(ret, tcrypt_test("sha1"));
+ break;
+
+ case 3:
+- ret += tcrypt_test("ecb(des)");
+- ret += tcrypt_test("cbc(des)");
+- ret += tcrypt_test("ctr(des)");
++ ret = min(ret, tcrypt_test("ecb(des)"));
++ ret = min(ret, tcrypt_test("cbc(des)"));
++ ret = min(ret, tcrypt_test("ctr(des)"));
+ break;
+
+ case 4:
+- ret += tcrypt_test("ecb(des3_ede)");
+- ret += tcrypt_test("cbc(des3_ede)");
+- ret += tcrypt_test("ctr(des3_ede)");
++ ret = min(ret, tcrypt_test("ecb(des3_ede)"));
++ ret = min(ret, tcrypt_test("cbc(des3_ede)"));
++ ret = min(ret, tcrypt_test("ctr(des3_ede)"));
+ break;
+
+ case 5:
+- ret += tcrypt_test("md4");
++ ret = min(ret, tcrypt_test("md4"));
+ break;
+
+ case 6:
+- ret += tcrypt_test("sha256");
++ ret = min(ret, tcrypt_test("sha256"));
+ break;
+
+ case 7:
+- ret += tcrypt_test("ecb(blowfish)");
+- ret += tcrypt_test("cbc(blowfish)");
+- ret += tcrypt_test("ctr(blowfish)");
++ ret = min(ret, tcrypt_test("ecb(blowfish)"));
++ ret = min(ret, tcrypt_test("cbc(blowfish)"));
++ ret = min(ret, tcrypt_test("ctr(blowfish)"));
+ break;
+
+ case 8:
+- ret += tcrypt_test("ecb(twofish)");
+- ret += tcrypt_test("cbc(twofish)");
+- ret += tcrypt_test("ctr(twofish)");
+- ret += tcrypt_test("lrw(twofish)");
+- ret += tcrypt_test("xts(twofish)");
++ ret = min(ret, tcrypt_test("ecb(twofish)"));
++ ret = min(ret, tcrypt_test("cbc(twofish)"));
++ ret = min(ret, tcrypt_test("ctr(twofish)"));
++ ret = min(ret, tcrypt_test("lrw(twofish)"));
++ ret = min(ret, tcrypt_test("xts(twofish)"));
+ break;
+
+ case 9:
+- ret += tcrypt_test("ecb(serpent)");
+- ret += tcrypt_test("cbc(serpent)");
+- ret += tcrypt_test("ctr(serpent)");
+- ret += tcrypt_test("lrw(serpent)");
+- ret += tcrypt_test("xts(serpent)");
++ ret = min(ret, tcrypt_test("ecb(serpent)"));
++ ret = min(ret, tcrypt_test("cbc(serpent)"));
++ ret = min(ret, tcrypt_test("ctr(serpent)"));
++ ret = min(ret, tcrypt_test("lrw(serpent)"));
++ ret = min(ret, tcrypt_test("xts(serpent)"));
+ break;
+
+ case 10:
+- ret += tcrypt_test("ecb(aes)");
+- ret += tcrypt_test("cbc(aes)");
+- ret += tcrypt_test("lrw(aes)");
+- ret += tcrypt_test("xts(aes)");
+- ret += tcrypt_test("ctr(aes)");
+- ret += tcrypt_test("rfc3686(ctr(aes))");
+- ret += tcrypt_test("ofb(aes)");
+- ret += tcrypt_test("cfb(aes)");
+- ret += tcrypt_test("xctr(aes)");
++ ret = min(ret, tcrypt_test("ecb(aes)"));
++ ret = min(ret, tcrypt_test("cbc(aes)"));
++ ret = min(ret, tcrypt_test("lrw(aes)"));
++ ret = min(ret, tcrypt_test("xts(aes)"));
++ ret = min(ret, tcrypt_test("ctr(aes)"));
++ ret = min(ret, tcrypt_test("rfc3686(ctr(aes))"));
++ ret = min(ret, tcrypt_test("ofb(aes)"));
++ ret = min(ret, tcrypt_test("cfb(aes)"));
++ ret = min(ret, tcrypt_test("xctr(aes)"));
+ break;
+
+ case 11:
+- ret += tcrypt_test("sha384");
++ ret = min(ret, tcrypt_test("sha384"));
+ break;
+
+ case 12:
+- ret += tcrypt_test("sha512");
++ ret = min(ret, tcrypt_test("sha512"));
+ break;
+
+ case 13:
+- ret += tcrypt_test("deflate");
++ ret = min(ret, tcrypt_test("deflate"));
+ break;
+
+ case 14:
+- ret += tcrypt_test("ecb(cast5)");
+- ret += tcrypt_test("cbc(cast5)");
+- ret += tcrypt_test("ctr(cast5)");
++ ret = min(ret, tcrypt_test("ecb(cast5)"));
++ ret = min(ret, tcrypt_test("cbc(cast5)"));
++ ret = min(ret, tcrypt_test("ctr(cast5)"));
+ break;
+
+ case 15:
+- ret += tcrypt_test("ecb(cast6)");
+- ret += tcrypt_test("cbc(cast6)");
+- ret += tcrypt_test("ctr(cast6)");
+- ret += tcrypt_test("lrw(cast6)");
+- ret += tcrypt_test("xts(cast6)");
++ ret = min(ret, tcrypt_test("ecb(cast6)"));
++ ret = min(ret, tcrypt_test("cbc(cast6)"));
++ ret = min(ret, tcrypt_test("ctr(cast6)"));
++ ret = min(ret, tcrypt_test("lrw(cast6)"));
++ ret = min(ret, tcrypt_test("xts(cast6)"));
+ break;
+
+ case 16:
+- ret += tcrypt_test("ecb(arc4)");
++ ret = min(ret, tcrypt_test("ecb(arc4)"));
+ break;
+
+ case 17:
+- ret += tcrypt_test("michael_mic");
++ ret = min(ret, tcrypt_test("michael_mic"));
+ break;
+
+ case 18:
+- ret += tcrypt_test("crc32c");
++ ret = min(ret, tcrypt_test("crc32c"));
+ break;
+
+ case 19:
+- ret += tcrypt_test("ecb(tea)");
++ ret = min(ret, tcrypt_test("ecb(tea)"));
+ break;
+
+ case 20:
+- ret += tcrypt_test("ecb(xtea)");
++ ret = min(ret, tcrypt_test("ecb(xtea)"));
+ break;
+
+ case 21:
+- ret += tcrypt_test("ecb(khazad)");
++ ret = min(ret, tcrypt_test("ecb(khazad)"));
+ break;
+
+ case 22:
+- ret += tcrypt_test("wp512");
++ ret = min(ret, tcrypt_test("wp512"));
+ break;
+
+ case 23:
+- ret += tcrypt_test("wp384");
++ ret = min(ret, tcrypt_test("wp384"));
+ break;
+
+ case 24:
+- ret += tcrypt_test("wp256");
++ ret = min(ret, tcrypt_test("wp256"));
+ break;
+
+ case 26:
+- ret += tcrypt_test("ecb(anubis)");
+- ret += tcrypt_test("cbc(anubis)");
++ ret = min(ret, tcrypt_test("ecb(anubis)"));
++ ret = min(ret, tcrypt_test("cbc(anubis)"));
+ break;
+
+ case 30:
+- ret += tcrypt_test("ecb(xeta)");
++ ret = min(ret, tcrypt_test("ecb(xeta)"));
+ break;
+
+ case 31:
+- ret += tcrypt_test("pcbc(fcrypt)");
++ ret = min(ret, tcrypt_test("pcbc(fcrypt)"));
+ break;
+
+ case 32:
+- ret += tcrypt_test("ecb(camellia)");
+- ret += tcrypt_test("cbc(camellia)");
+- ret += tcrypt_test("ctr(camellia)");
+- ret += tcrypt_test("lrw(camellia)");
+- ret += tcrypt_test("xts(camellia)");
++ ret = min(ret, tcrypt_test("ecb(camellia)"));
++ ret = min(ret, tcrypt_test("cbc(camellia)"));
++ ret = min(ret, tcrypt_test("ctr(camellia)"));
++ ret = min(ret, tcrypt_test("lrw(camellia)"));
++ ret = min(ret, tcrypt_test("xts(camellia)"));
+ break;
+
+ case 33:
+- ret += tcrypt_test("sha224");
++ ret = min(ret, tcrypt_test("sha224"));
+ break;
+
+ case 35:
+- ret += tcrypt_test("gcm(aes)");
++ ret = min(ret, tcrypt_test("gcm(aes)"));
+ break;
+
+ case 36:
+- ret += tcrypt_test("lzo");
++ ret = min(ret, tcrypt_test("lzo"));
+ break;
+
+ case 37:
+- ret += tcrypt_test("ccm(aes)");
++ ret = min(ret, tcrypt_test("ccm(aes)"));
+ break;
+
+ case 38:
+- ret += tcrypt_test("cts(cbc(aes))");
++ ret = min(ret, tcrypt_test("cts(cbc(aes))"));
+ break;
+
+ case 39:
+- ret += tcrypt_test("xxhash64");
++ ret = min(ret, tcrypt_test("xxhash64"));
+ break;
+
+ case 40:
+- ret += tcrypt_test("rmd160");
++ ret = min(ret, tcrypt_test("rmd160"));
+ break;
+
+ case 42:
+- ret += tcrypt_test("blake2b-512");
++ ret = min(ret, tcrypt_test("blake2b-512"));
+ break;
+
+ case 43:
+- ret += tcrypt_test("ecb(seed)");
++ ret = min(ret, tcrypt_test("ecb(seed)"));
+ break;
+
+ case 45:
+- ret += tcrypt_test("rfc4309(ccm(aes))");
++ ret = min(ret, tcrypt_test("rfc4309(ccm(aes))"));
+ break;
+
+ case 46:
+- ret += tcrypt_test("ghash");
++ ret = min(ret, tcrypt_test("ghash"));
+ break;
+
+ case 47:
+- ret += tcrypt_test("crct10dif");
++ ret = min(ret, tcrypt_test("crct10dif"));
+ break;
+
+ case 48:
+- ret += tcrypt_test("sha3-224");
++ ret = min(ret, tcrypt_test("sha3-224"));
+ break;
+
+ case 49:
+- ret += tcrypt_test("sha3-256");
++ ret = min(ret, tcrypt_test("sha3-256"));
+ break;
+
+ case 50:
+- ret += tcrypt_test("sha3-384");
++ ret = min(ret, tcrypt_test("sha3-384"));
+ break;
+
+ case 51:
+- ret += tcrypt_test("sha3-512");
++ ret = min(ret, tcrypt_test("sha3-512"));
+ break;
+
+ case 52:
+- ret += tcrypt_test("sm3");
++ ret = min(ret, tcrypt_test("sm3"));
+ break;
+
+ case 53:
+- ret += tcrypt_test("streebog256");
++ ret = min(ret, tcrypt_test("streebog256"));
+ break;
+
+ case 54:
+- ret += tcrypt_test("streebog512");
++ ret = min(ret, tcrypt_test("streebog512"));
+ break;
+
+ case 55:
+- ret += tcrypt_test("gcm(sm4)");
++ ret = min(ret, tcrypt_test("gcm(sm4)"));
+ break;
+
+ case 56:
+- ret += tcrypt_test("ccm(sm4)");
++ ret = min(ret, tcrypt_test("ccm(sm4)"));
+ break;
+
+ case 57:
+- ret += tcrypt_test("polyval");
++ ret = min(ret, tcrypt_test("polyval"));
+ break;
+
+ case 58:
+- ret += tcrypt_test("gcm(aria)");
++ ret = min(ret, tcrypt_test("gcm(aria)"));
+ break;
+
+ case 100:
+- ret += tcrypt_test("hmac(md5)");
++ ret = min(ret, tcrypt_test("hmac(md5)"));
+ break;
+
+ case 101:
+- ret += tcrypt_test("hmac(sha1)");
++ ret = min(ret, tcrypt_test("hmac(sha1)"));
+ break;
+
+ case 102:
+- ret += tcrypt_test("hmac(sha256)");
++ ret = min(ret, tcrypt_test("hmac(sha256)"));
+ break;
+
+ case 103:
+- ret += tcrypt_test("hmac(sha384)");
++ ret = min(ret, tcrypt_test("hmac(sha384)"));
+ break;
+
+ case 104:
+- ret += tcrypt_test("hmac(sha512)");
++ ret = min(ret, tcrypt_test("hmac(sha512)"));
+ break;
+
+ case 105:
+- ret += tcrypt_test("hmac(sha224)");
++ ret = min(ret, tcrypt_test("hmac(sha224)"));
+ break;
+
+ case 106:
+- ret += tcrypt_test("xcbc(aes)");
++ ret = min(ret, tcrypt_test("xcbc(aes)"));
+ break;
+
+ case 108:
+- ret += tcrypt_test("hmac(rmd160)");
++ ret = min(ret, tcrypt_test("hmac(rmd160)"));
+ break;
+
+ case 109:
+- ret += tcrypt_test("vmac64(aes)");
++ ret = min(ret, tcrypt_test("vmac64(aes)"));
+ break;
+
+ case 111:
+- ret += tcrypt_test("hmac(sha3-224)");
++ ret = min(ret, tcrypt_test("hmac(sha3-224)"));
+ break;
+
+ case 112:
+- ret += tcrypt_test("hmac(sha3-256)");
++ ret = min(ret, tcrypt_test("hmac(sha3-256)"));
+ break;
+
+ case 113:
+- ret += tcrypt_test("hmac(sha3-384)");
++ ret = min(ret, tcrypt_test("hmac(sha3-384)"));
+ break;
+
+ case 114:
+- ret += tcrypt_test("hmac(sha3-512)");
++ ret = min(ret, tcrypt_test("hmac(sha3-512)"));
+ break;
+
+ case 115:
+- ret += tcrypt_test("hmac(streebog256)");
++ ret = min(ret, tcrypt_test("hmac(streebog256)"));
+ break;
+
+ case 116:
+- ret += tcrypt_test("hmac(streebog512)");
++ ret = min(ret, tcrypt_test("hmac(streebog512)"));
+ break;
+
+ case 150:
+- ret += tcrypt_test("ansi_cprng");
++ ret = min(ret, tcrypt_test("ansi_cprng"));
+ break;
+
+ case 151:
+- ret += tcrypt_test("rfc4106(gcm(aes))");
++ ret = min(ret, tcrypt_test("rfc4106(gcm(aes))"));
+ break;
+
+ case 152:
+- ret += tcrypt_test("rfc4543(gcm(aes))");
++ ret = min(ret, tcrypt_test("rfc4543(gcm(aes))"));
+ break;
+
+ case 153:
+- ret += tcrypt_test("cmac(aes)");
++ ret = min(ret, tcrypt_test("cmac(aes)"));
+ break;
+
+ case 154:
+- ret += tcrypt_test("cmac(des3_ede)");
++ ret = min(ret, tcrypt_test("cmac(des3_ede)"));
+ break;
+
+ case 155:
+- ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(aes))"));
+ break;
+
+ case 156:
+- ret += tcrypt_test("authenc(hmac(md5),ecb(cipher_null))");
++ ret = min(ret, tcrypt_test("authenc(hmac(md5),ecb(cipher_null))"));
+ break;
+
+ case 157:
+- ret += tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))"));
+ break;
+
+ case 158:
+- ret += tcrypt_test("cbcmac(sm4)");
++ ret = min(ret, tcrypt_test("cbcmac(sm4)"));
+ break;
+
+ case 159:
+- ret += tcrypt_test("cmac(sm4)");
++ ret = min(ret, tcrypt_test("cmac(sm4)"));
+ break;
+
+ case 181:
+- ret += tcrypt_test("authenc(hmac(sha1),cbc(des))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des))"));
+ break;
+ case 182:
+- ret += tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))"));
+ break;
+ case 183:
+- ret += tcrypt_test("authenc(hmac(sha224),cbc(des))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des))"));
+ break;
+ case 184:
+- ret += tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))"));
+ break;
+ case 185:
+- ret += tcrypt_test("authenc(hmac(sha256),cbc(des))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des))"));
+ break;
+ case 186:
+- ret += tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))"));
+ break;
+ case 187:
+- ret += tcrypt_test("authenc(hmac(sha384),cbc(des))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des))"));
+ break;
+ case 188:
+- ret += tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))"));
+ break;
+ case 189:
+- ret += tcrypt_test("authenc(hmac(sha512),cbc(des))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des))"));
+ break;
+ case 190:
+- ret += tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))");
++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))"));
+ break;
+ case 191:
+- ret += tcrypt_test("ecb(sm4)");
+- ret += tcrypt_test("cbc(sm4)");
+- ret += tcrypt_test("cfb(sm4)");
+- ret += tcrypt_test("ctr(sm4)");
++ ret = min(ret, tcrypt_test("ecb(sm4)"));
++ ret = min(ret, tcrypt_test("cbc(sm4)"));
++ ret = min(ret, tcrypt_test("cfb(sm4)"));
++ ret = min(ret, tcrypt_test("ctr(sm4)"));
+ break;
+ case 192:
+- ret += tcrypt_test("ecb(aria)");
+- ret += tcrypt_test("cbc(aria)");
+- ret += tcrypt_test("cfb(aria)");
+- ret += tcrypt_test("ctr(aria)");
++ ret = min(ret, tcrypt_test("ecb(aria)"));
++ ret = min(ret, tcrypt_test("cbc(aria)"));
++ ret = min(ret, tcrypt_test("cfb(aria)"));
++ ret = min(ret, tcrypt_test("ctr(aria)"));
+ break;
+ case 200:
+ test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
+index ae2e768830bfc..9332bc688713c 100644
+--- a/drivers/acpi/acpica/dsmethod.c
++++ b/drivers/acpi/acpica/dsmethod.c
+@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ if (!info) {
+ status = AE_NO_MEMORY;
+- goto cleanup;
++ goto pop_walk_state;
+ }
+
+ info->parameters = &this_walk_state->operands[0];
+@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+
+ ACPI_FREE(info);
+ if (ACPI_FAILURE(status)) {
+- goto cleanup;
++ goto pop_walk_state;
+ }
+
+ next_walk_state->method_nesting_depth =
+@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+
+ return_ACPI_STATUS(status);
+
++pop_walk_state:
++
++ /* On error, pop the walk state to be deleted from thread */
++
++ acpi_ds_pop_walk_state(thread);
++
+ cleanup:
+
+ /* On error, we must terminate the method properly */
+diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
+index 400b9e15a709c..63c17f420fb86 100644
+--- a/drivers/acpi/acpica/utcopy.c
++++ b/drivers/acpi/acpica/utcopy.c
+@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
+ status = acpi_ut_walk_package_tree(source_obj, dest_obj,
+ acpi_ut_copy_ielement_to_ielement,
+ walk_state);
+- if (ACPI_FAILURE(status)) {
+-
+- /* On failure, delete the destination package object */
+-
+- acpi_ut_remove_reference(dest_obj);
+- }
+-
+ return_ACPI_STATUS(status);
+ }
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index c95e535035a04..fdc760e1e09ef 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1879,6 +1879,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),
+ },
+ },
++ {
++ /*
++ * HP Pavilion Gaming Laptop 15-cx0041ur
++ */
++ .callback = ec_honor_dsdt_gpe,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"),
++ },
++ },
+ {
+ /*
+ * Samsung hardware
+diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
+index dabe45eba055d..0d9a17fdd83eb 100644
+--- a/drivers/acpi/irq.c
++++ b/drivers/acpi/irq.c
+@@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
+ /**
+ * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source.
+ * @source: acpi_resource_source to use for the lookup.
++ * @gsi: GSI IRQ number
+ *
+ * Description:
+ * Retrieve the fwhandle of the device referenced by the given IRQ resource
+@@ -295,8 +296,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get);
+ /**
+ * acpi_set_irq_model - Setup the GSI irqdomain information
+ * @model: the value assigned to acpi_irq_model
+- * @fwnode: the irq_domain identifier for mapping and looking up
+- * GSI interrupts
++ * @fn: a dispatcher function that will return the domain fwnode
++ * for a given GSI
+ */
+ void __init acpi_set_irq_model(enum acpi_irq_model_id model,
+ struct fwnode_handle *(*fn)(u32))
+diff --git a/drivers/acpi/pfr_telemetry.c b/drivers/acpi/pfr_telemetry.c
+index 9abf350bd7a5a..27fb6cdad75f9 100644
+--- a/drivers/acpi/pfr_telemetry.c
++++ b/drivers/acpi/pfr_telemetry.c
+@@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info,
+ ret = 0;
+
+ free_acpi_buffer:
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+@@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev)
+ ret = -EBUSY;
+ }
+
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+@@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev)
+ ret = obj->integer.value;
+
+ free_acpi_buffer:
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c
+index 6bb0b778b5da5..9d2bdc13253a5 100644
+--- a/drivers/acpi/pfr_update.c
++++ b/drivers/acpi/pfr_update.c
+@@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr,
+ ret = 0;
+
+ free_acpi_buffer:
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+@@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info,
+ ret = 0;
+
+ free_acpi_buffer:
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+@@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev)
+ ret = 0;
+
+ free_acpi_buffer:
+- kfree(out_obj);
++ ACPI_FREE(out_obj);
+
+ return ret;
+ }
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index 9f40917c49efb..4d1dd255c1228 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -1134,6 +1134,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
+ status = acpi_get_parent(handle, &pr_ahandle);
+ while (ACPI_SUCCESS(status)) {
+ d = acpi_fetch_acpi_dev(pr_ahandle);
++ if (!d)
++ break;
++
+ handle = pr_ahandle;
+
+ if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID))
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index 950a93922ca8f..ae60e4aae0eec 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ },
+ {
+- /* Lenovo Yoga Tablet 1050F/L */
++ /* Lenovo Yoga Tablet 2 1050F/L */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
+@@ -319,6 +319,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ },
++ {
++ /* Lenovo Yoga Tab 3 Pro 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 *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
++ },
++ {
++ /* Medion Lifetab S10346 */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
++ /* Way too generic, also match on BIOS data */
++ DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
++ },
++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
++ },
+ {
+ /* Nextbook Ares 8 */
+ .matches = {
+@@ -348,6 +369,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = {
+ { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */
+ { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */
+ { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */
++ { "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */
+ { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */
+ {}
+ };
+diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
+index 13b9d0fdd42c8..8e292e2abb046 100644
+--- a/drivers/ata/libata-sata.c
++++ b/drivers/ata/libata-sata.c
+@@ -1392,7 +1392,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
+ tf->hob_lbah = buf[10];
+ tf->nsect = buf[12];
+ tf->hob_nsect = buf[13];
+- if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
++ if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id) &&
++ (tf->status & ATA_SENSE))
+ tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
+
+ return 0;
+@@ -1456,8 +1457,12 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
+ memcpy(&qc->result_tf, &tf, sizeof(tf));
+ qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
+ qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
+- if (dev->class == ATA_DEV_ZAC &&
+- ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) {
++
++ /*
++ * If the device supports NCQ autosense, ata_eh_read_log_10h() will have
++ * stored the sense data in qc->result_tf.auxiliary.
++ */
++ if (qc->result_tf.auxiliary) {
+ char sense_key, asc, ascq;
+
+ sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index 8feb85e186e3b..e394e3e473b5d 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key)
+ }
+ error = class_add_groups(class_get(cls), cls->class_groups);
+ class_put(cls);
++ if (error) {
++ kobject_del(&cp->subsys.kobj);
++ kfree_const(cp->subsys.kobj.name);
++ kfree(cp);
++ }
+ return error;
+ }
+ EXPORT_SYMBOL_GPL(__class_register);
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 997be3ac20a79..d36fb07190bf5 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -484,7 +484,17 @@ static int rpm_idle(struct device *dev, int rpmflags)
+
+ dev->power.idle_notification = true;
+
+- retval = __rpm_callback(callback, dev);
++ if (dev->power.irq_safe)
++ spin_unlock(&dev->power.lock);
++ else
++ spin_unlock_irq(&dev->power.lock);
++
++ retval = callback(dev);
++
++ if (dev->power.irq_safe)
++ spin_lock(&dev->power.lock);
++ else
++ spin_lock_irq(&dev->power.lock);
+
+ dev->power.idle_notification = false;
+ wake_up_all(&dev->power.wait_queue);
+diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
+index 4ef9488d05cde..3de89795f5843 100644
+--- a/drivers/base/regmap/regmap-irq.c
++++ b/drivers/base/regmap/regmap-irq.c
+@@ -722,6 +722,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
+ int i;
+ int ret = -ENOMEM;
+ int num_type_reg;
++ int num_regs;
+ u32 reg;
+
+ if (chip->num_regs <= 0)
+@@ -796,14 +797,20 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
+ goto err_alloc;
+ }
+
+- num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg;
+- if (num_type_reg) {
+- d->type_buf_def = kcalloc(num_type_reg,
++ /*
++ * Use num_config_regs if defined, otherwise fall back to num_type_reg
++ * to maintain backward compatibility.
++ */
++ num_type_reg = chip->num_config_regs ? chip->num_config_regs
++ : chip->num_type_reg;
++ num_regs = chip->type_in_mask ? chip->num_regs : num_type_reg;
++ if (num_regs) {
++ d->type_buf_def = kcalloc(num_regs,
+ sizeof(*d->type_buf_def), GFP_KERNEL);
+ if (!d->type_buf_def)
+ goto err_alloc;
+
+- d->type_buf = kcalloc(num_type_reg, sizeof(*d->type_buf),
++ d->type_buf = kcalloc(num_regs, sizeof(*d->type_buf),
+ GFP_KERNEL);
+ if (!d->type_buf)
+ goto err_alloc;
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index 8532b839a3435..6772402326842 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -2217,7 +2217,8 @@ void drbd_destroy_device(struct kref *kref)
+ kref_put(&peer_device->connection->kref, drbd_destroy_connection);
+ kfree(peer_device);
+ }
+- memset(device, 0xfd, sizeof(*device));
++ if (device->submit.wq)
++ destroy_workqueue(device->submit.wq);
+ kfree(device);
+ kref_put(&resource->kref, drbd_destroy_resource);
+ }
+@@ -2309,7 +2310,6 @@ void drbd_destroy_resource(struct kref *kref)
+ idr_destroy(&resource->devices);
+ free_cpumask_var(resource->cpu_mask);
+ kfree(resource->name);
+- memset(resource, 0xf2, sizeof(*resource));
+ kfree(resource);
+ }
+
+@@ -2650,7 +2650,6 @@ void drbd_destroy_connection(struct kref *kref)
+ drbd_free_socket(&connection->data);
+ kfree(connection->int_dig_in);
+ kfree(connection->int_dig_vv);
+- memset(connection, 0xfc, sizeof(*connection));
+ kfree(connection);
+ kref_put(&resource->kref, drbd_destroy_resource);
+ }
+@@ -2774,7 +2773,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+
+ err = add_disk(disk);
+ if (err)
+- goto out_idr_remove_from_resource;
++ goto out_destroy_workqueue;
+
+ /* inherit the connection state */
+ device->state.conn = first_connection(resource)->cstate;
+@@ -2788,6 +2787,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+ drbd_debugfs_device_add(device);
+ return NO_ERROR;
+
++out_destroy_workqueue:
++ destroy_workqueue(device->submit.wq);
+ out_idr_remove_from_resource:
+ for_each_connection_safe(connection, n, resource) {
+ peer_device = idr_remove(&connection->peer_devices, vnr);
+diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
+index 013d355a2033b..921c303a7b5c4 100644
+--- a/drivers/block/drbd/drbd_nl.c
++++ b/drivers/block/drbd/drbd_nl.c
+@@ -1210,6 +1210,7 @@ static void decide_on_discard_support(struct drbd_device *device,
+ struct drbd_connection *connection =
+ first_peer_device(device)->connection;
+ struct request_queue *q = device->rq_queue;
++ unsigned int max_discard_sectors;
+
+ if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev))
+ goto not_supported;
+@@ -1230,15 +1231,14 @@ static void decide_on_discard_support(struct drbd_device *device,
+ * topology on all peers.
+ */
+ blk_queue_discard_granularity(q, 512);
+- q->limits.max_discard_sectors = drbd_max_discard_sectors(connection);
+- q->limits.max_write_zeroes_sectors =
+- drbd_max_discard_sectors(connection);
++ max_discard_sectors = drbd_max_discard_sectors(connection);
++ blk_queue_max_discard_sectors(q, max_discard_sectors);
++ blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
+ return;
+
+ not_supported:
+ blk_queue_discard_granularity(q, 0);
+- q->limits.max_discard_sectors = 0;
+- q->limits.max_write_zeroes_sectors = 0;
++ blk_queue_max_discard_sectors(q, 0);
+ }
+
+ static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q)
+diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
+index ccad3d7b3ddd9..487840e3564df 100644
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -4593,8 +4593,10 @@ static int __init do_floppy_init(void)
+ goto out_put_disk;
+
+ err = floppy_alloc_disk(drive, 0);
+- if (err)
++ if (err) {
++ blk_mq_free_tag_set(&tag_sets[drive]);
+ goto out_put_disk;
++ }
+
+ timer_setup(&motor_off_timer[drive], motor_off_callback, 0);
+ }
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index ad92192c7d617..d12d3d171ec4c 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1773,7 +1773,16 @@ static const struct block_device_operations lo_fops = {
+ /*
+ * And now the modules code and kernel interface.
+ */
+-static int max_loop;
++
++/*
++ * If max_loop is specified, create that many devices upfront.
++ * This also becomes a hard limit. If max_loop is not specified,
++ * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
++ * init time. Loop devices can be requested on-demand with the
++ * /dev/loop-control interface, or be instantiated by accessing
++ * a 'dead' device node.
++ */
++static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
+ module_param(max_loop, int, 0444);
+ MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
+ module_param(max_part, int, 0444);
+@@ -2181,7 +2190,7 @@ MODULE_ALIAS("devname:loop-control");
+
+ static int __init loop_init(void)
+ {
+- int i, nr;
++ int i;
+ int err;
+
+ part_shift = 0;
+@@ -2209,19 +2218,6 @@ static int __init loop_init(void)
+ goto err_out;
+ }
+
+- /*
+- * If max_loop is specified, create that many devices upfront.
+- * This also becomes a hard limit. If max_loop is not specified,
+- * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
+- * init time. Loop devices can be requested on-demand with the
+- * /dev/loop-control interface, or be instantiated by accessing
+- * a 'dead' device node.
+- */
+- if (max_loop)
+- nr = max_loop;
+- else
+- nr = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
+-
+ err = misc_register(&loop_misc);
+ if (err < 0)
+ goto err_out;
+@@ -2233,7 +2229,7 @@ static int __init loop_init(void)
+ }
+
+ /* pre-create number of devices given by config or max_loop */
+- for (i = 0; i < nr; i++)
++ for (i = 0; i < max_loop; i++)
+ loop_add(i);
+
+ printk(KERN_INFO "loop: module loaded\n");
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index d44a966675179..0c2542cee294b 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2522,7 +2522,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ */
+ err = btintel_read_version(hdev, &ver);
+ if (err)
+- return err;
++ break;
+
+ /* Apply the device specific HCI quirks
+ *
+@@ -2563,7 +2563,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ default:
+ bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
+ INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
+- return -EINVAL;
++ err = -EINVAL;
++ break;
+ }
+
+ exit_error:
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 882b5893f9108..a132e7aba6054 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -788,13 +788,13 @@ static inline void btusb_free_frags(struct btusb_data *data)
+
+ spin_lock_irqsave(&data->rxlock, flags);
+
+- kfree_skb(data->evt_skb);
++ dev_kfree_skb_irq(data->evt_skb);
+ data->evt_skb = NULL;
+
+- kfree_skb(data->acl_skb);
++ dev_kfree_skb_irq(data->acl_skb);
+ data->acl_skb = NULL;
+
+- kfree_skb(data->sco_skb);
++ dev_kfree_skb_irq(data->sco_skb);
+ data->sco_skb = NULL;
+
+ spin_unlock_irqrestore(&data->rxlock, flags);
+diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
+index d7e0b75db8a60..2b6c0e1922cb3 100644
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -53,11 +53,13 @@
+ * struct bcm_device_data - device specific data
+ * @no_early_set_baudrate: Disallow set baudrate before driver setup()
+ * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
+ * @max_autobaud_speed: max baudrate supported by device in autobaud mode
+ */
+ struct bcm_device_data {
+ bool no_early_set_baudrate;
+ bool drive_rts_on_open;
++ bool no_uart_clock_set;
+ u32 max_autobaud_speed;
+ };
+
+@@ -100,6 +102,7 @@ struct bcm_device_data {
+ * @is_suspended: whether flow control is currently disabled
+ * @no_early_set_baudrate: don't set_baudrate before setup()
+ * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
+ * @pcm_int_params: keep the initial PCM configuration
+ * @use_autobaud_mode: start Bluetooth device in autobaud mode
+ * @max_autobaud_speed: max baudrate supported by device in autobaud mode
+@@ -140,6 +143,7 @@ struct bcm_device {
+ #endif
+ bool no_early_set_baudrate;
+ bool drive_rts_on_open;
++ bool no_uart_clock_set;
+ bool use_autobaud_mode;
+ u8 pcm_int_params[5];
+ u32 max_autobaud_speed;
+@@ -172,10 +176,11 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
+ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
+ {
+ struct hci_dev *hdev = hu->hdev;
++ struct bcm_data *bcm = hu->priv;
+ struct sk_buff *skb;
+ struct bcm_update_uart_baud_rate param;
+
+- if (speed > 3000000) {
++ if (speed > 3000000 && !bcm->dev->no_uart_clock_set) {
+ struct bcm_write_uart_clock_setting clock;
+
+ clock.type = BCM_UART_CLOCK_48MHZ;
+@@ -1529,6 +1534,7 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
+ bcmdev->max_autobaud_speed = data->max_autobaud_speed;
+ bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
+ bcmdev->drive_rts_on_open = data->drive_rts_on_open;
++ bcmdev->no_uart_clock_set = data->no_uart_clock_set;
+ }
+
+ return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
+@@ -1550,6 +1556,10 @@ static struct bcm_device_data bcm43438_device_data = {
+ .drive_rts_on_open = true,
+ };
+
++static struct bcm_device_data cyw4373a0_device_data = {
++ .no_uart_clock_set = true,
++};
++
+ static struct bcm_device_data cyw55572_device_data = {
+ .max_autobaud_speed = 921600,
+ };
+@@ -1566,6 +1576,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
+ { .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data },
+ { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
+ { .compatible = "brcm,bcm4335a0" },
++ { .compatible = "cypress,cyw4373a0-bt", .data = &cyw4373a0_device_data },
+ { .compatible = "infineon,cyw55572-bt", .data = &cyw55572_device_data },
+ { },
+ };
+diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
+index cf4a560958173..8055f63603f45 100644
+--- a/drivers/bluetooth/hci_bcsp.c
++++ b/drivers/bluetooth/hci_bcsp.c
+@@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
+ i++;
+
+ __skb_unlink(skb, &bcsp->unack);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ }
+
+ if (skb_queue_empty(&bcsp->unack))
+diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
+index c5a0409ef84fd..6455bc4fb5bb3 100644
+--- a/drivers/bluetooth/hci_h5.c
++++ b/drivers/bluetooth/hci_h5.c
+@@ -313,7 +313,7 @@ static void h5_pkt_cull(struct h5 *h5)
+ break;
+
+ __skb_unlink(skb, &h5->unack);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ }
+
+ if (skb_queue_empty(&h5->unack))
+diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
+index 4eb420a9ed04e..5abc01a2acf72 100644
+--- a/drivers/bluetooth/hci_ll.c
++++ b/drivers/bluetooth/hci_ll.c
+@@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+ default:
+ BT_ERR("illegal hcill state: %ld (losing packet)",
+ ll->hcill_state);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ break;
+ }
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 8df11016fd51b..bae9b2a408d95 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -912,7 +912,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+ default:
+ BT_ERR("Illegal tx state: %d (losing packet)",
+ qca->tx_ibs_state);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ break;
+ }
+
+diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
+index c22d4184bb612..0555e3838bce1 100644
+--- a/drivers/char/hw_random/amd-rng.c
++++ b/drivers/char/hw_random/amd-rng.c
+@@ -143,15 +143,19 @@ static int __init amd_rng_mod_init(void)
+ found:
+ err = pci_read_config_dword(pdev, 0x58, &pmbase);
+ if (err)
+- return err;
++ goto put_dev;
+
+ pmbase &= 0x0000FF00;
+- if (pmbase == 0)
+- return -EIO;
++ if (pmbase == 0) {
++ err = -EIO;
++ goto put_dev;
++ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
++ if (!priv) {
++ err = -ENOMEM;
++ goto put_dev;
++ }
+
+ if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
+ dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
+@@ -185,6 +189,8 @@ err_iomap:
+ release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+ out:
+ kfree(priv);
++put_dev:
++ pci_dev_put(pdev);
+ return err;
+ }
+
+@@ -200,6 +206,8 @@ static void __exit amd_rng_mod_exit(void)
+
+ release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+
++ pci_dev_put(priv->pcidev);
++
+ kfree(priv);
+ }
+
+diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
+index 138ce434f86b2..12fbe80918319 100644
+--- a/drivers/char/hw_random/geode-rng.c
++++ b/drivers/char/hw_random/geode-rng.c
+@@ -51,6 +51,10 @@ static const struct pci_device_id pci_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(pci, pci_tbl);
+
++struct amd_geode_priv {
++ struct pci_dev *pcidev;
++ void __iomem *membase;
++};
+
+ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+ {
+@@ -90,6 +94,7 @@ static int __init geode_rng_init(void)
+ const struct pci_device_id *ent;
+ void __iomem *mem;
+ unsigned long rng_base;
++ struct amd_geode_priv *priv;
+
+ for_each_pci_dev(pdev) {
+ ent = pci_match_id(pci_tbl, pdev);
+@@ -97,17 +102,26 @@ static int __init geode_rng_init(void)
+ goto found;
+ }
+ /* Device not found. */
+- goto out;
++ return err;
+
+ found:
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ err = -ENOMEM;
++ goto put_dev;
++ }
++
+ rng_base = pci_resource_start(pdev, 0);
+ if (rng_base == 0)
+- goto out;
++ goto free_priv;
+ err = -ENOMEM;
+ mem = ioremap(rng_base, 0x58);
+ if (!mem)
+- goto out;
+- geode_rng.priv = (unsigned long)mem;
++ goto free_priv;
++
++ geode_rng.priv = (unsigned long)priv;
++ priv->membase = mem;
++ priv->pcidev = pdev;
+
+ pr_info("AMD Geode RNG detected\n");
+ err = hwrng_register(&geode_rng);
+@@ -116,20 +130,26 @@ found:
+ err);
+ goto err_unmap;
+ }
+-out:
+ return err;
+
+ err_unmap:
+ iounmap(mem);
+- goto out;
++free_priv:
++ kfree(priv);
++put_dev:
++ pci_dev_put(pdev);
++ return err;
+ }
+
+ static void __exit geode_rng_exit(void)
+ {
+- void __iomem *mem = (void __iomem *)geode_rng.priv;
++ struct amd_geode_priv *priv;
+
++ priv = (struct amd_geode_priv *)geode_rng.priv;
+ hwrng_unregister(&geode_rng);
+- iounmap(mem);
++ iounmap(priv->membase);
++ pci_dev_put(priv->pcidev);
++ kfree(priv);
+ }
+
+ module_init(geode_rng_init);
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 703433493c852..c9e32d100b7eb 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -3710,12 +3710,16 @@ static void deliver_smi_err_response(struct ipmi_smi *intf,
+ struct ipmi_smi_msg *msg,
+ unsigned char err)
+ {
++ int rv;
+ msg->rsp[0] = msg->data[0] | 4;
+ msg->rsp[1] = msg->data[1];
+ msg->rsp[2] = err;
+ msg->rsp_size = 3;
+- /* It's an error, so it will never requeue, no need to check return. */
+- handle_one_recv_msg(intf, msg);
++
++ /* This will never requeue, but it may ask us to free the message. */
++ rv = handle_one_recv_msg(intf, msg);
++ if (rv == 0)
++ ipmi_free_smi_msg(msg);
+ }
+
+ static void cleanup_smi_msgs(struct ipmi_smi *intf)
+diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
+index cdc88cde1e9aa..417e5a3ccfaeb 100644
+--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
++++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
+@@ -399,13 +399,31 @@ static void aspeed_kcs_check_obe(struct timer_list *timer)
+ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state)
+ {
+ struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
++ int rc;
++ u8 str;
+
+ /* We don't have an OBE IRQ, emulate it */
+ if (mask & KCS_BMC_EVENT_TYPE_OBE) {
+- if (KCS_BMC_EVENT_TYPE_OBE & state)
+- mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
+- else
++ if (KCS_BMC_EVENT_TYPE_OBE & state) {
++ /*
++ * Given we don't have an OBE IRQ, delay by polling briefly to see if we can
++ * observe such an event before returning to the caller. This is not
++ * incorrect because OBF may have already become clear before enabling the
++ * IRQ if we had one, under which circumstance no event will be propagated
++ * anyway.
++ *
++ * The onus is on the client to perform a race-free check that it hasn't
++ * missed the event.
++ */
++ rc = read_poll_timeout_atomic(aspeed_kcs_inb, str,
++ !(str & KCS_BMC_STR_OBF), 1, 100, false,
++ &priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
++ /* Time for the slow path? */
++ if (rc == -ETIMEDOUT)
++ mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
++ } else {
+ del_timer(&priv->obe.timer);
++ }
+ }
+
+ if (mask & KCS_BMC_EVENT_TYPE_IBF) {
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 18606651d1aa4..65f8f179a27f0 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -252,7 +252,7 @@ static int __crb_relinquish_locality(struct device *dev,
+ iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
+ if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value,
+ TPM2_TIMEOUT_C)) {
+- dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
++ dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n");
+ return -ETIME;
+ }
+
+diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c
+index 5c233423c56fa..deff23bb54bf1 100644
+--- a/drivers/char/tpm/tpm_ftpm_tee.c
++++ b/drivers/char/tpm/tpm_ftpm_tee.c
+@@ -397,7 +397,13 @@ static int __init ftpm_mod_init(void)
+ if (rc)
+ return rc;
+
+- return driver_register(&ftpm_tee_driver.driver);
++ rc = driver_register(&ftpm_tee_driver.driver);
++ if (rc) {
++ platform_driver_unregister(&ftpm_tee_plat_driver);
++ return rc;
++ }
++
++ return 0;
+ }
+
+ static void __exit ftpm_mod_exit(void)
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 757623bacfd50..3f98e587b3e84 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -682,15 +682,19 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+
+- switch (priv->manufacturer_id) {
+- case TPM_VID_WINBOND:
+- return ((status == TPM_STS_VALID) ||
+- (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
+- case TPM_VID_STM:
+- return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
+- default:
+- return (status == TPM_STS_COMMAND_READY);
++ if (!test_bit(TPM_TIS_DEFAULT_CANCELLATION, &priv->flags)) {
++ switch (priv->manufacturer_id) {
++ case TPM_VID_WINBOND:
++ return ((status == TPM_STS_VALID) ||
++ (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
++ case TPM_VID_STM:
++ return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
++ default:
++ break;
++ }
+ }
++
++ return status == TPM_STS_COMMAND_READY;
+ }
+
+ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
+index 66a5a13cd1df2..b68479e0de10f 100644
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -86,6 +86,7 @@ enum tis_defaults {
+ enum tpm_tis_flags {
+ TPM_TIS_ITPM_WORKAROUND = BIT(0),
+ TPM_TIS_INVALID_STATUS = BIT(1),
++ TPM_TIS_DEFAULT_CANCELLATION = BIT(2),
+ };
+
+ struct tpm_tis_data {
+diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c
+index ba0911b1d1ff3..e728a61659f86 100644
+--- a/drivers/char/tpm/tpm_tis_i2c.c
++++ b/drivers/char/tpm/tpm_tis_i2c.c
+@@ -49,7 +49,7 @@
+
+ /* Masks with bits that must be read zero */
+ #define TPM_ACCESS_READ_ZERO 0x48
+-#define TPM_INT_ENABLE_ZERO 0x7FFFFF6
++#define TPM_INT_ENABLE_ZERO 0x7FFFFF60
+ #define TPM_STS_READ_ZERO 0x23
+ #define TPM_INTF_CAPABILITY_ZERO 0x0FFFF000
+ #define TPM_I2C_INTERFACE_CAPABILITY_ZERO 0x80000000
+@@ -329,6 +329,7 @@ static int tpm_tis_i2c_probe(struct i2c_client *dev,
+ if (!phy->io_buf)
+ return -ENOMEM;
+
++ set_bit(TPM_TIS_DEFAULT_CANCELLATION, &phy->priv.flags);
+ phy->i2c_client = dev;
+
+ /* must precede all communication with the tpm */
+diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
+index d37c45b676abe..2afea905f7f3c 100644
+--- a/drivers/clk/imx/clk-imx8mn.c
++++ b/drivers/clk/imx/clk-imx8mn.c
+@@ -27,10 +27,10 @@ static u32 share_count_nand;
+ static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+ static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
++static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
+ static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+ static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+-static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
++static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
+ static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+ static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+@@ -40,24 +40,24 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl
+
+ static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
+
+-static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out",
+- "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
++static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "m7_alt_pll_out",
++ "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
+
+ static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+ "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+- "video_pll1_out", "audio_pll2_out", };
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+ "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+- "video_pll1_out", "audio_pll2_out", };
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
+ "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
+- "video_pll1_out", "sys_pll1_100m",};
++ "video_pll_out", "sys_pll1_100m",};
+
+ static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+ "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+- "video_pll1_out", "sys_pll3_out", };
++ "video_pll_out", "sys_pll3_out", };
+
+ static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+ "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+@@ -77,23 +77,23 @@ static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "
+
+ static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+ "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+- "video_pll1_out", "audio_pll2_out", };
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+ "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+- "video_pll1_out", "audio_pll2_out", };
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+- "video_pll1_out", "audio_pll2_out", };
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
+ "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+- "audio_pll1_out", "video_pll1_out", };
++ "audio_pll1_out", "video_pll_out", };
+
+ static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
+- "audio_pll1_out", "video_pll1_out", };
++ "audio_pll1_out", "video_pll_out", };
+
+ static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
+ "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
+@@ -103,49 +103,49 @@ static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m",
+ "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_250m", "audio_pll2_out", };
+
+-static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
++static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out",
+ "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll3_out", "clk_ext4", };
+
+ static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+- "clk_ext3", "clk_ext4", };
++ "video_pll_out", "sys_pll1_133m", "dummy",
++ "clk_ext2", "clk_ext3", };
+
+ static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++ "video_pll_out", "sys_pll1_133m", "dummy",
+ "clk_ext3", "clk_ext4", };
+
+ static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++ "video_pll_out", "sys_pll1_133m", "dummy",
+ "clk_ext2", "clk_ext3", };
+
+ static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++ "video_pll_out", "sys_pll1_133m", "dummy",
+ "clk_ext3", "clk_ext4", };
+
+ static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++ "video_pll_out", "sys_pll1_133m", "dummy",
+ "clk_ext3", "clk_ext4", };
+
+ static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++ "video_pll_out", "sys_pll1_133m", "dummy",
+ "clk_ext2", "clk_ext3", };
+
+ static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+ "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+- "video_pll1_out", "clk_ext4", };
++ "video_pll_out", "clk_ext4", };
+
+ static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+ "clk_ext1", "clk_ext2", "clk_ext3",
+- "clk_ext4", "video_pll1_out", };
++ "clk_ext4", "video_pll_out", };
+
+ static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
+- "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
+- "audio_pll2_out", };
++ "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
++ "video_pll_out", "audio_pll2_out", };
+
+ static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+ "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+- "sys_pll2_250m", "video_pll1_out", };
++ "sys_pll2_250m", "video_pll_out", };
+
+ static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
+ "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
+@@ -160,19 +160,19 @@ static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s
+ "audio_pll2_out", "sys_pll1_100m", };
+
+ static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+- "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++ "sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ "audio_pll2_out", "sys_pll1_133m", };
+
+ static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+- "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++ "sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ "audio_pll2_out", "sys_pll1_133m", };
+
+ static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+- "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++ "sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ "audio_pll2_out", "sys_pll1_133m", };
+
+ static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+- "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++ "sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ "audio_pll2_out", "sys_pll1_133m", };
+
+ static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+@@ -213,63 +213,63 @@ static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s
+
+ static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+- "sys_pll1_80m", "video_pll1_out", };
++ "sys_pll1_80m", "video_pll_out", };
+
+ static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+- "sys_pll1_80m", "video_pll1_out", };
++ "sys_pll1_80m", "video_pll_out", };
+
+ static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+- "sys_pll1_80m", "video_pll1_out", };
++ "sys_pll1_80m", "video_pll_out", };
+
+ static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+- "sys_pll1_80m", "video_pll1_out", };
++ "sys_pll1_80m", "video_pll_out", };
+
+ static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ "audio_pll1_out", "clk_ext1", };
+
+ static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
+- "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
++ "m7_alt_pll_out", "sys_pll2_125m", "sys_pll3_out",
+ "sys_pll1_80m", "sys_pll2_166m", };
+
+-static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
++static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "m7_alt_pll_out",
+ "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
+ "sys_pll2_500m", "sys_pll1_100m", };
+
+ static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m",
+ "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+ "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+@@ -277,15 +277,15 @@ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s
+
+ static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+ "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+ "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+- "audio_pll2_out", "video_pll1_out", };
++ "audio_pll2_out", "video_pll_out", };
+
+ static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+@@ -306,9 +306,9 @@ static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "du
+ "dummy", "sys_pll1_80m", };
+ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
+ "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
+- "video_pll1_out", "osc_32k", };
++ "video_pll_out", "osc_32k", };
+
+-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
++static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
+ "dummy", "dummy", "gpu_pll_out", "dummy",
+ "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+ "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+@@ -349,19 +349,19 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+
+ hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+- hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
++ hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+- hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
++ hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+ hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
+ hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
+- hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
++ hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
+ hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
+ hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
+- hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
++ hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll);
+ hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
+ hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+ hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+@@ -370,20 +370,20 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ /* PLL bypass out */
+ hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+- hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
++ hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+- hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
++ hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* PLL out gate */
+ hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+ hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+- hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
++ hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
+ hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+ hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
+- hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
++ hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11);
+ hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
+ hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index 652ae58c2735f..5d68d975b4eb1 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -17,6 +17,7 @@
+
+ static u32 share_count_nand;
+ static u32 share_count_media;
++static u32 share_count_usb;
+
+ static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+@@ -673,7 +674,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
+ hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
+ hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
+- hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0);
++ hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb);
++ hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb);
+ hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
+ hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
+ hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
+diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
+index dcc41d178238e..2e99c3443d3c3 100644
+--- a/drivers/clk/imx/clk-imx93.c
++++ b/drivers/clk/imx/clk-imx93.c
+@@ -162,7 +162,7 @@ static const struct imx93_clk_ccgr {
+ { IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, },
+ { IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, },
+ { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, },
+- { IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, },
++ { IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, },
+ { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, },
+ { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, },
+ { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, },
+@@ -229,7 +229,7 @@ static const struct imx93_clk_ccgr {
+ { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, },
+ { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, },
+ { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, },
+- { IMX93_CLK_ENET1_GATE, "enet1", "enet_root", 0x9e00, },
++ { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, },
+ { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, },
+ { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, },
+ { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, },
+@@ -247,7 +247,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ struct device_node *np = dev->of_node;
+ const struct imx93_clk_root *root;
+ const struct imx93_clk_ccgr *ccgr;
+- void __iomem *base = NULL;
++ void __iomem *base, *anatop_base;
+ int i, ret;
+
+ clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+@@ -274,20 +274,22 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ "sys_pll_pfd2", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop");
+- base = of_iomap(np, 0);
++ anatop_base = of_iomap(np, 0);
+ of_node_put(np);
+- if (WARN_ON(!base))
++ if (WARN_ON(!anatop_base))
+ return -ENOMEM;
+
+- clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200,
++ clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200,
+ &imx_fracn_gppll);
+- clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400,
++ clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", anatop_base + 0x1400,
+ &imx_fracn_gppll);
+
+ np = dev->of_node;
+ base = devm_platform_ioremap_resource(pdev, 0);
+- if (WARN_ON(IS_ERR(base)))
++ if (WARN_ON(IS_ERR(base))) {
++ iounmap(anatop_base);
+ return PTR_ERR(base);
++ }
+
+ for (i = 0; i < ARRAY_SIZE(root_array); i++) {
+ root = &root_array[i];
+@@ -317,6 +319,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+
+ unregister_hws:
+ imx_unregister_hw_clocks(clks, IMX93_CLK_END);
++ iounmap(anatop_base);
+
+ return ret;
+ }
+diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
+index 9539d35588ee9..26108e9f7e67a 100644
+--- a/drivers/clk/imx/clk-imxrt1050.c
++++ b/drivers/clk/imx/clk-imxrt1050.c
+@@ -140,7 +140,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+ hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
+ hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
+ hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
+- hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
++ hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x70, 28);
+ hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
+ hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
+ imx_check_clk_hws(hws, IMXRT1050_CLK_END);
+diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+index d90727a53283c..49666047bf0ed 100644
+--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+@@ -153,7 +153,7 @@ static const struct mtk_gate infra_clks[] = {
+ 18),
+ GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+ 19),
+- GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
++ GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20),
+ GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+ GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+ /* INFRA2 */
+diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
+index 45da736bd5f4c..293a9dfa7151a 100644
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
+
+ if (d->lpl)
+ mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
++ else
++ mask <<= d->shift;
+
+ spin_lock_irqsave(&krait_clock_reg_lock, flags);
+ val = krait_get_l2_indirect_reg(d->offset);
+diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c
+index 0c3c2e26ede90..ea6f54ed846ec 100644
+--- a/drivers/clk/qcom/dispcc-sm6350.c
++++ b/drivers/clk/qcom/dispcc-sm6350.c
+@@ -306,7 +306,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+ .name = "disp_cc_mdss_pclk0_clk_src",
+ .parent_data = disp_cc_parent_data_5,
+ .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_pixel_ops,
+ },
+ };
+@@ -385,7 +385,7 @@ static struct clk_branch disp_cc_mdss_byte0_clk = {
+ &disp_cc_mdss_byte0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_branch2_ops,
+ },
+ },
+diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
+index 718de17a1e600..6447f3e81b555 100644
+--- a/drivers/clk/qcom/gcc-ipq806x.c
++++ b/drivers/clk/qcom/gcc-ipq806x.c
+@@ -79,7 +79,9 @@ static struct clk_regmap pll4_vote = {
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pll4_vote",
+- .parent_names = (const char *[]){ "pll4" },
++ .parent_data = &(const struct clk_parent_data){
++ .fw_name = "pll4", .name = "pll4",
++ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c
+index 9755ef4888c19..a0ba37656b07b 100644
+--- a/drivers/clk/qcom/gcc-sm8250.c
++++ b/drivers/clk/qcom/gcc-sm8250.c
+@@ -3267,7 +3267,7 @@ static struct gdsc usb30_prim_gdsc = {
+ .pd = {
+ .name = "usb30_prim_gdsc",
+ },
+- .pwrsts = PWRSTS_OFF_ON,
++ .pwrsts = PWRSTS_RET_ON,
+ };
+
+ static struct gdsc usb30_sec_gdsc = {
+@@ -3275,7 +3275,7 @@ static struct gdsc usb30_sec_gdsc = {
+ .pd = {
+ .name = "usb30_sec_gdsc",
+ },
+- .pwrsts = PWRSTS_OFF_ON,
++ .pwrsts = PWRSTS_RET_ON,
+ };
+
+ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
+diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+index 6ab6e5a34c724..b2646b7e13c9f 100644
+--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c
++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+@@ -12,6 +12,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+
++#include <dt-bindings/clock/qcom,lpass-sc7280.h>
+ #include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
+
+ #include "clk-alpha-pll.h"
+@@ -22,6 +23,7 @@
+ #include "clk-regmap-mux.h"
+ #include "common.h"
+ #include "gdsc.h"
++#include "reset.h"
+
+ enum {
+ P_BI_TCXO,
+@@ -38,6 +40,32 @@ static const struct pll_vco zonda_vco[] = {
+ { 595200000UL, 3600000000UL, 0 },
+ };
+
++static struct clk_branch lpass_q6ss_ahbm_clk = {
++ .halt_reg = 0x901c,
++ .halt_check = BRANCH_HALT,
++ .clkr = {
++ .enable_reg = 0x901c,
++ .enable_mask = BIT(0),
++ .hw.init = &(struct clk_init_data){
++ .name = "lpass_q6ss_ahbm_clk",
++ .ops = &clk_branch2_ops,
++ },
++ },
++};
++
++static struct clk_branch lpass_q6ss_ahbs_clk = {
++ .halt_reg = 0x9020,
++ .halt_check = BRANCH_HALT_VOTED,
++ .clkr = {
++ .enable_reg = 0x9020,
++ .enable_mask = BIT(0),
++ .hw.init = &(struct clk_init_data){
++ .name = "lpass_q6ss_ahbs_clk",
++ .ops = &clk_branch2_ops,
++ },
++ },
++};
++
+ /* 1128.96MHz configuration */
+ static const struct alpha_pll_config lpass_audio_cc_pll_config = {
+ .l = 0x3a,
+@@ -221,7 +249,7 @@ static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = {
+ .parent_data = lpass_aon_cc_parent_data_0,
+ .num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0),
+ .flags = CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -614,6 +642,11 @@ static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = {
+ .flags = RETAIN_FF_ENABLE,
+ };
+
++static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
++ [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
++ [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
++};
++
+ static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = {
+ [LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr,
+ [LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr,
+@@ -659,45 +692,47 @@ static struct regmap_config lpass_audio_cc_sc7280_regmap_config = {
+ .fast_io = true,
+ };
+
++static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
++ .config = &lpass_audio_cc_sc7280_regmap_config,
++ .clks = lpass_cc_sc7280_clocks,
++ .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
++};
++
+ static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = {
+ .config = &lpass_audio_cc_sc7280_regmap_config,
+ .clks = lpass_audio_cc_sc7280_clocks,
+ .num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks),
+ };
+
++static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = {
++ [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 },
++ [LPASS_AUDIO_SWR_TX_CGCR] = { 0xa8, 1 },
++ [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 },
++};
++
++static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = {
++ .config = &lpass_audio_cc_sc7280_regmap_config,
++ .resets = lpass_audio_cc_sc7280_resets,
++ .num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets),
++};
++
+ static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = {
+ { .compatible = "qcom,sc7280-lpassaudiocc" },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table);
+
+-static void lpassaudio_pm_runtime_disable(void *data)
+-{
+- pm_runtime_disable(data);
+-}
+-
+-static void lpassaudio_pm_clk_destroy(void *data)
+-{
+- pm_clk_destroy(data);
+-}
+-
+-static int lpassaudio_create_pm_clks(struct platform_device *pdev)
++static int lpass_audio_setup_runtime_pm(struct platform_device *pdev)
+ {
+ int ret;
+
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+- pm_runtime_enable(&pdev->dev);
+-
+- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_runtime_disable, &pdev->dev);
+- if (ret)
+- return ret;
+-
+- ret = pm_clk_create(&pdev->dev);
++ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
+ return ret;
+
+- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_clk_destroy, &pdev->dev);
++ ret = devm_pm_clk_create(&pdev->dev);
+ if (ret)
+ return ret;
+
+@@ -705,7 +740,7 @@ static int lpassaudio_create_pm_clks(struct platform_device *pdev)
+ if (ret < 0)
+ dev_err(&pdev->dev, "failed to acquire iface clock\n");
+
+- return ret;
++ return pm_runtime_resume_and_get(&pdev->dev);
+ }
+
+ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+@@ -714,7 +749,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+ struct regmap *regmap;
+ int ret;
+
+- ret = lpassaudio_create_pm_clks(pdev);
++ ret = lpass_audio_setup_runtime_pm(pdev);
+ if (ret)
+ return ret;
+
+@@ -724,8 +759,8 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+
+ regmap = qcom_cc_map(pdev, desc);
+ if (IS_ERR(regmap)) {
+- pm_runtime_disable(&pdev->dev);
+- return PTR_ERR(regmap);
++ ret = PTR_ERR(regmap);
++ goto exit;
+ }
+
+ clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config);
+@@ -734,16 +769,21 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+ regmap_write(regmap, 0x4, 0x3b);
+ regmap_write(regmap, 0x8, 0xff05);
+
+- ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap);
++ ret = qcom_cc_probe_by_index(pdev, 0, &lpass_audio_cc_sc7280_desc);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n");
+- pm_runtime_disable(&pdev->dev);
+- return ret;
++ goto exit;
++ }
++
++ ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc);
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n");
++ goto exit;
+ }
+
+ pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ pm_runtime_put_autosuspend(&pdev->dev);
+- pm_runtime_put_sync(&pdev->dev);
+
+ return ret;
+ }
+@@ -781,27 +821,38 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev)
+ struct regmap *regmap;
+ int ret;
+
+- ret = lpassaudio_create_pm_clks(pdev);
++ ret = lpass_audio_setup_runtime_pm(pdev);
+ if (ret)
+ return ret;
+
++ if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
++ lpass_audio_cc_sc7280_regmap_config.name = "cc";
++ desc = &lpass_cc_sc7280_desc;
++ ret = qcom_cc_probe(pdev, desc);
++ goto exit;
++ }
++
+ lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon";
+ lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008;
+ desc = &lpass_aon_cc_sc7280_desc;
+
+ regmap = qcom_cc_map(pdev, desc);
+- if (IS_ERR(regmap))
+- return PTR_ERR(regmap);
++ if (IS_ERR(regmap)) {
++ ret = PTR_ERR(regmap);
++ goto exit;
++ }
+
+ clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config);
+
+ ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap);
+- if (ret)
++ if (ret) {
+ dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n");
++ goto exit;
++ }
+
+ pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ pm_runtime_put_autosuspend(&pdev->dev);
+- pm_runtime_put_sync(&pdev->dev);
+
+ return ret;
+ }
+diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c
+index b39ee1c9647bc..5c1e17bd0d763 100644
+--- a/drivers/clk/qcom/lpasscc-sc7280.c
++++ b/drivers/clk/qcom/lpasscc-sc7280.c
+@@ -17,32 +17,6 @@
+ #include "clk-branch.h"
+ #include "common.h"
+
+-static struct clk_branch lpass_q6ss_ahbm_clk = {
+- .halt_reg = 0x1c,
+- .halt_check = BRANCH_HALT,
+- .clkr = {
+- .enable_reg = 0x1c,
+- .enable_mask = BIT(0),
+- .hw.init = &(struct clk_init_data){
+- .name = "lpass_q6ss_ahbm_clk",
+- .ops = &clk_branch2_ops,
+- },
+- },
+-};
+-
+-static struct clk_branch lpass_q6ss_ahbs_clk = {
+- .halt_reg = 0x20,
+- .halt_check = BRANCH_HALT_VOTED,
+- .clkr = {
+- .enable_reg = 0x20,
+- .enable_mask = BIT(0),
+- .hw.init = &(struct clk_init_data){
+- .name = "lpass_q6ss_ahbs_clk",
+- .ops = &clk_branch2_ops,
+- },
+- },
+-};
+-
+ static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = {
+ .halt_reg = 0x0,
+ .halt_check = BRANCH_HALT,
+@@ -105,17 +79,6 @@ static struct regmap_config lpass_regmap_config = {
+ .fast_io = true,
+ };
+
+-static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
+- [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
+- [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
+-};
+-
+-static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
+- .config = &lpass_regmap_config,
+- .clks = lpass_cc_sc7280_clocks,
+- .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
+-};
+-
+ static struct clk_regmap *lpass_cc_top_sc7280_clocks[] = {
+ [LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK] =
+ &lpass_top_cc_lpi_q6_axim_hs_clk.clkr,
+@@ -169,13 +132,6 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
+ if (ret)
+ goto destroy_pm_clk;
+
+- lpass_regmap_config.name = "cc";
+- desc = &lpass_cc_sc7280_desc;
+-
+- ret = qcom_cc_probe_by_index(pdev, 2, desc);
+- if (ret)
+- goto destroy_pm_clk;
+-
+ return 0;
+
+ destroy_pm_clk:
+diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c
+index ac09b7b840aba..a5731994cbed1 100644
+--- a/drivers/clk/qcom/lpasscorecc-sc7180.c
++++ b/drivers/clk/qcom/lpasscorecc-sc7180.c
+@@ -356,7 +356,7 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
+ .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
+ };
+
+-static int lpass_create_pm_clks(struct platform_device *pdev)
++static int lpass_setup_runtime_pm(struct platform_device *pdev)
+ {
+ int ret;
+
+@@ -375,7 +375,7 @@ static int lpass_create_pm_clks(struct platform_device *pdev)
+ if (ret < 0)
+ dev_err(&pdev->dev, "failed to acquire iface clock\n");
+
+- return ret;
++ return pm_runtime_resume_and_get(&pdev->dev);
+ }
+
+ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+@@ -384,7 +384,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ struct regmap *regmap;
+ int ret;
+
+- ret = lpass_create_pm_clks(pdev);
++ ret = lpass_setup_runtime_pm(pdev);
+ if (ret)
+ return ret;
+
+@@ -392,12 +392,14 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ desc = &lpass_audio_hm_sc7180_desc;
+ ret = qcom_cc_probe_by_index(pdev, 1, desc);
+ if (ret)
+- return ret;
++ goto exit;
+
+ lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc";
+ regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc);
+- if (IS_ERR(regmap))
+- return PTR_ERR(regmap);
++ if (IS_ERR(regmap)) {
++ ret = PTR_ERR(regmap);
++ goto exit;
++ }
+
+ /*
+ * Keep the CLK always-ON
+@@ -415,6 +417,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
+
+ pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ pm_runtime_put_autosuspend(&pdev->dev);
+
+ return ret;
+@@ -425,14 +428,19 @@ static int lpass_hm_core_probe(struct platform_device *pdev)
+ const struct qcom_cc_desc *desc;
+ int ret;
+
+- ret = lpass_create_pm_clks(pdev);
++ ret = lpass_setup_runtime_pm(pdev);
+ if (ret)
+ return ret;
+
+ lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core";
+ desc = &lpass_core_hm_sc7180_desc;
+
+- return qcom_cc_probe_by_index(pdev, 0, desc);
++ ret = qcom_cc_probe_by_index(pdev, 0, desc);
++
++ pm_runtime_mark_last_busy(&pdev->dev);
++ pm_runtime_put_autosuspend(&pdev->dev);
++
++ return ret;
+ }
+
+ static const struct of_device_id lpass_hm_sc7180_match_table[] = {
+diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c
+index 1f1f1bd1b68ef..6ad19b06b1ce3 100644
+--- a/drivers/clk/qcom/lpasscorecc-sc7280.c
++++ b/drivers/clk/qcom/lpasscorecc-sc7280.c
+@@ -190,6 +190,19 @@ static struct clk_rcg2 lpass_core_cc_ext_if1_clk_src = {
+ },
+ };
+
++static struct clk_rcg2 lpass_core_cc_ext_mclk0_clk_src = {
++ .cmd_rcgr = 0x20000,
++ .mnd_width = 8,
++ .hid_width = 5,
++ .parent_map = lpass_core_cc_parent_map_0,
++ .freq_tbl = ftbl_lpass_core_cc_ext_if0_clk_src,
++ .clkr.hw.init = &(const struct clk_init_data){
++ .name = "lpass_core_cc_ext_mclk0_clk_src",
++ .parent_data = lpass_core_cc_parent_data_0,
++ .num_parents = ARRAY_SIZE(lpass_core_cc_parent_data_0),
++ .ops = &clk_rcg2_ops,
++ },
++};
+
+ static struct clk_branch lpass_core_cc_core_clk = {
+ .halt_reg = 0x1f000,
+@@ -283,6 +296,24 @@ static struct clk_branch lpass_core_cc_lpm_mem0_core_clk = {
+ },
+ };
+
++static struct clk_branch lpass_core_cc_ext_mclk0_clk = {
++ .halt_reg = 0x20014,
++ .halt_check = BRANCH_HALT,
++ .clkr = {
++ .enable_reg = 0x20014,
++ .enable_mask = BIT(0),
++ .hw.init = &(const struct clk_init_data){
++ .name = "lpass_core_cc_ext_mclk0_clk",
++ .parent_hws = (const struct clk_hw*[]){
++ &lpass_core_cc_ext_mclk0_clk_src.clkr.hw,
++ },
++ .num_parents = 1,
++ .flags = CLK_SET_RATE_PARENT,
++ .ops = &clk_branch2_ops,
++ },
++ },
++};
++
+ static struct clk_branch lpass_core_cc_sysnoc_mport_core_clk = {
+ .halt_reg = 0x23000,
+ .halt_check = BRANCH_HALT_VOTED,
+@@ -326,6 +357,8 @@ static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = {
+ [LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr,
+ [LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr,
+ [LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr,
++ [LPASS_CORE_CC_EXT_MCLK0_CLK] = &lpass_core_cc_ext_mclk0_clk.clkr,
++ [LPASS_CORE_CC_EXT_MCLK0_CLK_SRC] = &lpass_core_cc_ext_mclk0_clk_src.clkr,
+ };
+
+ static struct regmap_config lpass_core_cc_sc7280_regmap_config = {
+diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+index d74d46833012f..e02542ca24a06 100644
+--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+@@ -116,7 +116,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
+ DEF_FIXED("cp", R8A779A0_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cl16mck", R8A779A0_CLK_CL16MCK, CLK_PLL1_DIV2, 64, 1),
+
+- DEF_GEN4_SDH("sdh0", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870),
++ DEF_GEN4_SDH("sd0h", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870),
+ DEF_GEN4_SD("sd0", R8A779A0_CLK_SD0, R8A779A0_CLK_SD0H, 0x870),
+
+ DEF_BASE("rpc", R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+index cd80b6084eceb..ab104a25a6019 100644
+--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+@@ -108,7 +108,13 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
+ DEF_FIXED("cbfusa", R8A779F0_CLK_CBFUSA, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A779F0_CLK_CPEX, CLK_EXTAL, 2, 1),
+
+- DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, CLK_SDSRC, 0x870),
++ DEF_FIXED("sasyncrt", R8A779F0_CLK_SASYNCRT, CLK_PLL5_DIV4, 48, 1),
++ DEF_FIXED("sasyncperd1", R8A779F0_CLK_SASYNCPERD1, CLK_PLL5_DIV4, 3, 1),
++ DEF_FIXED("sasyncperd2", R8A779F0_CLK_SASYNCPERD2, R8A779F0_CLK_SASYNCPERD1, 2, 1),
++ DEF_FIXED("sasyncperd4", R8A779F0_CLK_SASYNCPERD4, R8A779F0_CLK_SASYNCPERD1, 4, 1),
++
++ DEF_GEN4_SDH("sd0h", R8A779F0_CLK_SD0H, CLK_SDSRC, 0x870),
++ DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, R8A779F0_CLK_SD0H, 0x870),
+
+ DEF_BASE("rpc", R8A779F0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A779F0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
+@@ -120,10 +126,10 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
+ };
+
+ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+- DEF_MOD("hscif0", 514, R8A779F0_CLK_S0D3),
+- DEF_MOD("hscif1", 515, R8A779F0_CLK_S0D3),
+- DEF_MOD("hscif2", 516, R8A779F0_CLK_S0D3),
+- DEF_MOD("hscif3", 517, R8A779F0_CLK_S0D3),
++ DEF_MOD("hscif0", 514, R8A779F0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif1", 515, R8A779F0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif2", 516, R8A779F0_CLK_SASYNCPERD1),
++ DEF_MOD("hscif3", 517, R8A779F0_CLK_SASYNCPERD1),
+ DEF_MOD("i2c0", 518, R8A779F0_CLK_S0D6_PER),
+ DEF_MOD("i2c1", 519, R8A779F0_CLK_S0D6_PER),
+ DEF_MOD("i2c2", 520, R8A779F0_CLK_S0D6_PER),
+@@ -132,13 +138,18 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+ DEF_MOD("i2c5", 523, R8A779F0_CLK_S0D6_PER),
+ DEF_MOD("pcie0", 624, R8A779F0_CLK_S0D2),
+ DEF_MOD("pcie1", 625, R8A779F0_CLK_S0D2),
+- DEF_MOD("scif0", 702, R8A779F0_CLK_S0D12_PER),
+- DEF_MOD("scif1", 703, R8A779F0_CLK_S0D12_PER),
+- DEF_MOD("scif3", 704, R8A779F0_CLK_S0D12_PER),
+- DEF_MOD("scif4", 705, R8A779F0_CLK_S0D12_PER),
++ DEF_MOD("scif0", 702, R8A779F0_CLK_SASYNCPERD4),
++ DEF_MOD("scif1", 703, R8A779F0_CLK_SASYNCPERD4),
++ DEF_MOD("scif3", 704, R8A779F0_CLK_SASYNCPERD4),
++ DEF_MOD("scif4", 705, R8A779F0_CLK_SASYNCPERD4),
+ DEF_MOD("sdhi0", 706, R8A779F0_CLK_SD0),
+ DEF_MOD("sys-dmac0", 709, R8A779F0_CLK_S0D3_PER),
+ DEF_MOD("sys-dmac1", 710, R8A779F0_CLK_S0D3_PER),
++ DEF_MOD("tmu0", 713, R8A779F0_CLK_SASYNCRT),
++ DEF_MOD("tmu1", 714, R8A779F0_CLK_SASYNCPERD2),
++ DEF_MOD("tmu2", 715, R8A779F0_CLK_SASYNCPERD2),
++ DEF_MOD("tmu3", 716, R8A779F0_CLK_SASYNCPERD2),
++ DEF_MOD("tmu4", 717, R8A779F0_CLK_SASYNCPERD2),
+ DEF_MOD("wdt", 907, R8A779F0_CLK_R),
+ DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M),
+ DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M),
+diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
+index 1488c9d6e6394..983faa5707b9c 100644
+--- a/drivers/clk/renesas/r9a06g032-clocks.c
++++ b/drivers/clk/renesas/r9a06g032-clocks.c
+@@ -412,7 +412,7 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+ int error;
+ int index;
+
+- while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
++ while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++,
+ &clkspec)) {
+ if (clkspec.np != pd->dev.of_node)
+ continue;
+@@ -425,7 +425,6 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+ if (error)
+ return error;
+ }
+- i++;
+ }
+
+ return 0;
+diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
+index f7827b3b7fc1c..6e5e502be44a6 100644
+--- a/drivers/clk/rockchip/clk-pll.c
++++ b/drivers/clk/rockchip/clk-pll.c
+@@ -981,6 +981,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+ return mux_clk;
+
+ err_pll:
++ kfree(pll->rate_table);
+ clk_unregister(mux_clk);
+ mux_clk = pll_clk;
+ err_mux:
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index fe383471c5f0a..0ff28938943f0 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -1583,6 +1583,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
+ if (ret) {
+ pr_err("%s: failed to register pll clock %s : %d\n",
+ __func__, pll_clk->name, ret);
++ kfree(pll->rate_table);
+ kfree(pll);
+ return;
+ }
+diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
+index 53d6e3ec4309f..c94b59b80dd43 100644
+--- a/drivers/clk/socfpga/clk-gate.c
++++ b/drivers/clk/socfpga/clk-gate.c
+@@ -188,8 +188,10 @@ void __init socfpga_gate_init(struct device_node *node)
+ return;
+
+ ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
+- if (WARN_ON(!ops))
++ if (WARN_ON(!ops)) {
++ kfree(socfpga_clk);
+ return;
++ }
+
+ rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
+ if (rc)
+@@ -243,6 +245,7 @@ void __init socfpga_gate_init(struct device_node *node)
+
+ err = clk_hw_register(NULL, hw_clk);
+ if (err) {
++ kfree(ops);
+ kfree(socfpga_clk);
+ return;
+ }
+diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
+index d820292a381d0..40df1db102a77 100644
+--- a/drivers/clk/st/clkgen-fsyn.c
++++ b/drivers/clk/st/clkgen-fsyn.c
+@@ -1020,9 +1020,10 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+
+ clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data,
+ reg, lock);
+- if (IS_ERR(clk))
++ if (IS_ERR(clk)) {
++ kfree(lock);
+ goto err_exit;
+- else
++ } else
+ pr_debug("%s: parent %s rate %u\n",
+ __clk_get_name(clk),
+ __clk_get_name(clk_get_parent(clk)),
+diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
+index a484cb945d67b..1f3234f226674 100644
+--- a/drivers/clk/visconti/pll.c
++++ b/drivers/clk/visconti/pll.c
+@@ -277,6 +277,7 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx,
+ ret = clk_hw_register(NULL, &pll->hw);
+ if (ret) {
+ pr_err("failed to register pll clock %s : %d\n", name, ret);
++ kfree(pll->rate_table);
+ kfree(pll);
+ pll_hw_clk = ERR_PTR(ret);
+ }
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 64dcb082d4cf6..7b952aa52c0b9 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/ioport.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+@@ -116,6 +117,7 @@ struct sh_cmt_device {
+ void __iomem *mapbase;
+ struct clk *clk;
+ unsigned long rate;
++ unsigned int reg_delay;
+
+ raw_spinlock_t lock; /* Protect the shared start/stop register */
+
+@@ -247,10 +249,17 @@ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
+
+ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value)
+ {
+- if (ch->iostart)
+- ch->cmt->info->write_control(ch->iostart, 0, value);
+- else
+- ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++ u32 old_value = sh_cmt_read_cmstr(ch);
++
++ if (value != old_value) {
++ if (ch->iostart) {
++ ch->cmt->info->write_control(ch->iostart, 0, value);
++ udelay(ch->cmt->reg_delay);
++ } else {
++ ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++ udelay(ch->cmt->reg_delay);
++ }
++ }
+ }
+
+ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+@@ -260,7 +269,12 @@ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+
+ static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value)
+ {
+- ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++ u32 old_value = sh_cmt_read_cmcsr(ch);
++
++ if (value != old_value) {
++ ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++ udelay(ch->cmt->reg_delay);
++ }
+ }
+
+ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+@@ -268,14 +282,33 @@ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+ return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
+ }
+
+-static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
++static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
+ {
++ /* Tests showed that we need to wait 3 clocks here */
++ unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2);
++ u32 reg;
++
++ if (ch->cmt->info->model > SH_CMT_16BIT) {
++ int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg,
++ !(reg & SH_CMT32_CMCSR_WRFLG),
++ 1, cmcnt_delay, false, ch);
++ if (ret < 0)
++ return ret;
++ }
++
+ ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
++ udelay(cmcnt_delay);
++ return 0;
+ }
+
+ static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value)
+ {
+- ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++ u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR);
++
++ if (value != old_value) {
++ ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++ udelay(ch->cmt->reg_delay);
++ }
+ }
+
+ static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped)
+@@ -319,7 +352,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
+
+ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+ {
+- int k, ret;
++ int ret;
+
+ dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
+
+@@ -347,26 +380,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+ }
+
+ sh_cmt_write_cmcor(ch, 0xffffffff);
+- sh_cmt_write_cmcnt(ch, 0);
+-
+- /*
+- * According to the sh73a0 user's manual, as CMCNT can be operated
+- * only by the RCLK (Pseudo 32 kHz), there's one restriction on
+- * modifying CMCNT register; two RCLK cycles are necessary before
+- * this register is either read or any modification of the value
+- * it holds is reflected in the LSI's actual operation.
+- *
+- * While at it, we're supposed to clear out the CMCNT as of this
+- * moment, so make sure it's processed properly here. This will
+- * take RCLKx2 at maximum.
+- */
+- for (k = 0; k < 100; k++) {
+- if (!sh_cmt_read_cmcnt(ch))
+- break;
+- udelay(1);
+- }
++ ret = sh_cmt_write_cmcnt(ch, 0);
+
+- if (sh_cmt_read_cmcnt(ch)) {
++ if (ret || sh_cmt_read_cmcnt(ch)) {
+ dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+ ch->index);
+ ret = -ETIMEDOUT;
+@@ -995,8 +1011,8 @@ MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+
+ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ {
+- unsigned int mask;
+- unsigned int i;
++ unsigned int mask, i;
++ unsigned long rate;
+ int ret;
+
+ cmt->pdev = pdev;
+@@ -1032,10 +1048,16 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ if (ret < 0)
+ goto err_clk_unprepare;
+
+- if (cmt->info->width == 16)
+- cmt->rate = clk_get_rate(cmt->clk) / 512;
+- else
+- cmt->rate = clk_get_rate(cmt->clk) / 8;
++ rate = clk_get_rate(cmt->clk);
++ if (!rate) {
++ ret = -EINVAL;
++ goto err_clk_disable;
++ }
++
++ /* We shall wait 2 input clks after register writes */
++ if (cmt->info->model >= SH_CMT_48BIT)
++ cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate);
++ cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8);
+
+ /* Map the memory resource(s). */
+ ret = sh_cmt_map_memory(cmt);
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index 2737407ff0698..632523c1232f6 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t,
+ return error;
+
+ r = clk_get_rate(clock);
+- if (!r)
++ if (!r) {
++ clk_disable_unprepare(clock);
+ return -ENODEV;
++ }
+
+ if (is_ick)
+ t->ick = clock;
+diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
+index 469f7c91564b6..78c2c038d3ae4 100644
+--- a/drivers/clocksource/timer-ti-dm.c
++++ b/drivers/clocksource/timer-ti-dm.c
+@@ -1081,7 +1081,7 @@ static struct platform_driver omap_dm_timer_driver = {
+ .remove = omap_dm_timer_remove,
+ .driver = {
+ .name = "omap_timer",
+- .of_match_table = of_match_ptr(omap_timer_match),
++ .of_match_table = omap_timer_match,
+ .pm = &omap_dm_timer_pm_ops,
+ },
+ };
+diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
+index 68031d93ce895..aee3b1a8aaa77 100644
+--- a/drivers/counter/stm32-lptimer-cnt.c
++++ b/drivers/counter/stm32-lptimer-cnt.c
+@@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
+
+ /* ensure CMP & ARR registers are properly written */
+ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
+- (val & STM32_LPTIM_CMPOK_ARROK),
++ (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
+ 100, 1000);
+ if (ret)
+ return ret;
+diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
+index 6448e03bcf488..59b19b9975e8c 100644
+--- a/drivers/cpufreq/amd_freq_sensitivity.c
++++ b/drivers/cpufreq/amd_freq_sensitivity.c
+@@ -125,6 +125,8 @@ static int __init amd_freq_sensitivity_init(void)
+ if (!pcidev) {
+ if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK))
+ return -ENODEV;
++ } else {
++ pci_dev_put(pcidev);
+ }
+
+ if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index bb32659820ceb..823b069203e1b 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -122,7 +122,35 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+ return 0;
+ }
+
++static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
++{
++ unsigned int lval;
++
++ if (data->soc_data->reg_current_vote)
++ lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff;
++ else
++ lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff;
++
++ return lval * xo_rate;
++}
++
++/* Get the current frequency of the CPU (after throttling) */
+ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
++{
++ struct qcom_cpufreq_data *data;
++ struct cpufreq_policy *policy;
++
++ policy = cpufreq_cpu_get_raw(cpu);
++ if (!policy)
++ return 0;
++
++ data = policy->driver_data;
++
++ return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;
++}
++
++/* Get the frequency requested by the cpufreq core for the CPU */
++static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
+ {
+ struct qcom_cpufreq_data *data;
+ const struct qcom_cpufreq_soc_data *soc_data;
+@@ -190,6 +218,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
+ }
+ } else if (ret != -ENODEV) {
+ dev_err(cpu_dev, "Invalid opp table in device tree\n");
++ kfree(table);
+ return ret;
+ } else {
+ policy->fast_switch_possible = true;
+@@ -283,18 +312,6 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
+ }
+ }
+
+-static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
+-{
+- unsigned int lval;
+-
+- if (data->soc_data->reg_current_vote)
+- lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff;
+- else
+- lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff;
+-
+- return lval * xo_rate;
+-}
+-
+ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ {
+ struct cpufreq_policy *policy = data->policy;
+@@ -336,7 +353,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ * If h/w throttled frequency is higher than what cpufreq has requested
+ * for, then stop polling and switch back to interrupt mechanism.
+ */
+- if (throttled_freq >= qcom_cpufreq_hw_get(cpu))
++ if (throttled_freq >= qcom_cpufreq_get_freq(cpu))
+ enable_irq(data->throttle_irq);
+ else
+ mod_delayed_work(system_highpri_wq, &data->throttle_work,
+diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
+index 252f2a9686a62..448bc796b0b40 100644
+--- a/drivers/cpuidle/dt_idle_states.c
++++ b/drivers/cpuidle/dt_idle_states.c
+@@ -223,6 +223,6 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
+ * also be 0 on platforms with missing DT idle states or legacy DT
+ * configuration predating the DT idle states bindings.
+ */
+- return i;
++ return state_idx - start_idx;
+ }
+ EXPORT_SYMBOL_GPL(dt_init_idle_driver);
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 3e6aa319920b7..79d9e14b70c87 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -669,7 +669,12 @@ config CRYPTO_DEV_IMGTEC_HASH
+ config CRYPTO_DEV_ROCKCHIP
+ tristate "Rockchip's Cryptographic Engine driver"
+ depends on OF && ARCH_ROCKCHIP
++ depends on PM
++ select CRYPTO_ECB
++ select CRYPTO_CBC
++ select CRYPTO_DES
+ select CRYPTO_AES
++ select CRYPTO_ENGINE
+ select CRYPTO_LIB_DES
+ select CRYPTO_MD5
+ select CRYPTO_SHA1
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index 910d6751644cf..902f6be057ec6 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -124,7 +124,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ struct sun8i_ss_flow *sf = &ss->flows[rctx->flow];
+ int i = 0;
+- u32 a;
++ dma_addr_t a;
+ int err;
+
+ rctx->ivlen = ivsize;
+diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
+index 6e7ae896717cd..937187027ad57 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
+@@ -237,7 +237,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
+ return err;
+ }
+
+- mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL);
+ for (i = 0; i < MAXFLOW; i++) {
+ mc->irqs[i] = platform_get_irq(pdev, i);
+ if (mc->irqs[i] < 0)
+diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
+index dc0f142324a3c..8c0746a1d6d43 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl.h
++++ b/drivers/crypto/amlogic/amlogic-gxl.h
+@@ -95,7 +95,7 @@ struct meson_dev {
+ struct device *dev;
+ struct meson_flow *chanlist;
+ atomic_t flow;
+- int *irqs;
++ int irqs[MAXFLOW];
+ #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ struct dentry *dbgfs_dir;
+ #endif
+diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+index 9e7308e39b304..d4e06999af9b7 100644
+--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+@@ -195,6 +195,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev)
+ ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0);
+ if (!ndev->iov.pf2vf_wq) {
+ kfree(ndev->iov.vfdev);
++ ndev->iov.vfdev = NULL;
+ return -ENOMEM;
+ }
+ /* enable pf2vf mailbox interrupts */
+diff --git a/drivers/crypto/ccree/cc_debugfs.c b/drivers/crypto/ccree/cc_debugfs.c
+index 7083767602fcf..8f008f024f8f1 100644
+--- a/drivers/crypto/ccree/cc_debugfs.c
++++ b/drivers/crypto/ccree/cc_debugfs.c
+@@ -55,7 +55,7 @@ void __init cc_debugfs_global_init(void)
+ cc_debugfs_dir = debugfs_create_dir("ccree", NULL);
+ }
+
+-void __exit cc_debugfs_global_fini(void)
++void cc_debugfs_global_fini(void)
+ {
+ debugfs_remove(cc_debugfs_dir);
+ }
+diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c
+index cadead18b59e8..d489c6f808925 100644
+--- a/drivers/crypto/ccree/cc_driver.c
++++ b/drivers/crypto/ccree/cc_driver.c
+@@ -651,9 +651,17 @@ static struct platform_driver ccree_driver = {
+
+ static int __init ccree_init(void)
+ {
++ int rc;
++
+ cc_debugfs_global_init();
+
+- return platform_driver_register(&ccree_driver);
++ rc = platform_driver_register(&ccree_driver);
++ if (rc) {
++ cc_debugfs_global_fini();
++ return rc;
++ }
++
++ return 0;
+ }
+ module_init(ccree_init);
+
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
+index 9d529df0eab9b..7a50ca664ada1 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
+@@ -457,7 +457,7 @@ static void hpre_open_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ /* Enable prefetch */
+@@ -478,7 +478,7 @@ static void hpre_close_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ val = readl_relaxed(qm->io_base + HPRE_PREFETCH_CFG);
+@@ -1287,18 +1287,12 @@ err_with_qm_init:
+ static void hpre_remove(struct pci_dev *pdev)
+ {
+ struct hisi_qm *qm = pci_get_drvdata(pdev);
+- int ret;
+
+ hisi_qm_pm_uninit(qm);
+ hisi_qm_wait_task_finish(qm, &hpre_devices);
+ hisi_qm_alg_unregister(qm, &hpre_devices);
+- if (qm->fun_type == QM_HW_PF && qm->vfs_num) {
+- ret = hisi_qm_sriov_disable(pdev, true);
+- if (ret) {
+- pci_err(pdev, "Disable SRIOV fail!\n");
+- return;
+- }
+- }
++ if (qm->fun_type == QM_HW_PF && qm->vfs_num)
++ hisi_qm_sriov_disable(pdev, true);
+
+ hpre_debugfs_exit(qm);
+ hisi_qm_stop(qm, QM_NORMAL);
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index 9fa2efe601537..959f4846aa233 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -86,9 +86,7 @@
+ #define QM_DB_CMD_SHIFT_V1 16
+ #define QM_DB_INDEX_SHIFT_V1 32
+ #define QM_DB_PRIORITY_SHIFT_V1 48
+-#define QM_QUE_ISO_CFG_V 0x0030
+ #define QM_PAGE_SIZE 0x0034
+-#define QM_QUE_ISO_EN 0x100154
+ #define QM_CAPBILITY 0x100158
+ #define QM_QP_NUN_MASK GENMASK(10, 0)
+ #define QM_QP_DB_INTERVAL 0x10000
+@@ -205,6 +203,8 @@
+ #define MAX_WAIT_COUNTS 1000
+ #define QM_CACHE_WB_START 0x204
+ #define QM_CACHE_WB_DONE 0x208
++#define QM_FUNC_CAPS_REG 0x3100
++#define QM_CAPBILITY_VERSION GENMASK(7, 0)
+
+ #define PCI_BAR_2 2
+ #define PCI_BAR_4 4
+@@ -252,7 +252,6 @@
+ #define QM_QOS_MIN_CIR_B 100
+ #define QM_QOS_MAX_CIR_U 6
+ #define QM_QOS_MAX_CIR_S 11
+-#define QM_QOS_VAL_MAX_LEN 32
+ #define QM_DFX_BASE 0x0100000
+ #define QM_DFX_STATE1 0x0104000
+ #define QM_DFX_STATE2 0x01040C8
+@@ -329,6 +328,22 @@ enum qm_mb_cmd {
+ QM_VF_GET_QOS,
+ };
+
++static const struct hisi_qm_cap_info qm_cap_info_comm[] = {
++ {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0},
++ {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1},
++ {QM_SUPPORT_STOP_QP, 0x3100, 0, BIT(9), 0x0, 0x0, 0x1},
++ {QM_SUPPORT_MB_COMMAND, 0x3100, 0, BIT(11), 0x0, 0x0, 0x1},
++ {QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1},
++};
++
++static const struct hisi_qm_cap_info qm_cap_info_pf[] = {
++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(13), 0x0, 0x0, 0x1},
++};
++
++static const struct hisi_qm_cap_info qm_cap_info_vf[] = {
++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(12), 0x0, 0x0, 0x0},
++};
++
+ struct qm_cqe {
+ __le32 rsvd0;
+ __le16 cmd_id;
+@@ -426,10 +441,7 @@ struct hisi_qm_hw_ops {
+ void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe);
+ void (*hw_error_uninit)(struct hisi_qm *qm);
+ enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm);
+- int (*stop_qp)(struct hisi_qp *qp);
+ int (*set_msi)(struct hisi_qm *qm, bool set);
+- int (*ping_all_vfs)(struct hisi_qm *qm, u64 cmd);
+- int (*ping_pf)(struct hisi_qm *qm, u64 cmd);
+ };
+
+ struct qm_dfx_item {
+@@ -828,6 +840,36 @@ static int qm_dev_mem_reset(struct hisi_qm *qm)
+ POLL_TIMEOUT);
+ }
+
++/**
++ * hisi_qm_get_hw_info() - Get device information.
++ * @qm: The qm which want to get information.
++ * @info_table: Array for storing device information.
++ * @index: Index in info_table.
++ * @is_read: Whether read from reg, 0: not support read from reg.
++ *
++ * This function returns device information the caller needs.
++ */
++u32 hisi_qm_get_hw_info(struct hisi_qm *qm,
++ const struct hisi_qm_cap_info *info_table,
++ u32 index, bool is_read)
++{
++ u32 val;
++
++ switch (qm->ver) {
++ case QM_HW_V1:
++ return info_table[index].v1_val;
++ case QM_HW_V2:
++ return info_table[index].v2_val;
++ default:
++ if (!is_read)
++ return info_table[index].v3_val;
++
++ val = readl(qm->io_base + info_table[index].offset);
++ return (val >> info_table[index].shift) & info_table[index].mask;
++ }
++}
++EXPORT_SYMBOL_GPL(hisi_qm_get_hw_info);
++
+ static u32 qm_get_irq_num_v1(struct hisi_qm *qm)
+ {
+ return QM_IRQ_NUM_V1;
+@@ -854,7 +896,7 @@ static int qm_pm_get_sync(struct hisi_qm *qm)
+ struct device *dev = &qm->pdev->dev;
+ int ret;
+
+- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ return 0;
+
+ ret = pm_runtime_resume_and_get(dev);
+@@ -870,7 +912,7 @@ static void qm_pm_put_sync(struct hisi_qm *qm)
+ {
+ struct device *dev = &qm->pdev->dev;
+
+- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ return;
+
+ pm_runtime_mark_last_busy(dev);
+@@ -1151,7 +1193,7 @@ static void qm_init_prefetch(struct hisi_qm *qm)
+ struct device *dev = &qm->pdev->dev;
+ u32 page_type = 0x0;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ switch (PAGE_SIZE) {
+@@ -1270,7 +1312,7 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
+ }
+ break;
+ case SHAPER_VFT:
+- if (qm->ver >= QM_HW_V3) {
++ if (factor) {
+ tmp = factor->cir_b |
+ (factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) |
+ (factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) |
+@@ -1288,10 +1330,13 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
+ static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type,
+ u32 fun_num, u32 base, u32 number)
+ {
+- struct qm_shaper_factor *factor = &qm->factor[fun_num];
++ struct qm_shaper_factor *factor = NULL;
+ unsigned int val;
+ int ret;
+
++ if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++ factor = &qm->factor[fun_num];
++
+ ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
+ val & BIT(0), POLL_PERIOD,
+ POLL_TIMEOUT);
+@@ -1349,7 +1394,7 @@ static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
+ }
+
+ /* init default shaper qos val */
+- if (qm->ver >= QM_HW_V3) {
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
+ ret = qm_shaper_init_vft(qm, fun_num);
+ if (ret)
+ goto back_sqc_cqc;
+@@ -2495,7 +2540,7 @@ static int qm_wait_vf_prepare_finish(struct hisi_qm *qm)
+ u64 val;
+ u32 i;
+
+- if (!qm->vfs_num || qm->ver < QM_HW_V3)
++ if (!qm->vfs_num || !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ return 0;
+
+ while (true) {
+@@ -2780,10 +2825,7 @@ static const struct hisi_qm_hw_ops qm_hw_ops_v3 = {
+ .hw_error_init = qm_hw_error_init_v3,
+ .hw_error_uninit = qm_hw_error_uninit_v3,
+ .hw_error_handle = qm_hw_error_handle_v2,
+- .stop_qp = qm_stop_qp,
+ .set_msi = qm_set_msi_v3,
+- .ping_all_vfs = qm_ping_all_vfs,
+- .ping_pf = qm_ping_pf,
+ };
+
+ static void *qm_get_avail_sqe(struct hisi_qp *qp)
+@@ -3080,8 +3122,8 @@ static int qm_drain_qp(struct hisi_qp *qp)
+ return 0;
+
+ /* Kunpeng930 supports drain qp by device */
+- if (qm->ops->stop_qp) {
+- ret = qm->ops->stop_qp(qp);
++ if (test_bit(QM_SUPPORT_STOP_QP, &qm->caps)) {
++ ret = qm_stop_qp(qp);
+ if (ret)
+ dev_err(dev, "Failed to stop qp(%u)!\n", qp->qp_id);
+ return ret;
+@@ -3312,7 +3354,7 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q,
+ if (qm->ver == QM_HW_V1) {
+ if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR)
+ return -EINVAL;
+- } else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) {
++ } else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
+ if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
+ QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE))
+ return -EINVAL;
+@@ -3466,7 +3508,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
+
+ if (qm->ver == QM_HW_V1)
+ mmio_page_nr = QM_DOORBELL_PAGE_NR;
+- else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation)
++ else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ mmio_page_nr = QM_DOORBELL_PAGE_NR +
+ QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE;
+ else
+@@ -3628,7 +3670,7 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
+ init_rwsem(&qm->qps_lock);
+ qm->qp_in_used = 0;
+ qm->misc_ctl = false;
+- if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V2) {
++ if (test_bit(QM_SUPPORT_RPM, &qm->caps)) {
+ if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev)))
+ dev_info(&pdev->dev, "_PS0 and _PR0 are not defined");
+ }
+@@ -3638,7 +3680,7 @@ static void qm_cmd_uninit(struct hisi_qm *qm)
+ {
+ u32 val;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ return;
+
+ val = readl(qm->io_base + QM_IFC_INT_MASK);
+@@ -3650,7 +3692,7 @@ static void qm_cmd_init(struct hisi_qm *qm)
+ {
+ u32 val;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ return;
+
+ /* Clear communication interrupt source */
+@@ -3666,7 +3708,7 @@ static void qm_put_pci_res(struct hisi_qm *qm)
+ {
+ struct pci_dev *pdev = qm->pdev;
+
+- if (qm->use_db_isolation)
++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ iounmap(qm->db_io_base);
+
+ iounmap(qm->io_base);
+@@ -3716,7 +3758,9 @@ static void hisi_qm_memory_uninit(struct hisi_qm *qm)
+ }
+
+ idr_destroy(&qm->qp_idr);
+- kfree(qm->factor);
++
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++ kfree(qm->factor);
+ }
+
+ /**
+@@ -4499,12 +4543,10 @@ static int qm_vf_read_qos(struct hisi_qm *qm)
+ qm->mb_qos = 0;
+
+ /* vf ping pf to get function qos */
+- if (qm->ops->ping_pf) {
+- ret = qm->ops->ping_pf(qm, QM_VF_GET_QOS);
+- if (ret) {
+- pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
+- return ret;
+- }
++ ret = qm_ping_pf(qm, QM_VF_GET_QOS);
++ if (ret) {
++ pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
++ return ret;
+ }
+
+ while (true) {
+@@ -4583,7 +4625,7 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf,
+ unsigned int *fun_index)
+ {
+ char tbuf_bdf[QM_DBG_READ_LEN] = {0};
+- char val_buf[QM_QOS_VAL_MAX_LEN] = {0};
++ char val_buf[QM_DBG_READ_LEN] = {0};
+ u32 tmp1, device, function;
+ int ret, bus;
+
+@@ -4676,14 +4718,14 @@ static const struct file_operations qm_algqos_fops = {
+ * hisi_qm_set_algqos_init() - Initialize function qos debugfs files.
+ * @qm: The qm for which we want to add debugfs files.
+ *
+- * Create function qos debugfs files.
++ * Create function qos debugfs files, VF ping PF to get function qos.
+ */
+ static void hisi_qm_set_algqos_init(struct hisi_qm *qm)
+ {
+ if (qm->fun_type == QM_HW_PF)
+ debugfs_create_file("alg_qos", 0644, qm->debug.debug_root,
+ qm, &qm_algqos_fops);
+- else
++ else if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ debugfs_create_file("alg_qos", 0444, qm->debug.debug_root,
+ qm, &qm_algqos_fops);
+ }
+@@ -4731,7 +4773,7 @@ void hisi_qm_debug_init(struct hisi_qm *qm)
+ &qm_atomic64_ops);
+ }
+
+- if (qm->ver >= QM_HW_V3)
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
+ hisi_qm_set_algqos_init(qm);
+ }
+ EXPORT_SYMBOL_GPL(hisi_qm_debug_init);
+@@ -4848,7 +4890,9 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen)
+
+ pci_disable_sriov(pdev);
+ /* clear vf function shaper configure array */
+- memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs);
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++ memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs);
++
+ ret = qm_clear_vft_config(qm);
+ if (ret)
+ return ret;
+@@ -5072,8 +5116,8 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, u64 cmd,
+ return 0;
+
+ /* Kunpeng930 supports to notify VFs to stop before PF reset */
+- if (qm->ops->ping_all_vfs) {
+- ret = qm->ops->ping_all_vfs(qm, cmd);
++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
++ ret = qm_ping_all_vfs(qm, cmd);
+ if (ret)
+ pci_err(pdev, "failed to send cmd to all VFs before PF reset!\n");
+ } else {
+@@ -5264,8 +5308,8 @@ static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_mb_cmd cmd)
+ }
+
+ /* Kunpeng930 supports to notify VFs to start after PF reset. */
+- if (qm->ops->ping_all_vfs) {
+- ret = qm->ops->ping_all_vfs(qm, cmd);
++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
++ ret = qm_ping_all_vfs(qm, cmd);
+ if (ret)
+ pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n");
+ } else {
+@@ -5713,7 +5757,7 @@ err_prepare:
+ hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
+ out:
+ pci_save_state(pdev);
+- ret = qm->ops->ping_pf(qm, cmd);
++ ret = qm_ping_pf(qm, cmd);
+ if (ret)
+ dev_warn(&pdev->dev, "PF responds timeout in reset prepare!\n");
+ }
+@@ -5731,7 +5775,8 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm)
+ cmd = QM_VF_START_FAIL;
+ }
+
+- ret = qm->ops->ping_pf(qm, cmd);
++ qm_cmd_init(qm);
++ ret = qm_ping_pf(qm, cmd);
+ if (ret)
+ dev_warn(&pdev->dev, "PF responds timeout in reset done!\n");
+
+@@ -5792,7 +5837,6 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm,
+ goto err_get_status;
+
+ qm_pf_reset_vf_done(qm);
+- qm_cmd_init(qm);
+
+ dev_info(dev, "device reset done.\n");
+
+@@ -5936,7 +5980,7 @@ static int qm_get_qp_num(struct hisi_qm *qm)
+ qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) &
+ QM_QP_NUN_MASK;
+
+- if (qm->use_db_isolation)
++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ qm->max_qp_num = (readl(qm->io_base + QM_CAPBILITY) >>
+ QM_QP_MAX_NUM_SHIFT) & QM_QP_NUN_MASK;
+ else
+@@ -5952,6 +5996,39 @@ static int qm_get_qp_num(struct hisi_qm *qm)
+ return 0;
+ }
+
++static void qm_get_hw_caps(struct hisi_qm *qm)
++{
++ const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ?
++ qm_cap_info_pf : qm_cap_info_vf;
++ u32 size = qm->fun_type == QM_HW_PF ? ARRAY_SIZE(qm_cap_info_pf) :
++ ARRAY_SIZE(qm_cap_info_vf);
++ u32 val, i;
++
++ /* Doorbell isolate register is a independent register. */
++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, QM_SUPPORT_DB_ISOLATION, true);
++ if (val)
++ set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps);
++
++ if (qm->ver >= QM_HW_V3) {
++ val = readl(qm->io_base + QM_FUNC_CAPS_REG);
++ qm->cap_ver = val & QM_CAPBILITY_VERSION;
++ }
++
++ /* Get PF/VF common capbility */
++ for (i = 1; i < ARRAY_SIZE(qm_cap_info_comm); i++) {
++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, i, qm->cap_ver);
++ if (val)
++ set_bit(qm_cap_info_comm[i].type, &qm->caps);
++ }
++
++ /* Get PF/VF different capbility */
++ for (i = 0; i < size; i++) {
++ val = hisi_qm_get_hw_info(qm, cap_info, i, qm->cap_ver);
++ if (val)
++ set_bit(cap_info[i].type, &qm->caps);
++ }
++}
++
+ static int qm_get_pci_res(struct hisi_qm *qm)
+ {
+ struct pci_dev *pdev = qm->pdev;
+@@ -5971,16 +6048,8 @@ static int qm_get_pci_res(struct hisi_qm *qm)
+ goto err_request_mem_regions;
+ }
+
+- if (qm->ver > QM_HW_V2) {
+- if (qm->fun_type == QM_HW_PF)
+- qm->use_db_isolation = readl(qm->io_base +
+- QM_QUE_ISO_EN) & BIT(0);
+- else
+- qm->use_db_isolation = readl(qm->io_base +
+- QM_QUE_ISO_CFG_V) & BIT(0);
+- }
+-
+- if (qm->use_db_isolation) {
++ qm_get_hw_caps(qm);
++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
+ qm->db_interval = QM_QP_DB_INTERVAL;
+ qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4);
+ qm->db_io_base = ioremap(qm->db_phys_base,
+@@ -6004,7 +6073,7 @@ static int qm_get_pci_res(struct hisi_qm *qm)
+ return 0;
+
+ err_db_ioremap:
+- if (qm->use_db_isolation)
++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ iounmap(qm->db_io_base);
+ err_ioremap:
+ iounmap(qm->io_base);
+@@ -6121,12 +6190,15 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+ int ret, total_func, i;
+ size_t off = 0;
+
+- total_func = pci_sriov_get_totalvfs(qm->pdev) + 1;
+- qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL);
+- if (!qm->factor)
+- return -ENOMEM;
+- for (i = 0; i < total_func; i++)
+- qm->factor[i].func_qos = QM_QOS_MAX_VAL;
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
++ total_func = pci_sriov_get_totalvfs(qm->pdev) + 1;
++ qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL);
++ if (!qm->factor)
++ return -ENOMEM;
++
++ for (i = 0; i < total_func; i++)
++ qm->factor[i].func_qos = QM_QOS_MAX_VAL;
++ }
+
+ #define QM_INIT_BUF(qm, type, num) do { \
+ (qm)->type = ((qm)->qdma.va + (off)); \
+@@ -6143,8 +6215,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+ GFP_ATOMIC);
+ dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size);
+ if (!qm->qdma.va) {
+- ret = -ENOMEM;
+- goto err_alloc_qdma;
++ ret = -ENOMEM;
++ goto err_destroy_idr;
+ }
+
+ QM_INIT_BUF(qm, eqe, QM_EQ_DEPTH);
+@@ -6160,8 +6232,10 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+
+ err_alloc_qp_array:
+ dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma);
+-err_alloc_qdma:
+- kfree(qm->factor);
++err_destroy_idr:
++ idr_destroy(&qm->qp_idr);
++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++ kfree(qm->factor);
+
+ return ret;
+ }
+@@ -6304,7 +6378,7 @@ void hisi_qm_pm_init(struct hisi_qm *qm)
+ {
+ struct device *dev = &qm->pdev->dev;
+
+- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ return;
+
+ pm_runtime_set_autosuspend_delay(dev, QM_AUTOSUSPEND_DELAY);
+@@ -6323,7 +6397,7 @@ void hisi_qm_pm_uninit(struct hisi_qm *qm)
+ {
+ struct device *dev = &qm->pdev->dev;
+
+- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ return;
+
+ pm_runtime_get_noresume(dev);
+diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
+index 2c0be91c0b094..1ec3b06345fd4 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_main.c
++++ b/drivers/crypto/hisilicon/sec2/sec_main.c
+@@ -415,7 +415,7 @@ static void sec_open_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ /* Enable prefetch */
+@@ -435,7 +435,7 @@ static void sec_close_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG);
+diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
+index c3303d99acac7..65ed2ae8e1319 100644
+--- a/drivers/crypto/hisilicon/zip/zip_main.c
++++ b/drivers/crypto/hisilicon/zip/zip_main.c
+@@ -348,7 +348,7 @@ static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ /* Enable prefetch */
+@@ -368,7 +368,7 @@ static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)
+ u32 val;
+ int ret;
+
+- if (qm->ver < QM_HW_V3)
++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ return;
+
+ val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
+diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c
+index d8e82d69745d8..9629e98bd68b7 100644
+--- a/drivers/crypto/img-hash.c
++++ b/drivers/crypto/img-hash.c
+@@ -358,12 +358,16 @@ static int img_hash_dma_init(struct img_hash_dev *hdev)
+ static void img_hash_dma_task(unsigned long d)
+ {
+ struct img_hash_dev *hdev = (struct img_hash_dev *)d;
+- struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req);
++ struct img_hash_request_ctx *ctx;
+ u8 *addr;
+ size_t nbytes, bleft, wsend, len, tbc;
+ struct scatterlist tsg;
+
+- if (!hdev->req || !ctx->sg)
++ if (!hdev->req)
++ return;
++
++ ctx = ahash_request_ctx(hdev->req);
++ if (!ctx->sg)
+ return;
+
+ addr = sg_virt(ctx->sg);
+diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
+index 655a7f5a406a1..cbeda59c6b191 100644
+--- a/drivers/crypto/omap-sham.c
++++ b/drivers/crypto/omap-sham.c
+@@ -2114,7 +2114,7 @@ static int omap_sham_probe(struct platform_device *pdev)
+
+ pm_runtime_enable(dev);
+
+- err = pm_runtime_get_sync(dev);
++ err = pm_runtime_resume_and_get(dev);
+ if (err < 0) {
+ dev_err(dev, "failed to get sync: %d\n", err);
+ goto err_pm;
+diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+index 2f212561acc47..670a58b25cb16 100644
+--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c
++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+@@ -261,6 +261,7 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
+ if (!hw_data->accel_capabilities_mask) {
+ dev_err(&pdev->dev, "Failed to get capabilities mask.\n");
++ ret = -EINVAL;
+ goto out_err;
+ }
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
+index 35d73061d1569..14a0aef18ab13 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.c
++++ b/drivers/crypto/rockchip/rk3288_crypto.c
+@@ -65,186 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
+ clk_disable_unprepare(dev->sclk);
+ }
+
+-static int check_alignment(struct scatterlist *sg_src,
+- struct scatterlist *sg_dst,
+- int align_mask)
+-{
+- int in, out, align;
+-
+- in = IS_ALIGNED((uint32_t)sg_src->offset, 4) &&
+- IS_ALIGNED((uint32_t)sg_src->length, align_mask);
+- if (!sg_dst)
+- return in;
+- out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) &&
+- IS_ALIGNED((uint32_t)sg_dst->length, align_mask);
+- align = in && out;
+-
+- return (align && (sg_src->length == sg_dst->length));
+-}
+-
+-static int rk_load_data(struct rk_crypto_info *dev,
+- struct scatterlist *sg_src,
+- struct scatterlist *sg_dst)
+-{
+- unsigned int count;
+-
+- dev->aligned = dev->aligned ?
+- check_alignment(sg_src, sg_dst, dev->align_size) :
+- dev->aligned;
+- if (dev->aligned) {
+- count = min(dev->left_bytes, sg_src->length);
+- dev->left_bytes -= count;
+-
+- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
+- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n",
+- __func__, __LINE__);
+- return -EINVAL;
+- }
+- dev->addr_in = sg_dma_address(sg_src);
+-
+- if (sg_dst) {
+- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
+- dev_err(dev->dev,
+- "[%s:%d] dma_map_sg(dst) error\n",
+- __func__, __LINE__);
+- dma_unmap_sg(dev->dev, sg_src, 1,
+- DMA_TO_DEVICE);
+- return -EINVAL;
+- }
+- dev->addr_out = sg_dma_address(sg_dst);
+- }
+- } else {
+- count = (dev->left_bytes > PAGE_SIZE) ?
+- PAGE_SIZE : dev->left_bytes;
+-
+- if (!sg_pcopy_to_buffer(dev->first, dev->src_nents,
+- dev->addr_vir, count,
+- dev->total - dev->left_bytes)) {
+- dev_err(dev->dev, "[%s:%d] pcopy err\n",
+- __func__, __LINE__);
+- return -EINVAL;
+- }
+- dev->left_bytes -= count;
+- sg_init_one(&dev->sg_tmp, dev->addr_vir, count);
+- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) {
+- dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp) error\n",
+- __func__, __LINE__);
+- return -ENOMEM;
+- }
+- dev->addr_in = sg_dma_address(&dev->sg_tmp);
+-
+- if (sg_dst) {
+- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1,
+- DMA_FROM_DEVICE)) {
+- dev_err(dev->dev,
+- "[%s:%d] dma_map_sg(sg_tmp) error\n",
+- __func__, __LINE__);
+- dma_unmap_sg(dev->dev, &dev->sg_tmp, 1,
+- DMA_TO_DEVICE);
+- return -ENOMEM;
+- }
+- dev->addr_out = sg_dma_address(&dev->sg_tmp);
+- }
+- }
+- dev->count = count;
+- return 0;
+-}
+-
+-static void rk_unload_data(struct rk_crypto_info *dev)
+-{
+- struct scatterlist *sg_in, *sg_out;
+-
+- sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp;
+- dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);
+-
+- if (dev->sg_dst) {
+- sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp;
+- dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
+- }
+-}
+-
+ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
+ {
+ struct rk_crypto_info *dev = platform_get_drvdata(dev_id);
+ u32 interrupt_status;
+
+- spin_lock(&dev->lock);
+ interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
+ CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);
+
++ dev->status = 1;
+ if (interrupt_status & 0x0a) {
+ dev_warn(dev->dev, "DMA Error\n");
+- dev->err = -EFAULT;
++ dev->status = 0;
+ }
+- tasklet_schedule(&dev->done_task);
++ complete(&dev->complete);
+
+- spin_unlock(&dev->lock);
+ return IRQ_HANDLED;
+ }
+
+-static int rk_crypto_enqueue(struct rk_crypto_info *dev,
+- struct crypto_async_request *async_req)
+-{
+- unsigned long flags;
+- int ret;
+-
+- spin_lock_irqsave(&dev->lock, flags);
+- ret = crypto_enqueue_request(&dev->queue, async_req);
+- if (dev->busy) {
+- spin_unlock_irqrestore(&dev->lock, flags);
+- return ret;
+- }
+- dev->busy = true;
+- spin_unlock_irqrestore(&dev->lock, flags);
+- tasklet_schedule(&dev->queue_task);
+-
+- return ret;
+-}
+-
+-static void rk_crypto_queue_task_cb(unsigned long data)
+-{
+- struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+- struct crypto_async_request *async_req, *backlog;
+- unsigned long flags;
+- int err = 0;
+-
+- dev->err = 0;
+- spin_lock_irqsave(&dev->lock, flags);
+- backlog = crypto_get_backlog(&dev->queue);
+- async_req = crypto_dequeue_request(&dev->queue);
+-
+- if (!async_req) {
+- dev->busy = false;
+- spin_unlock_irqrestore(&dev->lock, flags);
+- return;
+- }
+- spin_unlock_irqrestore(&dev->lock, flags);
+-
+- if (backlog) {
+- backlog->complete(backlog, -EINPROGRESS);
+- backlog = NULL;
+- }
+-
+- dev->async_req = async_req;
+- err = dev->start(dev);
+- if (err)
+- dev->complete(dev->async_req, err);
+-}
+-
+-static void rk_crypto_done_task_cb(unsigned long data)
+-{
+- struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+-
+- if (dev->err) {
+- dev->complete(dev->async_req, dev->err);
+- return;
+- }
+-
+- dev->err = dev->update(dev);
+- if (dev->err)
+- dev->complete(dev->async_req, dev->err);
+-}
+-
+ static struct rk_crypto_tmp *rk_cipher_algs[] = {
+ &rk_ecb_aes_alg,
+ &rk_cbc_aes_alg,
+@@ -337,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ if (err)
+ goto err_crypto;
+
+- spin_lock_init(&crypto_info->lock);
+-
+ crypto_info->reg = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(crypto_info->reg)) {
+ err = PTR_ERR(crypto_info->reg);
+@@ -389,18 +225,11 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ crypto_info->dev = &pdev->dev;
+ platform_set_drvdata(pdev, crypto_info);
+
+- tasklet_init(&crypto_info->queue_task,
+- rk_crypto_queue_task_cb, (unsigned long)crypto_info);
+- tasklet_init(&crypto_info->done_task,
+- rk_crypto_done_task_cb, (unsigned long)crypto_info);
+- crypto_init_queue(&crypto_info->queue, 50);
++ crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
++ crypto_engine_start(crypto_info->engine);
++ init_completion(&crypto_info->complete);
+
+- crypto_info->enable_clk = rk_crypto_enable_clk;
+- crypto_info->disable_clk = rk_crypto_disable_clk;
+- crypto_info->load_data = rk_load_data;
+- crypto_info->unload_data = rk_unload_data;
+- crypto_info->enqueue = rk_crypto_enqueue;
+- crypto_info->busy = false;
++ rk_crypto_enable_clk(crypto_info);
+
+ err = rk_crypto_register(crypto_info);
+ if (err) {
+@@ -412,9 +241,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ return 0;
+
+ err_register_alg:
+- tasklet_kill(&crypto_info->queue_task);
+- tasklet_kill(&crypto_info->done_task);
++ crypto_engine_exit(crypto_info->engine);
+ err_crypto:
++ dev_err(dev, "Crypto Accelerator not successfully registered\n");
+ return err;
+ }
+
+@@ -423,8 +252,8 @@ static int rk_crypto_remove(struct platform_device *pdev)
+ struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
+
+ rk_crypto_unregister();
+- tasklet_kill(&crypto_tmp->done_task);
+- tasklet_kill(&crypto_tmp->queue_task);
++ rk_crypto_disable_clk(crypto_tmp);
++ crypto_engine_exit(crypto_tmp->engine);
+ return 0;
+ }
+
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 97278c2574ff9..045e811b4af84 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -5,9 +5,11 @@
+ #include <crypto/aes.h>
+ #include <crypto/internal/des.h>
+ #include <crypto/algapi.h>
++#include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/scatterlist.h>
++#include <crypto/engine.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/internal/skcipher.h>
+
+@@ -193,45 +195,15 @@ struct rk_crypto_info {
+ struct reset_control *rst;
+ void __iomem *reg;
+ int irq;
+- struct crypto_queue queue;
+- struct tasklet_struct queue_task;
+- struct tasklet_struct done_task;
+- struct crypto_async_request *async_req;
+- int err;
+- /* device lock */
+- spinlock_t lock;
+-
+- /* the public variable */
+- struct scatterlist *sg_src;
+- struct scatterlist *sg_dst;
+- struct scatterlist sg_tmp;
+- struct scatterlist *first;
+- unsigned int left_bytes;
+- void *addr_vir;
+- int aligned;
+- int align_size;
+- size_t src_nents;
+- size_t dst_nents;
+- unsigned int total;
+- unsigned int count;
+- dma_addr_t addr_in;
+- dma_addr_t addr_out;
+- bool busy;
+- int (*start)(struct rk_crypto_info *dev);
+- int (*update)(struct rk_crypto_info *dev);
+- void (*complete)(struct crypto_async_request *base, int err);
+- int (*enable_clk)(struct rk_crypto_info *dev);
+- void (*disable_clk)(struct rk_crypto_info *dev);
+- int (*load_data)(struct rk_crypto_info *dev,
+- struct scatterlist *sg_src,
+- struct scatterlist *sg_dst);
+- void (*unload_data)(struct rk_crypto_info *dev);
+- int (*enqueue)(struct rk_crypto_info *dev,
+- struct crypto_async_request *async_req);
++
++ struct crypto_engine *engine;
++ struct completion complete;
++ int status;
+ };
+
+ /* the private variable of hash */
+ struct rk_ahash_ctx {
++ struct crypto_engine_ctx enginectx;
+ struct rk_crypto_info *dev;
+ /* for fallback */
+ struct crypto_ahash *fallback_tfm;
+@@ -241,14 +213,23 @@ struct rk_ahash_ctx {
+ struct rk_ahash_rctx {
+ struct ahash_request fallback_req;
+ u32 mode;
++ int nrsg;
+ };
+
+ /* the private variable of cipher */
+ struct rk_cipher_ctx {
++ struct crypto_engine_ctx enginectx;
+ struct rk_crypto_info *dev;
+ unsigned int keylen;
+- u32 mode;
++ u8 key[AES_MAX_KEY_SIZE];
+ u8 iv[AES_BLOCK_SIZE];
++ struct crypto_skcipher *fallback_tfm;
++};
++
++struct rk_cipher_rctx {
++ u8 backup_iv[AES_BLOCK_SIZE];
++ u32 mode;
++ struct skcipher_request fallback_req; // keep at the end
+ };
+
+ enum alg_type {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index ed03058497bc2..edd40e16a3f0a 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -9,6 +9,7 @@
+ * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
+ */
+ #include <linux/device.h>
++#include <asm/unaligned.h>
+ #include "rk3288_crypto.h"
+
+ /*
+@@ -16,6 +17,40 @@
+ * so we put the fixed hash out when met zero message.
+ */
+
++static bool rk_ahash_need_fallback(struct ahash_request *req)
++{
++ struct scatterlist *sg;
++
++ sg = req->src;
++ while (sg) {
++ if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
++ return true;
++ }
++ if (sg->length % 4) {
++ return true;
++ }
++ sg = sg_next(sg);
++ }
++ return false;
++}
++
++static int rk_ahash_digest_fb(struct ahash_request *areq)
++{
++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
++
++ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
++ rctx->fallback_req.base.flags = areq->base.flags &
++ CRYPTO_TFM_REQ_MAY_SLEEP;
++
++ rctx->fallback_req.nbytes = areq->nbytes;
++ rctx->fallback_req.src = areq->src;
++ rctx->fallback_req.result = areq->result;
++
++ return crypto_ahash_digest(&rctx->fallback_req);
++}
++
+ static int zero_message_process(struct ahash_request *req)
+ {
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+@@ -38,16 +73,12 @@ static int zero_message_process(struct ahash_request *req)
+ return 0;
+ }
+
+-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err)
+-{
+- if (base->complete)
+- base->complete(base, err);
+-}
+-
+-static void rk_ahash_reg_init(struct rk_crypto_info *dev)
++static void rk_ahash_reg_init(struct ahash_request *req)
+ {
+- struct ahash_request *req = ahash_request_cast(dev->async_req);
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++ struct rk_crypto_info *dev = tctx->dev;
+ int reg_status;
+
+ reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
+@@ -74,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev)
+ RK_CRYPTO_BYTESWAP_BRFIFO |
+ RK_CRYPTO_BYTESWAP_BTFIFO);
+
+- CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total);
++ CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes);
+ }
+
+ static int rk_ahash_init(struct ahash_request *req)
+@@ -167,48 +198,64 @@ static int rk_ahash_digest(struct ahash_request *req)
+ struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
+ struct rk_crypto_info *dev = tctx->dev;
+
++ if (rk_ahash_need_fallback(req))
++ return rk_ahash_digest_fb(req);
++
+ if (!req->nbytes)
+ return zero_message_process(req);
+- else
+- return dev->enqueue(dev, &req->base);
++
++ return crypto_transfer_hash_request_to_engine(dev->engine, req);
+ }
+
+-static void crypto_ahash_dma_start(struct rk_crypto_info *dev)
++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
+ {
+- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in);
+- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4);
++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg));
++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4);
+ CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START |
+ (RK_CRYPTO_HASH_START << 16));
+ }
+
+-static int rk_ahash_set_data_start(struct rk_crypto_info *dev)
++static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
++{
++ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++ int ret;
++
++ ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
++ if (ret <= 0)
++ return -EINVAL;
++
++ rctx->nrsg = ret;
++
++ return 0;
++}
++
++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
+ {
+- int err;
++ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+
+- err = dev->load_data(dev, dev->sg_src, NULL);
+- if (!err)
+- crypto_ahash_dma_start(dev);
+- return err;
++ dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
++ return 0;
+ }
+
+-static int rk_ahash_start(struct rk_crypto_info *dev)
++static int rk_hash_run(struct crypto_engine *engine, void *breq)
+ {
+- struct ahash_request *req = ahash_request_cast(dev->async_req);
+- struct crypto_ahash *tfm;
+- struct rk_ahash_rctx *rctx;
+-
+- dev->total = req->nbytes;
+- dev->left_bytes = req->nbytes;
+- dev->aligned = 0;
+- dev->align_size = 4;
+- dev->sg_dst = NULL;
+- dev->sg_src = req->src;
+- dev->first = req->src;
+- dev->src_nents = sg_nents(req->src);
+- rctx = ahash_request_ctx(req);
++ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++ struct scatterlist *sg = areq->src;
++ int err = 0;
++ int i;
++ u32 v;
++
+ rctx->mode = 0;
+
+- tfm = crypto_ahash_reqtfm(req);
+ switch (crypto_ahash_digestsize(tfm)) {
+ case SHA1_DIGEST_SIZE:
+ rctx->mode = RK_CRYPTO_HASH_SHA1;
+@@ -220,32 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev)
+ rctx->mode = RK_CRYPTO_HASH_MD5;
+ break;
+ default:
+- return -EINVAL;
++ err = -EINVAL;
++ goto theend;
+ }
+
+- rk_ahash_reg_init(dev);
+- return rk_ahash_set_data_start(dev);
+-}
+-
+-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+-{
+- int err = 0;
+- struct ahash_request *req = ahash_request_cast(dev->async_req);
+- struct crypto_ahash *tfm;
+-
+- dev->unload_data(dev);
+- if (dev->left_bytes) {
+- if (dev->aligned) {
+- if (sg_is_last(dev->sg_src)) {
+- dev_warn(dev->dev, "[%s:%d], Lack of data\n",
+- __func__, __LINE__);
+- err = -ENOMEM;
+- goto out_rx;
+- }
+- dev->sg_src = sg_next(dev->sg_src);
++ rk_ahash_reg_init(areq);
++
++ while (sg) {
++ reinit_completion(&tctx->dev->complete);
++ tctx->dev->status = 0;
++ crypto_ahash_dma_start(tctx->dev, sg);
++ wait_for_completion_interruptible_timeout(&tctx->dev->complete,
++ msecs_to_jiffies(2000));
++ if (!tctx->dev->status) {
++ dev_err(tctx->dev->dev, "DMA timeout\n");
++ err = -EFAULT;
++ goto theend;
+ }
+- err = rk_ahash_set_data_start(dev);
+- } else {
++ sg = sg_next(sg);
++ }
++
+ /*
+ * it will take some time to process date after last dma
+ * transmission.
+@@ -256,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+ * efficiency, and make it response quickly when dma
+ * complete.
+ */
+- while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS))
+- udelay(10);
+-
+- tfm = crypto_ahash_reqtfm(req);
+- memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0,
+- crypto_ahash_digestsize(tfm));
+- dev->complete(dev->async_req, 0);
+- tasklet_schedule(&dev->queue_task);
++ while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS))
++ udelay(10);
++
++ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
++ v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
++ put_unaligned_le32(v, areq->result + i * 4);
+ }
+
+-out_rx:
+- return err;
++theend:
++ local_bh_disable();
++ crypto_finalize_hash_request(engine, breq, err);
++ local_bh_enable();
++
++ return 0;
+ }
+
+ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+@@ -281,14 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+ algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
+
+ tctx->dev = algt->dev;
+- tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL);
+- if (!tctx->dev->addr_vir) {
+- dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n");
+- return -ENOMEM;
+- }
+- tctx->dev->start = rk_ahash_start;
+- tctx->dev->update = rk_ahash_crypto_rx;
+- tctx->dev->complete = rk_ahash_crypto_complete;
+
+ /* for fallback */
+ tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
+@@ -297,19 +332,23 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+ dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
+ return PTR_ERR(tctx->fallback_tfm);
+ }
++
+ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+ sizeof(struct rk_ahash_rctx) +
+ crypto_ahash_reqsize(tctx->fallback_tfm));
+
+- return tctx->dev->enable_clk(tctx->dev);
++ tctx->enginectx.op.do_one_request = rk_hash_run;
++ tctx->enginectx.op.prepare_request = rk_hash_prepare;
++ tctx->enginectx.op.unprepare_request = rk_hash_unprepare;
++
++ return 0;
+ }
+
+ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+ {
+ struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
+
+- free_page((unsigned long)tctx->dev->addr_vir);
+- return tctx->dev->disable_clk(tctx->dev);
++ crypto_free_ahash(tctx->fallback_tfm);
+ }
+
+ struct rk_crypto_tmp rk_ahash_sha1 = {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index 5bbf0d2722e11..67a7e05d5ae31 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -9,23 +9,77 @@
+ * Some ideas are from marvell-cesa.c and s5p-sss.c driver.
+ */
+ #include <linux/device.h>
++#include <crypto/scatterwalk.h>
+ #include "rk3288_crypto.h"
+
+ #define RK_CRYPTO_DEC BIT(0)
+
+-static void rk_crypto_complete(struct crypto_async_request *base, int err)
++static int rk_cipher_need_fallback(struct skcipher_request *req)
+ {
+- if (base->complete)
+- base->complete(base, err);
++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++ unsigned int bs = crypto_skcipher_blocksize(tfm);
++ struct scatterlist *sgs, *sgd;
++ unsigned int stodo, dtodo, len;
++
++ if (!req->cryptlen)
++ return true;
++
++ len = req->cryptlen;
++ sgs = req->src;
++ sgd = req->dst;
++ while (sgs && sgd) {
++ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) {
++ return true;
++ }
++ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) {
++ return true;
++ }
++ stodo = min(len, sgs->length);
++ if (stodo % bs) {
++ return true;
++ }
++ dtodo = min(len, sgd->length);
++ if (dtodo % bs) {
++ return true;
++ }
++ if (stodo != dtodo) {
++ return true;
++ }
++ len -= stodo;
++ sgs = sg_next(sgs);
++ sgd = sg_next(sgd);
++ }
++ return false;
++}
++
++static int rk_cipher_fallback(struct skcipher_request *areq)
++{
++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
++ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++ int err;
++
++ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm);
++ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
++ areq->base.complete, areq->base.data);
++ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst,
++ areq->cryptlen, areq->iv);
++ if (rctx->mode & RK_CRYPTO_DEC)
++ err = crypto_skcipher_decrypt(&rctx->fallback_req);
++ else
++ err = crypto_skcipher_encrypt(&rctx->fallback_req);
++ return err;
+ }
+
+ static int rk_handle_req(struct rk_crypto_info *dev,
+ struct skcipher_request *req)
+ {
+- if (!IS_ALIGNED(req->cryptlen, dev->align_size))
+- return -EINVAL;
+- else
+- return dev->enqueue(dev, &req->base);
++ struct crypto_engine *engine = dev->engine;
++
++ if (rk_cipher_need_fallback(req))
++ return rk_cipher_fallback(req);
++
++ return crypto_transfer_skcipher_request_to_engine(engine, req);
+ }
+
+ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+@@ -38,8 +92,9 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+ keylen != AES_KEYSIZE_256)
+ return -EINVAL;
+ ctx->keylen = keylen;
+- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
+- return 0;
++ memcpy(ctx->key, key, keylen);
++
++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+
+ static int rk_des_setkey(struct crypto_skcipher *cipher,
+@@ -53,8 +108,9 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,
+ return err;
+
+ ctx->keylen = keylen;
+- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+- return 0;
++ memcpy(ctx->key, key, keylen);
++
++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+
+ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+@@ -68,17 +124,19 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+ return err;
+
+ ctx->keylen = keylen;
+- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+- return 0;
++ memcpy(ctx->key, key, keylen);
++
++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+
+ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_AES_ECB_MODE;
++ rctx->mode = RK_CRYPTO_AES_ECB_MODE;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -86,9 +144,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
++ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -96,9 +155,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_AES_CBC_MODE;
++ rctx->mode = RK_CRYPTO_AES_CBC_MODE;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -106,9 +166,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
++ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -116,9 +177,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = 0;
++ rctx->mode = 0;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -126,9 +188,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_DEC;
++ rctx->mode = RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -136,9 +199,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -146,9 +210,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -156,9 +221,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_SELECT;
++ rctx->mode = RK_CRYPTO_TDES_SELECT;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -166,9 +232,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -176,9 +243,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+ return rk_handle_req(dev, req);
+ }
+
+@@ -186,43 +254,42 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
+ {
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_crypto_info *dev = ctx->dev;
+
+- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+ RK_CRYPTO_DEC;
+ return rk_handle_req(dev, req);
+ }
+
+-static void rk_ablk_hw_init(struct rk_crypto_info *dev)
++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
+ {
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
+- u32 ivsize, block, conf_reg = 0;
++ u32 block, conf_reg = 0;
+
+ block = crypto_tfm_alg_blocksize(tfm);
+- ivsize = crypto_skcipher_ivsize(cipher);
+
+ if (block == DES_BLOCK_SIZE) {
+- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
++ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+ RK_CRYPTO_TDES_BYTESWAP_KEY |
+ RK_CRYPTO_TDES_BYTESWAP_IV;
+- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
+- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
++ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
+ conf_reg = RK_CRYPTO_DESSEL;
+ } else {
+- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
++ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+ RK_CRYPTO_AES_KEY_CHANGE |
+ RK_CRYPTO_AES_BYTESWAP_KEY |
+ RK_CRYPTO_AES_BYTESWAP_IV;
+ if (ctx->keylen == AES_KEYSIZE_192)
+- ctx->mode |= RK_CRYPTO_AES_192BIT_key;
++ rctx->mode |= RK_CRYPTO_AES_192BIT_key;
+ else if (ctx->keylen == AES_KEYSIZE_256)
+- ctx->mode |= RK_CRYPTO_AES_256BIT_key;
+- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
+- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
++ rctx->mode |= RK_CRYPTO_AES_256BIT_key;
++ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
+ }
+ conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
+ RK_CRYPTO_BYTESWAP_BRFIFO;
+@@ -231,146 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+ RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA);
+ }
+
+-static void crypto_dma_start(struct rk_crypto_info *dev)
++static void crypto_dma_start(struct rk_crypto_info *dev,
++ struct scatterlist *sgs,
++ struct scatterlist *sgd, unsigned int todo)
+ {
+- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in);
+- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4);
+- CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out);
++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs));
++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo);
++ CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd));
+ CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START |
+ _SBF(RK_CRYPTO_BLOCK_START, 16));
+ }
+
+-static int rk_set_data_start(struct rk_crypto_info *dev)
++static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
+ {
+- int err;
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base);
++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+- u32 ivsize = crypto_skcipher_ivsize(tfm);
+- u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
+- dev->sg_src->offset + dev->sg_src->length - ivsize;
+-
+- /* Store the iv that need to be updated in chain mode.
+- * And update the IV buffer to contain the next IV for decryption mode.
+- */
+- if (ctx->mode & RK_CRYPTO_DEC) {
+- memcpy(ctx->iv, src_last_blk, ivsize);
+- sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
+- ivsize, dev->total - ivsize);
+- }
+-
+- err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
+- if (!err)
+- crypto_dma_start(dev);
+- return err;
+-}
+-
+-static int rk_ablk_start(struct rk_crypto_info *dev)
+-{
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+- unsigned long flags;
++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++ struct scatterlist *sgs, *sgd;
+ int err = 0;
++ int ivsize = crypto_skcipher_ivsize(tfm);
++ int offset;
++ u8 iv[AES_BLOCK_SIZE];
++ u8 biv[AES_BLOCK_SIZE];
++ u8 *ivtouse = areq->iv;
++ unsigned int len = areq->cryptlen;
++ unsigned int todo;
++
++ ivsize = crypto_skcipher_ivsize(tfm);
++ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
++ if (rctx->mode & RK_CRYPTO_DEC) {
++ offset = areq->cryptlen - ivsize;
++ scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
++ offset, ivsize, 0);
++ }
++ }
+
+- dev->left_bytes = req->cryptlen;
+- dev->total = req->cryptlen;
+- dev->sg_src = req->src;
+- dev->first = req->src;
+- dev->src_nents = sg_nents(req->src);
+- dev->sg_dst = req->dst;
+- dev->dst_nents = sg_nents(req->dst);
+- dev->aligned = 1;
+-
+- spin_lock_irqsave(&dev->lock, flags);
+- rk_ablk_hw_init(dev);
+- err = rk_set_data_start(dev);
+- spin_unlock_irqrestore(&dev->lock, flags);
+- return err;
+-}
++ sgs = areq->src;
++ sgd = areq->dst;
+
+-static void rk_iv_copyback(struct rk_crypto_info *dev)
+-{
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+- u32 ivsize = crypto_skcipher_ivsize(tfm);
+-
+- /* Update the IV buffer to contain the next IV for encryption mode. */
+- if (!(ctx->mode & RK_CRYPTO_DEC)) {
+- if (dev->aligned) {
+- memcpy(req->iv, sg_virt(dev->sg_dst) +
+- dev->sg_dst->length - ivsize, ivsize);
++ while (sgs && sgd && len) {
++ if (!sgs->length) {
++ sgs = sg_next(sgs);
++ sgd = sg_next(sgd);
++ continue;
++ }
++ if (rctx->mode & RK_CRYPTO_DEC) {
++ /* we backup last block of source to be used as IV at next step */
++ offset = sgs->length - ivsize;
++ scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
++ }
++ if (sgs == sgd) {
++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++ if (err <= 0) {
++ err = -EINVAL;
++ goto theend_iv;
++ }
++ } else {
++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++ if (err <= 0) {
++ err = -EINVAL;
++ goto theend_iv;
++ }
++ err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++ if (err <= 0) {
++ err = -EINVAL;
++ goto theend_sgs;
++ }
++ }
++ err = 0;
++ rk_ablk_hw_init(ctx->dev, areq);
++ if (ivsize) {
++ if (ivsize == DES_BLOCK_SIZE)
++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
++ else
++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
++ }
++ reinit_completion(&ctx->dev->complete);
++ ctx->dev->status = 0;
++
++ todo = min(sg_dma_len(sgs), len);
++ len -= todo;
++ crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
++ wait_for_completion_interruptible_timeout(&ctx->dev->complete,
++ msecs_to_jiffies(2000));
++ if (!ctx->dev->status) {
++ dev_err(ctx->dev->dev, "DMA timeout\n");
++ err = -EFAULT;
++ goto theend;
++ }
++ if (sgs == sgd) {
++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++ } else {
++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++ }
++ if (rctx->mode & RK_CRYPTO_DEC) {
++ memcpy(iv, biv, ivsize);
++ ivtouse = iv;
+ } else {
+- memcpy(req->iv, dev->addr_vir +
+- dev->count - ivsize, ivsize);
++ offset = sgd->length - ivsize;
++ scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0);
++ ivtouse = iv;
+ }
++ sgs = sg_next(sgs);
++ sgd = sg_next(sgd);
+ }
+-}
+-
+-static void rk_update_iv(struct rk_crypto_info *dev)
+-{
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+- u32 ivsize = crypto_skcipher_ivsize(tfm);
+- u8 *new_iv = NULL;
+
+- if (ctx->mode & RK_CRYPTO_DEC) {
+- new_iv = ctx->iv;
+- } else {
+- new_iv = page_address(sg_page(dev->sg_dst)) +
+- dev->sg_dst->offset + dev->sg_dst->length - ivsize;
++ if (areq->iv && ivsize > 0) {
++ offset = areq->cryptlen - ivsize;
++ if (rctx->mode & RK_CRYPTO_DEC) {
++ memcpy(areq->iv, rctx->backup_iv, ivsize);
++ memzero_explicit(rctx->backup_iv, ivsize);
++ } else {
++ scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
++ ivsize, 0);
++ }
+ }
+
+- if (ivsize == DES_BLOCK_SIZE)
+- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
+- else if (ivsize == AES_BLOCK_SIZE)
+- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
+-}
++theend:
++ local_bh_disable();
++ crypto_finalize_skcipher_request(engine, areq, err);
++ local_bh_enable();
++ return 0;
+
+-/* return:
+- * true some err was occurred
+- * fault no err, continue
+- */
+-static int rk_ablk_rx(struct rk_crypto_info *dev)
+-{
+- int err = 0;
+- struct skcipher_request *req =
+- skcipher_request_cast(dev->async_req);
+-
+- dev->unload_data(dev);
+- if (!dev->aligned) {
+- if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents,
+- dev->addr_vir, dev->count,
+- dev->total - dev->left_bytes -
+- dev->count)) {
+- err = -EINVAL;
+- goto out_rx;
+- }
+- }
+- if (dev->left_bytes) {
+- rk_update_iv(dev);
+- if (dev->aligned) {
+- if (sg_is_last(dev->sg_src)) {
+- dev_err(dev->dev, "[%s:%d] Lack of data\n",
+- __func__, __LINE__);
+- err = -ENOMEM;
+- goto out_rx;
+- }
+- dev->sg_src = sg_next(dev->sg_src);
+- dev->sg_dst = sg_next(dev->sg_dst);
+- }
+- err = rk_set_data_start(dev);
++theend_sgs:
++ if (sgs == sgd) {
++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ } else {
+- rk_iv_copyback(dev);
+- /* here show the calculation is over without any err */
+- dev->complete(dev->async_req, 0);
+- tasklet_schedule(&dev->queue_task);
++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ }
+-out_rx:
++theend_iv:
+ return err;
+ }
+
+@@ -378,26 +437,34 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+ {
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
++ const char *name = crypto_tfm_alg_name(&tfm->base);
+ struct rk_crypto_tmp *algt;
+
+ algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+
+ ctx->dev = algt->dev;
+- ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1;
+- ctx->dev->start = rk_ablk_start;
+- ctx->dev->update = rk_ablk_rx;
+- ctx->dev->complete = rk_crypto_complete;
+- ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
+
+- return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM;
++ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
++ if (IS_ERR(ctx->fallback_tfm)) {
++ dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
++ name, PTR_ERR(ctx->fallback_tfm));
++ return PTR_ERR(ctx->fallback_tfm);
++ }
++
++ tfm->reqsize = sizeof(struct rk_cipher_rctx) +
++ crypto_skcipher_reqsize(ctx->fallback_tfm);
++
++ ctx->enginectx.op.do_one_request = rk_cipher_run;
++
++ return 0;
+ }
+
+ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+ {
+ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+- free_page((unsigned long)ctx->dev->addr_vir);
+- ctx->dev->disable_clk(ctx->dev);
++ memzero_explicit(ctx->key, ctx->keylen);
++ crypto_free_skcipher(ctx->fallback_tfm);
+ }
+
+ struct rk_crypto_tmp rk_ecb_aes_alg = {
+@@ -406,7 +473,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
+ .base.cra_name = "ecb(aes)",
+ .base.cra_driver_name = "ecb-aes-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = AES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x0f,
+@@ -428,7 +495,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
+ .base.cra_name = "cbc(aes)",
+ .base.cra_driver_name = "cbc-aes-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = AES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x0f,
+@@ -451,7 +518,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
+ .base.cra_name = "ecb(des)",
+ .base.cra_driver_name = "ecb-des-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = DES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x07,
+@@ -473,7 +540,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
+ .base.cra_name = "cbc(des)",
+ .base.cra_driver_name = "cbc-des-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = DES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x07,
+@@ -496,7 +563,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
+ .base.cra_name = "ecb(des3_ede)",
+ .base.cra_driver_name = "ecb-des3-ede-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = DES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x07,
+@@ -518,7 +585,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
+ .base.cra_name = "cbc(des3_ede)",
+ .base.cra_driver_name = "cbc-des3-ede-rk",
+ .base.cra_priority = 300,
+- .base.cra_flags = CRYPTO_ALG_ASYNC,
++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = DES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
+ .base.cra_alignmask = 0x07,
+diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
+index 0e5a5662d5a40..0a051d6568800 100644
+--- a/drivers/dio/dio.c
++++ b/drivers/dio/dio.c
+@@ -109,6 +109,12 @@ static char dio_no_name[] = { 0 };
+
+ #endif /* CONFIG_DIO_CONSTANTS */
+
++static void dio_dev_release(struct device *dev)
++{
++ struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev);
++ kfree(ddev);
++}
++
+ int __init dio_find(int deviceid)
+ {
+ /* Called to find a DIO device before the full bus scan has run.
+@@ -225,6 +231,7 @@ static int __init dio_init(void)
+ dev->bus = &dio_bus;
+ dev->dev.parent = &dio_bus.dev;
+ dev->dev.bus = &dio_bus_type;
++ dev->dev.release = dio_dev_release;
+ dev->scode = scode;
+ dev->resource.start = pa;
+ dev->resource.end = pa + DIO_SIZE(scode, va);
+@@ -252,6 +259,7 @@ static int __init dio_init(void)
+ if (error) {
+ pr_err("DIO: Error registering device %s\n",
+ dev->name);
++ put_device(&dev->dev);
+ continue;
+ }
+ error = dio_create_sysfs_dev_files(dev);
+diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
+index 6780761a16403..e3334762be853 100644
+--- a/drivers/dma/apple-admac.c
++++ b/drivers/dma/apple-admac.c
+@@ -20,6 +20,12 @@
+ #define NCHANNELS_MAX 64
+ #define IRQ_NOUTPUTS 4
+
++/*
++ * For allocation purposes we split the cache
++ * memory into blocks of fixed size (given in bytes).
++ */
++#define SRAM_BLOCK 2048
++
+ #define RING_WRITE_SLOT GENMASK(1, 0)
+ #define RING_READ_SLOT GENMASK(5, 4)
+ #define RING_FULL BIT(9)
+@@ -35,6 +41,9 @@
+ #define REG_TX_STOP 0x0004
+ #define REG_RX_START 0x0008
+ #define REG_RX_STOP 0x000c
++#define REG_IMPRINT 0x0090
++#define REG_TX_SRAM_SIZE 0x0094
++#define REG_RX_SRAM_SIZE 0x0098
+
+ #define REG_CHAN_CTL(ch) (0x8000 + (ch) * 0x200)
+ #define REG_CHAN_CTL_RST_RINGS BIT(0)
+@@ -52,7 +61,9 @@
+ #define BUS_WIDTH_FRAME_2_WORDS 0x10
+ #define BUS_WIDTH_FRAME_4_WORDS 0x20
+
+-#define CHAN_BUFSIZE 0x8000
++#define REG_CHAN_SRAM_CARVEOUT(ch) (0x8050 + (ch) * 0x200)
++#define CHAN_SRAM_CARVEOUT_SIZE GENMASK(31, 16)
++#define CHAN_SRAM_CARVEOUT_BASE GENMASK(15, 0)
+
+ #define REG_CHAN_FIFOCTL(ch) (0x8054 + (ch) * 0x200)
+ #define CHAN_FIFOCTL_LIMIT GENMASK(31, 16)
+@@ -75,6 +86,8 @@ struct admac_chan {
+ struct dma_chan chan;
+ struct tasklet_struct tasklet;
+
++ u32 carveout;
++
+ spinlock_t lock;
+ struct admac_tx *current_tx;
+ int nperiod_acks;
+@@ -91,11 +104,24 @@ struct admac_chan {
+ struct list_head to_free;
+ };
+
++struct admac_sram {
++ u32 size;
++ /*
++ * SRAM_CARVEOUT has 16-bit fields, so the SRAM cannot be larger than
++ * 64K and a 32-bit bitfield over 2K blocks covers it.
++ */
++ u32 allocated;
++};
++
+ struct admac_data {
+ struct dma_device dma;
+ struct device *dev;
+ __iomem void *base;
+
++ struct mutex cache_alloc_lock;
++ struct admac_sram txcache, rxcache;
++
++ int irq;
+ int irq_index;
+ int nchannels;
+ struct admac_chan channels[];
+@@ -115,6 +141,60 @@ struct admac_tx {
+ struct list_head node;
+ };
+
++static int admac_alloc_sram_carveout(struct admac_data *ad,
++ enum dma_transfer_direction dir,
++ u32 *out)
++{
++ struct admac_sram *sram;
++ int i, ret = 0, nblocks;
++
++ if (dir == DMA_MEM_TO_DEV)
++ sram = &ad->txcache;
++ else
++ sram = &ad->rxcache;
++
++ mutex_lock(&ad->cache_alloc_lock);
++
++ nblocks = sram->size / SRAM_BLOCK;
++ for (i = 0; i < nblocks; i++)
++ if (!(sram->allocated & BIT(i)))
++ break;
++
++ if (i < nblocks) {
++ *out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, i * SRAM_BLOCK) |
++ FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, SRAM_BLOCK);
++ sram->allocated |= BIT(i);
++ } else {
++ ret = -EBUSY;
++ }
++
++ mutex_unlock(&ad->cache_alloc_lock);
++
++ return ret;
++}
++
++static void admac_free_sram_carveout(struct admac_data *ad,
++ enum dma_transfer_direction dir,
++ u32 carveout)
++{
++ struct admac_sram *sram;
++ u32 base = FIELD_GET(CHAN_SRAM_CARVEOUT_BASE, carveout);
++ int i;
++
++ if (dir == DMA_MEM_TO_DEV)
++ sram = &ad->txcache;
++ else
++ sram = &ad->rxcache;
++
++ if (WARN_ON(base >= sram->size))
++ return;
++
++ mutex_lock(&ad->cache_alloc_lock);
++ i = base / SRAM_BLOCK;
++ sram->allocated &= ~BIT(i);
++ mutex_unlock(&ad->cache_alloc_lock);
++}
++
+ static void admac_modify(struct admac_data *ad, int reg, u32 mask, u32 val)
+ {
+ void __iomem *addr = ad->base + reg;
+@@ -463,15 +543,28 @@ static void admac_synchronize(struct dma_chan *chan)
+ static int admac_alloc_chan_resources(struct dma_chan *chan)
+ {
+ struct admac_chan *adchan = to_admac_chan(chan);
++ struct admac_data *ad = adchan->host;
++ int ret;
+
+ dma_cookie_init(&adchan->chan);
++ ret = admac_alloc_sram_carveout(ad, admac_chan_direction(adchan->no),
++ &adchan->carveout);
++ if (ret < 0)
++ return ret;
++
++ writel_relaxed(adchan->carveout,
++ ad->base + REG_CHAN_SRAM_CARVEOUT(adchan->no));
+ return 0;
+ }
+
+ static void admac_free_chan_resources(struct dma_chan *chan)
+ {
++ struct admac_chan *adchan = to_admac_chan(chan);
++
+ admac_terminate_all(chan);
+ admac_synchronize(chan);
++ admac_free_sram_carveout(adchan->host, admac_chan_direction(adchan->no),
++ adchan->carveout);
+ }
+
+ static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec,
+@@ -709,6 +802,7 @@ static int admac_probe(struct platform_device *pdev)
+ platform_set_drvdata(pdev, ad);
+ ad->dev = &pdev->dev;
+ ad->nchannels = nchannels;
++ mutex_init(&ad->cache_alloc_lock);
+
+ /*
+ * The controller has 4 IRQ outputs. Try them all until
+@@ -724,12 +818,7 @@ static int admac_probe(struct platform_device *pdev)
+
+ if (irq < 0)
+ return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n");
+-
+- err = devm_request_irq(&pdev->dev, irq, admac_interrupt,
+- 0, dev_name(&pdev->dev), ad);
+- if (err)
+- return dev_err_probe(&pdev->dev, err,
+- "unable to register interrupt\n");
++ ad->irq = irq;
+
+ ad->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ad->base))
+@@ -774,17 +863,36 @@ static int admac_probe(struct platform_device *pdev)
+ tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
+ }
+
+- err = dma_async_device_register(&ad->dma);
++ err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad);
+ if (err)
+- return dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
++ return dev_err_probe(&pdev->dev, err,
++ "unable to register interrupt\n");
++
++ err = dma_async_device_register(&ad->dma);
++ if (err) {
++ dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
++ goto free_irq;
++ }
+
+ err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
+ if (err) {
+ dma_async_device_unregister(&ad->dma);
+- return dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
++ dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
++ goto free_irq;
+ }
+
++ ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
++ ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
++
++ dev_info(&pdev->dev, "Audio DMA Controller\n");
++ dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
++ readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
++
+ return 0;
++
++free_irq:
++ free_irq(ad->irq, ad);
++ return err;
+ }
+
+ static int admac_remove(struct platform_device *pdev)
+@@ -793,6 +901,7 @@ static int admac_remove(struct platform_device *pdev)
+
+ of_dma_controller_free(pdev->dev.of_node);
+ dma_async_device_unregister(&ad->dma);
++ free_irq(ad->irq, ad);
+
+ return 0;
+ }
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 6cf50ee0b77c5..e0af60833d28c 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -198,11 +198,10 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
+ if (unlikely(pci_enable_device(pdev) < 0)) {
+ edac_dbg(2, "Failed to enable device %02x:%02x.%x\n",
+ bus, dev, fun);
++ pci_dev_put(pdev);
+ return NULL;
+ }
+
+- pci_dev_get(pdev);
+-
+ return pdev;
+ }
+
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index dca7cecb37e34..290186e44e6bd 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -183,7 +183,7 @@ config EXTCON_USBC_CROS_EC
+
+ config EXTCON_USBC_TUSB320
+ tristate "TI TUSB320 USB-C extcon support"
+- depends on I2C
++ depends on I2C && TYPEC
+ select REGMAP_I2C
+ help
+ Say Y here to enable support for USB Type C cable detection extcon
+diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
+index 6ba3d89b106d0..7223c4b9dc707 100644
+--- a/drivers/extcon/extcon-usbc-tusb320.c
++++ b/drivers/extcon/extcon-usbc-tusb320.c
+@@ -6,6 +6,7 @@
+ * Author: Michael Auchter <michael.auchter@ni.com>
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/extcon-provider.h>
+ #include <linux/i2c.h>
+ #include <linux/init.h>
+@@ -13,6 +14,24 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/regmap.h>
++#include <linux/usb/typec.h>
++
++#define TUSB320_REG8 0x8
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE GENMASK(7, 6)
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB 0x0
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A 0x1
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A 0x2
++#define TUSB320_REG8_CURRENT_MODE_DETECT GENMASK(5, 4)
++#define TUSB320_REG8_CURRENT_MODE_DETECT_DEF 0x0
++#define TUSB320_REG8_CURRENT_MODE_DETECT_MED 0x1
++#define TUSB320_REG8_CURRENT_MODE_DETECT_ACC 0x2
++#define TUSB320_REG8_CURRENT_MODE_DETECT_HI 0x3
++#define TUSB320_REG8_ACCESSORY_CONNECTED GENMASK(3, 2)
++#define TUSB320_REG8_ACCESSORY_CONNECTED_NONE 0x0
++#define TUSB320_REG8_ACCESSORY_CONNECTED_AUDIO 0x4
++#define TUSB320_REG8_ACCESSORY_CONNECTED_ACC 0x5
++#define TUSB320_REG8_ACCESSORY_CONNECTED_DEBUG 0x6
++#define TUSB320_REG8_ACTIVE_CABLE_DETECTION BIT(0)
+
+ #define TUSB320_REG9 0x9
+ #define TUSB320_REG9_ATTACHED_STATE_SHIFT 6
+@@ -55,6 +74,10 @@ struct tusb320_priv {
+ struct extcon_dev *edev;
+ struct tusb320_ops *ops;
+ enum tusb320_attached_state state;
++ struct typec_port *port;
++ struct typec_capability cap;
++ enum typec_port_type port_type;
++ enum typec_pwr_opmode pwr_opmode;
+ };
+
+ static const char * const tusb_attached_states[] = {
+@@ -184,19 +207,47 @@ static struct tusb320_ops tusb320l_ops = {
+ .get_revision = tusb320l_get_revision,
+ };
+
+-static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
++static int tusb320_set_adv_pwr_mode(struct tusb320_priv *priv)
+ {
+- struct tusb320_priv *priv = dev_id;
+- int state, polarity;
+- unsigned reg;
++ u8 mode;
++
++ if (priv->pwr_opmode == TYPEC_PWR_MODE_USB)
++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB;
++ else if (priv->pwr_opmode == TYPEC_PWR_MODE_1_5A)
++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A;
++ else if (priv->pwr_opmode == TYPEC_PWR_MODE_3_0A)
++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A;
++ else /* No other mode is supported. */
++ return -EINVAL;
+
+- if (regmap_read(priv->regmap, TUSB320_REG9, ®)) {
+- dev_err(priv->dev, "error during i2c read!\n");
+- return IRQ_NONE;
+- }
++ return regmap_write_bits(priv->regmap, TUSB320_REG8,
++ TUSB320_REG8_CURRENT_MODE_ADVERTISE,
++ FIELD_PREP(TUSB320_REG8_CURRENT_MODE_ADVERTISE,
++ mode));
++}
+
+- if (!(reg & TUSB320_REG9_INTERRUPT_STATUS))
+- return IRQ_NONE;
++static int tusb320_port_type_set(struct typec_port *port,
++ enum typec_port_type type)
++{
++ struct tusb320_priv *priv = typec_get_drvdata(port);
++
++ if (type == TYPEC_PORT_SRC)
++ return priv->ops->set_mode(priv, TUSB320_MODE_DFP);
++ else if (type == TYPEC_PORT_SNK)
++ return priv->ops->set_mode(priv, TUSB320_MODE_UFP);
++ else if (type == TYPEC_PORT_DRP)
++ return priv->ops->set_mode(priv, TUSB320_MODE_DRP);
++ else
++ return priv->ops->set_mode(priv, TUSB320_MODE_PORT);
++}
++
++static const struct typec_operations tusb320_typec_ops = {
++ .port_type_set = tusb320_port_type_set,
++};
++
++static void tusb320_extcon_irq_handler(struct tusb320_priv *priv, u8 reg)
++{
++ int state, polarity;
+
+ state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
+ TUSB320_REG9_ATTACHED_STATE_MASK;
+@@ -219,19 +270,166 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
+ extcon_sync(priv->edev, EXTCON_USB_HOST);
+
+ priv->state = state;
++}
++
++static void tusb320_typec_irq_handler(struct tusb320_priv *priv, u8 reg9)
++{
++ struct typec_port *port = priv->port;
++ struct device *dev = priv->dev;
++ u8 mode, role, state;
++ int ret, reg8;
++ bool ori;
++
++ ori = reg9 & TUSB320_REG9_CABLE_DIRECTION;
++ typec_set_orientation(port, ori ? TYPEC_ORIENTATION_REVERSE :
++ TYPEC_ORIENTATION_NORMAL);
++
++ state = (reg9 >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
++ TUSB320_REG9_ATTACHED_STATE_MASK;
++ if (state == TUSB320_ATTACHED_STATE_DFP)
++ role = TYPEC_SOURCE;
++ else
++ role = TYPEC_SINK;
++
++ typec_set_vconn_role(port, role);
++ typec_set_pwr_role(port, role);
++ typec_set_data_role(port, role == TYPEC_SOURCE ?
++ TYPEC_HOST : TYPEC_DEVICE);
++
++ ret = regmap_read(priv->regmap, TUSB320_REG8, ®8);
++ if (ret) {
++ dev_err(dev, "error during reg8 i2c read, ret=%d!\n", ret);
++ return;
++ }
++
++ mode = FIELD_GET(TUSB320_REG8_CURRENT_MODE_DETECT, reg8);
++ if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_DEF)
++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB);
++ else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_MED)
++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_1_5A);
++ else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_HI)
++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_3_0A);
++ else /* Charge through accessory */
++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB);
++}
++
++static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
++ bool force_update)
++{
++ unsigned int reg;
++
++ if (regmap_read(priv->regmap, TUSB320_REG9, ®)) {
++ dev_err(priv->dev, "error during i2c read!\n");
++ return IRQ_NONE;
++ }
++
++ if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS))
++ return IRQ_NONE;
++
++ tusb320_extcon_irq_handler(priv, reg);
++
++ /*
++ * Type-C support is optional. Only call the Type-C handler if a
++ * port had been registered previously.
++ */
++ if (priv->port)
++ tusb320_typec_irq_handler(priv, reg);
+
+ regmap_write(priv->regmap, TUSB320_REG9, reg);
+
+ return IRQ_HANDLED;
+ }
+
++static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
++{
++ struct tusb320_priv *priv = dev_id;
++
++ return tusb320_state_update_handler(priv, false);
++}
++
+ static const struct regmap_config tusb320_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ };
+
+-static int tusb320_extcon_probe(struct i2c_client *client,
+- const struct i2c_device_id *id)
++static int tusb320_extcon_probe(struct tusb320_priv *priv)
++{
++ int ret;
++
++ priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
++ if (IS_ERR(priv->edev)) {
++ dev_err(priv->dev, "failed to allocate extcon device\n");
++ return PTR_ERR(priv->edev);
++ }
++
++ ret = devm_extcon_dev_register(priv->dev, priv->edev);
++ if (ret < 0) {
++ dev_err(priv->dev, "failed to register extcon device\n");
++ return ret;
++ }
++
++ extcon_set_property_capability(priv->edev, EXTCON_USB,
++ EXTCON_PROP_USB_TYPEC_POLARITY);
++ extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
++ EXTCON_PROP_USB_TYPEC_POLARITY);
++
++ return 0;
++}
++
++static int tusb320_typec_probe(struct i2c_client *client,
++ struct tusb320_priv *priv)
++{
++ struct fwnode_handle *connector;
++ const char *cap_str;
++ int ret;
++
++ /* The Type-C connector is optional, for backward compatibility. */
++ connector = device_get_named_child_node(&client->dev, "connector");
++ if (!connector)
++ return 0;
++
++ /* Type-C connector found. */
++ ret = typec_get_fw_cap(&priv->cap, connector);
++ if (ret)
++ return ret;
++
++ priv->port_type = priv->cap.type;
++
++ /* This goes into register 0x8 field CURRENT_MODE_ADVERTISE */
++ ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
++ if (ret)
++ return ret;
++
++ ret = typec_find_pwr_opmode(cap_str);
++ if (ret < 0)
++ return ret;
++ if (ret == TYPEC_PWR_MODE_PD)
++ return -EINVAL;
++
++ priv->pwr_opmode = ret;
++
++ /* Initialize the hardware with the devicetree settings. */
++ ret = tusb320_set_adv_pwr_mode(priv);
++ if (ret)
++ return ret;
++
++ priv->cap.revision = USB_TYPEC_REV_1_1;
++ priv->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO;
++ priv->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG;
++ priv->cap.orientation_aware = true;
++ priv->cap.driver_data = priv;
++ priv->cap.ops = &tusb320_typec_ops;
++ priv->cap.fwnode = connector;
++
++ priv->port = typec_register_port(&client->dev, &priv->cap);
++ if (IS_ERR(priv->port))
++ return PTR_ERR(priv->port);
++
++ return 0;
++}
++
++static int tusb320_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
+ {
+ struct tusb320_priv *priv;
+ const void *match_data;
+@@ -257,12 +455,6 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+
+ priv->ops = (struct tusb320_ops*)match_data;
+
+- priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
+- if (IS_ERR(priv->edev)) {
+- dev_err(priv->dev, "failed to allocate extcon device\n");
+- return PTR_ERR(priv->edev);
+- }
+-
+ if (priv->ops->get_revision) {
+ ret = priv->ops->get_revision(priv, &revision);
+ if (ret)
+@@ -272,19 +464,16 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+ dev_info(priv->dev, "chip revision %d\n", revision);
+ }
+
+- ret = devm_extcon_dev_register(priv->dev, priv->edev);
+- if (ret < 0) {
+- dev_err(priv->dev, "failed to register extcon device\n");
++ ret = tusb320_extcon_probe(priv);
++ if (ret)
+ return ret;
+- }
+
+- extcon_set_property_capability(priv->edev, EXTCON_USB,
+- EXTCON_PROP_USB_TYPEC_POLARITY);
+- extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
+- EXTCON_PROP_USB_TYPEC_POLARITY);
++ ret = tusb320_typec_probe(client, priv);
++ if (ret)
++ return ret;
+
+ /* update initial state */
+- tusb320_irq_handler(client->irq, priv);
++ tusb320_state_update_handler(priv, true);
+
+ /* Reset chip to its default state */
+ ret = tusb320_reset(priv);
+@@ -295,7 +484,7 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+ * State and polarity might change after a reset, so update
+ * them again and make sure the interrupt status bit is cleared.
+ */
+- tusb320_irq_handler(client->irq, priv);
++ tusb320_state_update_handler(priv, true);
+
+ ret = devm_request_threaded_irq(priv->dev, client->irq, NULL,
+ tusb320_irq_handler,
+@@ -313,7 +502,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = {
+ MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
+
+ static struct i2c_driver tusb320_extcon_driver = {
+- .probe = tusb320_extcon_probe,
++ .probe = tusb320_probe,
+ .driver = {
+ .name = "extcon-tusb320",
+ .of_match_table = tusb320_extcon_dt_match,
+diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
+index 4b8978b254f9a..dba315f675bc7 100644
+--- a/drivers/firmware/raspberrypi.c
++++ b/drivers/firmware/raspberrypi.c
+@@ -272,6 +272,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
+ int ret = PTR_ERR(fw->chan);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get mbox channel: %d\n", ret);
++ kfree(fw);
+ return ret;
+ }
+
+diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
+index ebc32bbd9b833..6281e7153b475 100644
+--- a/drivers/firmware/ti_sci.c
++++ b/drivers/firmware/ti_sci.c
+@@ -429,15 +429,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
+ * during noirq phase, so we must manually poll the completion.
+ */
+ ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
+- true, 1,
++ done_state, 1,
+ info->desc->max_rx_timeout_ms * 1000,
+ false, &xfer->done);
+ }
+
+- if (ret == -ETIMEDOUT || !done_state) {
++ if (ret == -ETIMEDOUT)
+ dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
+ (void *)_RET_IP_);
+- }
+
+ /*
+ * NOTE: we might prefer not to need the mailbox ticker to manage the
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index 92f185575e941..12e068dc60bc2 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -55,6 +55,50 @@ static_assert(IS_ALIGNED(sizeof(struct gpio_v2_line_values), 8));
+ * interface to gpiolib GPIOs via ioctl()s.
+ */
+
++typedef __poll_t (*poll_fn)(struct file *, struct poll_table_struct *);
++typedef long (*ioctl_fn)(struct file *, unsigned int, unsigned long);
++typedef ssize_t (*read_fn)(struct file *, char __user *,
++ size_t count, loff_t *);
++
++static __poll_t call_poll_locked(struct file *file,
++ struct poll_table_struct *wait,
++ struct gpio_device *gdev, poll_fn func)
++{
++ __poll_t ret;
++
++ down_read(&gdev->sem);
++ ret = func(file, wait);
++ up_read(&gdev->sem);
++
++ return ret;
++}
++
++static long call_ioctl_locked(struct file *file, unsigned int cmd,
++ unsigned long arg, struct gpio_device *gdev,
++ ioctl_fn func)
++{
++ long ret;
++
++ down_read(&gdev->sem);
++ ret = func(file, cmd, arg);
++ up_read(&gdev->sem);
++
++ return ret;
++}
++
++static ssize_t call_read_locked(struct file *file, char __user *buf,
++ size_t count, loff_t *f_ps,
++ struct gpio_device *gdev, read_fn func)
++{
++ ssize_t ret;
++
++ down_read(&gdev->sem);
++ ret = func(file, buf, count, f_ps);
++ up_read(&gdev->sem);
++
++ return ret;
++}
++
+ /*
+ * GPIO line handle management
+ */
+@@ -191,8 +235,8 @@ static long linehandle_set_config(struct linehandle_state *lh,
+ return 0;
+ }
+
+-static long linehandle_ioctl(struct file *file, unsigned int cmd,
+- unsigned long arg)
++static long linehandle_ioctl_unlocked(struct file *file, unsigned int cmd,
++ unsigned long arg)
+ {
+ struct linehandle_state *lh = file->private_data;
+ void __user *ip = (void __user *)arg;
+@@ -201,6 +245,9 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+ unsigned int i;
+ int ret;
+
++ if (!lh->gdev->chip)
++ return -ENODEV;
++
+ switch (cmd) {
+ case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
+ /* NOTE: It's okay to read values of output lines */
+@@ -247,6 +294,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+ }
+ }
+
++static long linehandle_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct linehandle_state *lh = file->private_data;
++
++ return call_ioctl_locked(file, cmd, arg, lh->gdev,
++ linehandle_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long linehandle_ioctl_compat(struct file *file, unsigned int cmd,
+ unsigned long arg)
+@@ -1378,12 +1434,15 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
+ return ret;
+ }
+
+-static long linereq_ioctl(struct file *file, unsigned int cmd,
+- unsigned long arg)
++static long linereq_ioctl_unlocked(struct file *file, unsigned int cmd,
++ unsigned long arg)
+ {
+ struct linereq *lr = file->private_data;
+ void __user *ip = (void __user *)arg;
+
++ if (!lr->gdev->chip)
++ return -ENODEV;
++
+ switch (cmd) {
+ case GPIO_V2_LINE_GET_VALUES_IOCTL:
+ return linereq_get_values(lr, ip);
+@@ -1396,6 +1455,15 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
+ }
+ }
+
++static long linereq_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct linereq *lr = file->private_data;
++
++ return call_ioctl_locked(file, cmd, arg, lr->gdev,
++ linereq_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long linereq_ioctl_compat(struct file *file, unsigned int cmd,
+ unsigned long arg)
+@@ -1404,12 +1472,15 @@ static long linereq_ioctl_compat(struct file *file, unsigned int cmd,
+ }
+ #endif
+
+-static __poll_t linereq_poll(struct file *file,
+- struct poll_table_struct *wait)
++static __poll_t linereq_poll_unlocked(struct file *file,
++ struct poll_table_struct *wait)
+ {
+ struct linereq *lr = file->private_data;
+ __poll_t events = 0;
+
++ if (!lr->gdev->chip)
++ return EPOLLHUP | EPOLLERR;
++
+ poll_wait(file, &lr->wait, wait);
+
+ if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events,
+@@ -1419,16 +1490,25 @@ static __poll_t linereq_poll(struct file *file,
+ return events;
+ }
+
+-static ssize_t linereq_read(struct file *file,
+- char __user *buf,
+- size_t count,
+- loff_t *f_ps)
++static __poll_t linereq_poll(struct file *file,
++ struct poll_table_struct *wait)
++{
++ struct linereq *lr = file->private_data;
++
++ return call_poll_locked(file, wait, lr->gdev, linereq_poll_unlocked);
++}
++
++static ssize_t linereq_read_unlocked(struct file *file, char __user *buf,
++ size_t count, loff_t *f_ps)
+ {
+ struct linereq *lr = file->private_data;
+ struct gpio_v2_line_event le;
+ ssize_t bytes_read = 0;
+ int ret;
+
++ if (!lr->gdev->chip)
++ return -ENODEV;
++
+ if (count < sizeof(le))
+ return -EINVAL;
+
+@@ -1473,6 +1553,15 @@ static ssize_t linereq_read(struct file *file,
+ return bytes_read;
+ }
+
++static ssize_t linereq_read(struct file *file, char __user *buf,
++ size_t count, loff_t *f_ps)
++{
++ struct linereq *lr = file->private_data;
++
++ return call_read_locked(file, buf, count, f_ps, lr->gdev,
++ linereq_read_unlocked);
++}
++
+ static void linereq_free(struct linereq *lr)
+ {
+ unsigned int i;
+@@ -1692,12 +1781,15 @@ struct lineevent_state {
+ (GPIOEVENT_REQUEST_RISING_EDGE | \
+ GPIOEVENT_REQUEST_FALLING_EDGE)
+
+-static __poll_t lineevent_poll(struct file *file,
+- struct poll_table_struct *wait)
++static __poll_t lineevent_poll_unlocked(struct file *file,
++ struct poll_table_struct *wait)
+ {
+ struct lineevent_state *le = file->private_data;
+ __poll_t events = 0;
+
++ if (!le->gdev->chip)
++ return EPOLLHUP | EPOLLERR;
++
+ poll_wait(file, &le->wait, wait);
+
+ if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock))
+@@ -1706,15 +1798,21 @@ static __poll_t lineevent_poll(struct file *file,
+ return events;
+ }
+
++static __poll_t lineevent_poll(struct file *file,
++ struct poll_table_struct *wait)
++{
++ struct lineevent_state *le = file->private_data;
++
++ return call_poll_locked(file, wait, le->gdev, lineevent_poll_unlocked);
++}
++
+ struct compat_gpioeevent_data {
+ compat_u64 timestamp;
+ u32 id;
+ };
+
+-static ssize_t lineevent_read(struct file *file,
+- char __user *buf,
+- size_t count,
+- loff_t *f_ps)
++static ssize_t lineevent_read_unlocked(struct file *file, char __user *buf,
++ size_t count, loff_t *f_ps)
+ {
+ struct lineevent_state *le = file->private_data;
+ struct gpioevent_data ge;
+@@ -1722,6 +1820,9 @@ static ssize_t lineevent_read(struct file *file,
+ ssize_t ge_size;
+ int ret;
+
++ if (!le->gdev->chip)
++ return -ENODEV;
++
+ /*
+ * When compatible system call is being used the struct gpioevent_data,
+ * in case of at least ia32, has different size due to the alignment
+@@ -1779,6 +1880,15 @@ static ssize_t lineevent_read(struct file *file,
+ return bytes_read;
+ }
+
++static ssize_t lineevent_read(struct file *file, char __user *buf,
++ size_t count, loff_t *f_ps)
++{
++ struct lineevent_state *le = file->private_data;
++
++ return call_read_locked(file, buf, count, f_ps, le->gdev,
++ lineevent_read_unlocked);
++}
++
+ static void lineevent_free(struct lineevent_state *le)
+ {
+ if (le->irq)
+@@ -1796,13 +1906,16 @@ static int lineevent_release(struct inode *inode, struct file *file)
+ return 0;
+ }
+
+-static long lineevent_ioctl(struct file *file, unsigned int cmd,
+- unsigned long arg)
++static long lineevent_ioctl_unlocked(struct file *file, unsigned int cmd,
++ unsigned long arg)
+ {
+ struct lineevent_state *le = file->private_data;
+ void __user *ip = (void __user *)arg;
+ struct gpiohandle_data ghd;
+
++ if (!le->gdev->chip)
++ return -ENODEV;
++
+ /*
+ * We can get the value for an event line but not set it,
+ * because it is input by definition.
+@@ -1825,6 +1938,15 @@ static long lineevent_ioctl(struct file *file, unsigned int cmd,
+ return -EINVAL;
+ }
+
++static long lineevent_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct lineevent_state *le = file->private_data;
++
++ return call_ioctl_locked(file, cmd, arg, le->gdev,
++ lineevent_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long lineevent_ioctl_compat(struct file *file, unsigned int cmd,
+ unsigned long arg)
+@@ -2383,12 +2505,15 @@ static int lineinfo_changed_notify(struct notifier_block *nb,
+ return NOTIFY_OK;
+ }
+
+-static __poll_t lineinfo_watch_poll(struct file *file,
+- struct poll_table_struct *pollt)
++static __poll_t lineinfo_watch_poll_unlocked(struct file *file,
++ struct poll_table_struct *pollt)
+ {
+ struct gpio_chardev_data *cdev = file->private_data;
+ __poll_t events = 0;
+
++ if (!cdev->gdev->chip)
++ return EPOLLHUP | EPOLLERR;
++
+ poll_wait(file, &cdev->wait, pollt);
+
+ if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events,
+@@ -2398,8 +2523,17 @@ static __poll_t lineinfo_watch_poll(struct file *file,
+ return events;
+ }
+
+-static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+- size_t count, loff_t *off)
++static __poll_t lineinfo_watch_poll(struct file *file,
++ struct poll_table_struct *pollt)
++{
++ struct gpio_chardev_data *cdev = file->private_data;
++
++ return call_poll_locked(file, pollt, cdev->gdev,
++ lineinfo_watch_poll_unlocked);
++}
++
++static ssize_t lineinfo_watch_read_unlocked(struct file *file, char __user *buf,
++ size_t count, loff_t *off)
+ {
+ struct gpio_chardev_data *cdev = file->private_data;
+ struct gpio_v2_line_info_changed event;
+@@ -2407,6 +2541,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+ int ret;
+ size_t event_size;
+
++ if (!cdev->gdev->chip)
++ return -ENODEV;
++
+ #ifndef CONFIG_GPIO_CDEV_V1
+ event_size = sizeof(struct gpio_v2_line_info_changed);
+ if (count < event_size)
+@@ -2474,6 +2611,15 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+ return bytes_read;
+ }
+
++static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
++ size_t count, loff_t *off)
++{
++ struct gpio_chardev_data *cdev = file->private_data;
++
++ return call_read_locked(file, buf, count, off, cdev->gdev,
++ lineinfo_watch_read_unlocked);
++}
++
+ /**
+ * gpio_chrdev_open() - open the chardev for ioctl operations
+ * @inode: inode for this chardev
+@@ -2487,13 +2633,17 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
+ struct gpio_chardev_data *cdev;
+ int ret = -ENOMEM;
+
++ down_read(&gdev->sem);
++
+ /* Fail on open if the backing gpiochip is gone */
+- if (!gdev->chip)
+- return -ENODEV;
++ if (!gdev->chip) {
++ ret = -ENODEV;
++ goto out_unlock;
++ }
+
+ cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+ if (!cdev)
+- return -ENOMEM;
++ goto out_unlock;
+
+ cdev->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL);
+ if (!cdev->watched_lines)
+@@ -2516,6 +2666,8 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
+ if (ret)
+ goto out_unregister_notifier;
+
++ up_read(&gdev->sem);
++
+ return ret;
+
+ out_unregister_notifier:
+@@ -2525,6 +2677,8 @@ out_free_bitmap:
+ bitmap_free(cdev->watched_lines);
+ out_free_cdev:
+ kfree(cdev);
++out_unlock:
++ up_read(&gdev->sem);
+ return ret;
+ }
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index eb7d00608c7fb..2adca7c2dd5c8 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -735,6 +735,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->notifier);
++ init_rwsem(&gdev->sem);
+
+ #ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
+@@ -875,6 +876,8 @@ void gpiochip_remove(struct gpio_chip *gc)
+ unsigned long flags;
+ unsigned int i;
+
++ down_write(&gdev->sem);
++
+ /* FIXME: should the legacy sysfs handling be moved to gpio_device? */
+ gpiochip_sysfs_unregister(gdev);
+ gpiochip_free_hogs(gc);
+@@ -909,6 +912,7 @@ void gpiochip_remove(struct gpio_chip *gc)
+ * gone.
+ */
+ gcdev_unregister(gdev);
++ up_write(&gdev->sem);
+ put_device(&gdev->dev);
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_remove);
+diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
+index d900ecdbac46d..9ad68a0adf4a8 100644
+--- a/drivers/gpio/gpiolib.h
++++ b/drivers/gpio/gpiolib.h
+@@ -15,6 +15,7 @@
+ #include <linux/device.h>
+ #include <linux/module.h>
+ #include <linux/cdev.h>
++#include <linux/rwsem.h>
+
+ #define GPIOCHIP_NAME "gpiochip"
+
+@@ -39,6 +40,9 @@
+ * @list: links gpio_device:s together for traversal
+ * @notifier: used to notify subscribers about lines being requested, released
+ * or reconfigured
++ * @sem: protects the structure from a NULL-pointer dereference of @chip by
++ * user-space operations when the device gets unregistered during
++ * a hot-unplug event
+ * @pin_ranges: range of pins served by the GPIO driver
+ *
+ * This state container holds most of the runtime variable data
+@@ -60,6 +64,7 @@ struct gpio_device {
+ void *data;
+ struct list_head list;
+ struct blocking_notifier_head notifier;
++ struct rw_semaphore sem;
+
+ #ifdef CONFIG_PINCTRL
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 5e184952ec988..6659630303a38 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -2253,7 +2253,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
+
+ ret = drm_vma_node_allow(&obj->vma_node, drm_priv);
+ if (ret) {
+- kfree(mem);
++ kfree(*mem);
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+index e363f56c72af1..30c28a69e847d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+@@ -317,6 +317,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
+
+ if (!found)
+ return false;
++ pci_dev_put(pdev);
+
+ adev->bios = kmalloc(size, GFP_KERNEL);
+ if (!adev->bios) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index e0c960cc1d2e1..f04e698e631c5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -5004,6 +5004,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
+ pm_runtime_enable(&(p->dev));
+ pm_runtime_resume(&(p->dev));
+ }
++
++ pci_dev_put(p);
+ }
+
+ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+@@ -5042,6 +5044,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+
+ if (expires < ktime_get_mono_fast_ns()) {
+ dev_warn(adev->dev, "failed to suspend display audio\n");
++ pci_dev_put(p);
+ /* TODO: abort the succeeding gpu reset? */
+ return -ETIMEDOUT;
+ }
+@@ -5049,6 +5052,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+
+ pm_runtime_disable(&(p->dev));
+
++ pci_dev_put(p);
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index 617d072275ebe..77210fd64a2bc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -75,6 +75,8 @@ struct amdgpu_vf_error_buffer {
+ uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ };
+
++enum idh_request;
++
+ /**
+ * struct amdgpu_virt_ops - amdgpu device virt operations
+ */
+@@ -84,7 +86,8 @@ struct amdgpu_virt_ops {
+ int (*req_init_data)(struct amdgpu_device *adev);
+ int (*reset_gpu)(struct amdgpu_device *adev);
+ int (*wait_reset)(struct amdgpu_device *adev);
+- void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
++ void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req,
++ u32 data1, u32 data2, u32 data3);
+ };
+
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
+index b3fba8dea63ca..6853b93ac82e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nv.c
++++ b/drivers/gpu/drm/amd/amdgpu/nv.c
+@@ -82,10 +82,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_encode =
+ /* Navi1x */
+ static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -100,10 +100,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode =
+ /* Sienna Cichlid */
+ static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -125,10 +125,10 @@ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] =
+
+ static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -149,7 +149,7 @@ static struct amdgpu_video_codecs sriov_sc_video_codecs_decode =
+
+ /* Beige Goby*/
+ static const struct amdgpu_video_codec_info bg_video_codecs_decode_array[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+ };
+@@ -166,7 +166,7 @@ static const struct amdgpu_video_codecs bg_video_codecs_encode = {
+
+ /* Yellow Carp*/
+ static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
+index e3b2b6b4f1a66..7cd17dda32ceb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
+@@ -103,10 +103,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_encode =
+ /* Vega */
+ static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ };
+@@ -120,10 +120,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_decode =
+ /* Raven */
+ static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)},
+@@ -138,10 +138,10 @@ static const struct amdgpu_video_codecs rv_video_codecs_decode =
+ /* Renoir, Arcturus */
+ static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
+index 9c3463b481396..6d21c975b73d1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
+@@ -61,7 +61,7 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode =
+
+ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+index a0154a5f71832..e2d3027c39936 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+@@ -41,39 +41,6 @@
+ #include "dm_helpers.h"
+ #include "ddc_service_types.h"
+
+-struct monitor_patch_info {
+- unsigned int manufacturer_id;
+- unsigned int product_id;
+- void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param);
+- unsigned int patch_param;
+-};
+-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param);
+-
+-static const struct monitor_patch_info monitor_patch_table[] = {
+-{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15},
+-{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15},
+-};
+-
+-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param)
+-{
+- if (edid_caps)
+- edid_caps->panel_patch.max_dsc_target_bpp_limit = param;
+-}
+-
+-static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps)
+-{
+- int i, ret = 0;
+-
+- for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++)
+- if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id)
+- && (edid_caps->product_id == monitor_patch_table[i].product_id)) {
+- monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param);
+- ret++;
+- }
+-
+- return ret;
+-}
+-
+ /* dm_helpers_parse_edid_caps
+ *
+ * Parse edid caps
+@@ -148,8 +115,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
+ kfree(sads);
+ kfree(sadb);
+
+- amdgpu_dm_patch_edid_caps(edid_caps);
+-
+ return result;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index de3a1f3fd4f1a..c98cd7c5b9f7a 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -487,6 +487,7 @@ static enum bp_result get_gpio_i2c_info(
+ uint32_t count = 0;
+ unsigned int table_index = 0;
+ bool find_valid = false;
++ struct atom_gpio_pin_assignment *pin;
+
+ if (!info)
+ return BP_RESULT_BADINPUT;
+@@ -514,20 +515,17 @@ static enum bp_result get_gpio_i2c_info(
+ - sizeof(struct atom_common_table_header))
+ / sizeof(struct atom_gpio_pin_assignment);
+
++ pin = (struct atom_gpio_pin_assignment *) header->gpio_pin;
++
+ for (table_index = 0; table_index < count; table_index++) {
+- if (((record->i2c_id & I2C_HW_CAP) == (
+- header->gpio_pin[table_index].gpio_id &
+- I2C_HW_CAP)) &&
+- ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
+- (header->gpio_pin[table_index].gpio_id &
+- I2C_HW_ENGINE_ID_MASK)) &&
+- ((record->i2c_id & I2C_HW_LANE_MUX) ==
+- (header->gpio_pin[table_index].gpio_id &
+- I2C_HW_LANE_MUX))) {
++ if (((record->i2c_id & I2C_HW_CAP) == (pin->gpio_id & I2C_HW_CAP)) &&
++ ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) &&
++ ((record->i2c_id & I2C_HW_LANE_MUX) == (pin->gpio_id & I2C_HW_LANE_MUX))) {
+ /* still valid */
+ find_valid = true;
+ break;
+ }
++ pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment));
+ }
+
+ /* If we don't find the entry that we are looking for then
+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 e7f1d5f8166f9..59a29c32f66a8 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
+@@ -436,7 +436,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
+ }
+
+ if (!new_clocks->dtbclk_en) {
+- new_clocks->ref_dtbclk_khz = 0;
++ new_clocks->ref_dtbclk_khz = clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
+ }
+
+ /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+index fc6aa098bda06..8db9f75144662 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+@@ -1128,6 +1128,7 @@ struct resource_pool *dce60_create_resource_pool(
+ if (dce60_construct(num_virtual_links, dc, pool))
+ return &pool->base;
+
++ kfree(pool);
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+@@ -1325,6 +1326,7 @@ struct resource_pool *dce61_create_resource_pool(
+ if (dce61_construct(num_virtual_links, dc, pool))
+ return &pool->base;
+
++ kfree(pool);
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+@@ -1518,6 +1520,7 @@ struct resource_pool *dce64_create_resource_pool(
+ if (dce64_construct(num_virtual_links, dc, pool))
+ return &pool->base;
+
++ kfree(pool);
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+index b28025960050c..5825e6f412bd7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+@@ -1137,6 +1137,7 @@ struct resource_pool *dce80_create_resource_pool(
+ if (dce80_construct(num_virtual_links, dc, pool))
+ return &pool->base;
+
++ kfree(pool);
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+@@ -1336,6 +1337,7 @@ struct resource_pool *dce81_create_resource_pool(
+ if (dce81_construct(num_virtual_links, dc, pool))
+ return &pool->base;
+
++ kfree(pool);
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index bc9b92838ea9f..d7757e7900ba7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -867,6 +867,32 @@ static void false_optc_underflow_wa(
+ tg->funcs->clear_optc_underflow(tg);
+ }
+
++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
++{
++ struct pipe_ctx *other_pipe;
++ int vready_offset = pipe->pipe_dlg_param.vready_offset;
++
++ /* Always use the largest vready_offset of all connected pipes */
++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++
++ return vready_offset;
++}
++
+ enum dc_status dcn10_enable_stream_timing(
+ struct pipe_ctx *pipe_ctx,
+ struct dc_state *context,
+@@ -902,7 +928,7 @@ enum dc_status dcn10_enable_stream_timing(
+ pipe_ctx->stream_res.tg->funcs->program_timing(
+ pipe_ctx->stream_res.tg,
+ &stream->timing,
+- pipe_ctx->pipe_dlg_param.vready_offset,
++ calculate_vready_offset_for_group(pipe_ctx),
+ pipe_ctx->pipe_dlg_param.vstartup_start,
+ pipe_ctx->pipe_dlg_param.vupdate_offset,
+ pipe_ctx->pipe_dlg_param.vupdate_width,
+@@ -2869,7 +2895,7 @@ void dcn10_program_pipe(
+
+ pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ pipe_ctx->stream_res.tg,
+- pipe_ctx->pipe_dlg_param.vready_offset,
++ calculate_vready_offset_for_group(pipe_ctx),
+ pipe_ctx->pipe_dlg_param.vstartup_start,
+ pipe_ctx->pipe_dlg_param.vupdate_offset,
+ pipe_ctx->pipe_dlg_param.vupdate_width);
+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 0f30df523fdf5..cd799ce6e48b8 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -1608,6 +1608,31 @@ static void dcn20_update_dchubp_dpp(
+ hubp->funcs->phantom_hubp_post_enable(hubp);
+ }
+
++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
++{
++ struct pipe_ctx *other_pipe;
++ int vready_offset = pipe->pipe_dlg_param.vready_offset;
++
++ /* Always use the largest vready_offset of all connected pipes */
++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++ vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++ }
++
++ return vready_offset;
++}
+
+ static void dcn20_program_pipe(
+ struct dc *dc,
+@@ -1626,16 +1651,14 @@ static void dcn20_program_pipe(
+ && !pipe_ctx->prev_odm_pipe) {
+ pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ pipe_ctx->stream_res.tg,
+- pipe_ctx->pipe_dlg_param.vready_offset,
++ calculate_vready_offset_for_group(pipe_ctx),
+ pipe_ctx->pipe_dlg_param.vstartup_start,
+ pipe_ctx->pipe_dlg_param.vupdate_offset,
+ pipe_ctx->pipe_dlg_param.vupdate_width);
+
+ if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+- pipe_ctx->stream_res.tg->funcs->wait_for_state(
+- pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+- pipe_ctx->stream_res.tg->funcs->wait_for_state(
+- pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+ }
+
+ pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+@@ -2040,7 +2063,7 @@ bool dcn20_update_bandwidth(
+
+ pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ pipe_ctx->stream_res.tg,
+- pipe_ctx->pipe_dlg_param.vready_offset,
++ calculate_vready_offset_for_group(pipe_ctx),
+ pipe_ctx->pipe_dlg_param.vstartup_start,
+ pipe_ctx->pipe_dlg_param.vupdate_offset,
+ pipe_ctx->pipe_dlg_param.vupdate_width);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+index 6dd8dadd68a5d..6f160f65c8fa9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+@@ -225,11 +225,7 @@ void dccg32_set_dtbclk_dto(
+ } else {
+ REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+- PIPE_DTO_SRC_SEL[params->otg_inst], 1);
+- if (params->is_hdmi)
+- REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+- PIPE_DTO_SRC_SEL[params->otg_inst], 0);
+-
++ PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
+ REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+ REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
+ }
+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 07c56e231b045..d05df4f7139fd 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
+@@ -485,9 +485,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
+ unsigned int i, pipe_idx;
+ struct pipe_ctx *pipe;
+ uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines;
++ unsigned int num_dpp;
+ unsigned int vlevel = context->bw_ctx.dml.vba.VoltageLevel;
+ unsigned int dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+ unsigned int socclk = context->bw_ctx.dml.vba.SOCCLKPerState[vlevel];
++ struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+
+ dc_assert_fp_enabled();
+
+@@ -523,6 +525,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
+ phantom_vactive = get_subviewport_lines_needed_in_mall(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx) +
+ pstate_width_fw_delay_lines + dc->caps.subvp_swath_height_margin_lines;
+
++ // W/A for DCC corruption with certain high resolution timings.
++ // Determing if pipesplit is used. If so, add meta_row_height to the phantom vactive.
++ num_dpp = vba->NoOfDPP[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]];
++ phantom_vactive += num_dpp > 1 ? vba->meta_row_height[vba->pipe_plane[pipe_idx]] : 0;
++
+ // For backporch of phantom pipe, use vstartup of the main pipe
+ phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+
+diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+index 7e3231c2191ca..ffe19883b2ee9 100644
+--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+@@ -354,7 +354,8 @@ struct amd_pm_funcs {
+ int (*get_power_profile_mode)(void *handle, char *buf);
+ int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
+ int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
+- int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
++ int (*odn_edit_dpm_table)(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++ long *input, uint32_t size);
+ int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
+ int (*smu_i2c_bus_access)(void *handle, bool acquire);
+ int (*gfx_state_change_set)(void *handle, uint32_t state);
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+index 1eb4e613b27a5..6562978de84a0 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+@@ -838,7 +838,8 @@ static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, u
+ return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size);
+ }
+
+-static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size)
++static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++ long *input, uint32_t size)
+ {
+ struct pp_hwmgr *hwmgr = handle;
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
+index 67d7da0b6fed5..1d829402cd2e2 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
+@@ -75,8 +75,10 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
+ for (i = 0; i < table_entries; i++) {
+ result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
+ if (result) {
++ kfree(hwmgr->current_ps);
+ kfree(hwmgr->request_ps);
+ kfree(hwmgr->ps);
++ hwmgr->current_ps = NULL;
+ hwmgr->request_ps = NULL;
+ hwmgr->ps = NULL;
+ return -EINVAL;
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+index 97b3ad3690467..b30684c84e20e 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+@@ -2961,7 +2961,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
+ data->od8_settings.od8_settings_array;
+ OverDriveTable_t *od_table =
+ &(data->smc_state_table.overdrive_table);
+- int32_t input_index, input_clk, input_vol, i;
++ int32_t input_clk, input_vol, i;
++ uint32_t input_index;
+ int od8_id;
+ int ret;
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index 70b560737687e..ad5f6a15a1d7d 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -1588,6 +1588,10 @@ bool smu_v11_0_baco_is_support(struct smu_context *smu)
+ if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support)
+ return false;
+
++ /* return true if ASIC is in BACO state already */
++ if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
++ return true;
++
+ /* Arcturus does not support this bit mask */
+ if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
+ !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
+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 d74debc584f89..39deb06a86ba3 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
+@@ -1436,7 +1436,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
+
+ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf)
+ {
+- DpmActivityMonitorCoeffIntExternal_t activity_monitor_external[PP_SMC_POWER_PROFILE_COUNT];
++ DpmActivityMonitorCoeffIntExternal_t *activity_monitor_external;
+ uint32_t i, j, size = 0;
+ int16_t workload_type = 0;
+ int result = 0;
+@@ -1444,6 +1444,12 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
+ if (!buf)
+ return -EINVAL;
+
++ activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT,
++ sizeof(*activity_monitor_external),
++ GFP_KERNEL);
++ if (!activity_monitor_external)
++ return -ENOMEM;
++
+ size += sysfs_emit_at(buf, size, " ");
+ for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++)
+ size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i],
+@@ -1456,15 +1462,17 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
+ workload_type = smu_cmn_to_asic_specific_index(smu,
+ CMN2ASIC_MAPPING_WORKLOAD,
+ i);
+- if (workload_type < 0)
+- return -EINVAL;
++ if (workload_type < 0) {
++ result = -EINVAL;
++ goto out;
++ }
+
+ result = smu_cmn_update_table(smu,
+ SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
+ (void *)(&activity_monitor_external[i]), false);
+ if (result) {
+ dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
+- return result;
++ goto out;
+ }
+ }
+
+@@ -1492,7 +1500,10 @@ do { \
+ PRINT_DPM_MONITOR(Fclk_BoosterFreq);
+ #undef PRINT_DPM_MONITOR
+
+- return size;
++ result = size;
++out:
++ kfree(activity_monitor_external);
++ return result;
+ }
+
+ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 94de73cbeb2dd..17445800248dd 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+
+ void adv7533_dsi_power_on(struct adv7511 *adv);
+ void adv7533_dsi_power_off(struct adv7511 *adv);
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode);
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++ const struct drm_display_mode *mode);
+ int adv7533_patch_registers(struct adv7511 *adv);
+ int adv7533_patch_cec_registers(struct adv7511 *adv);
+ int adv7533_attach_dsi(struct adv7511 *adv);
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 6031bdd923420..0f0950c111960 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
+ }
+
+ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
+- struct drm_display_mode *mode)
++ const struct drm_display_mode *mode)
+ {
+ if (mode->clock > 165000)
+ return MODE_CLOCK_HIGH;
+@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
+ regmap_update_bits(adv7511->regmap, 0x17,
+ 0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+
+- if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+- adv7533_mode_set(adv7511, adj_mode);
+-
+ drm_mode_copy(&adv7511->curr_mode, adj_mode);
+
+ /*
+@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
+ adv7511_mode_set(adv, mode, adj_mode);
+ }
+
++static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
++ const struct drm_display_info *info,
++ const struct drm_display_mode *mode)
++{
++ struct adv7511 *adv = bridge_to_adv7511(bridge);
++
++ if (adv->type == ADV7533 || adv->type == ADV7535)
++ return adv7533_mode_valid(adv, mode);
++ else
++ return adv7511_mode_valid(adv, mode);
++}
++
+ static int adv7511_bridge_attach(struct drm_bridge *bridge,
+ enum drm_bridge_attach_flags flags)
+ {
+@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = {
+ .enable = adv7511_bridge_enable,
+ .disable = adv7511_bridge_disable,
+ .mode_set = adv7511_bridge_mode_set,
++ .mode_valid = adv7511_bridge_mode_valid,
+ .attach = adv7511_bridge_attach,
+ .detect = adv7511_bridge_detect,
+ .get_edid = adv7511_bridge_get_edid,
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+index ef6270806d1d3..258c79d4dab0a 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
+ regmap_write(adv->regmap_cec, 0x27, 0x0b);
+ }
+
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode)
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++ const struct drm_display_mode *mode)
+ {
++ int lanes;
+ struct mipi_dsi_device *dsi = adv->dsi;
+- int lanes, ret;
+-
+- if (adv->num_dsi_lanes != 4)
+- return;
+
+ if (mode->clock > 80000)
+ lanes = 4;
+ else
+ lanes = 3;
+
+- if (lanes != dsi->lanes) {
+- mipi_dsi_detach(dsi);
+- dsi->lanes = lanes;
+- ret = mipi_dsi_attach(dsi);
+- if (ret)
+- dev_err(&dsi->dev, "failed to change host lanes\n");
+- }
++ /*
++ * TODO: add support for dynamic switching of lanes
++ * by using the bridge pre_enable() op . Till then filter
++ * out the modes which shall need different number of lanes
++ * than what was configured in the device tree.
++ */
++ if (lanes != dsi->lanes)
++ return MODE_BAD;
++
++ return MODE_OK;
+ }
+
+ int adv7533_patch_registers(struct adv7511 *adv)
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index a09d1a39ab0ae..711f403afe7ce 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -2854,10 +2854,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge,
+ }
+
+ /* Register aux channel */
+- it6505->aux.name = "DP-AUX";
+- it6505->aux.dev = dev;
+ it6505->aux.drm_dev = bridge->dev;
+- it6505->aux.transfer = it6505_aux_transfer;
+
+ ret = drm_dp_aux_register(&it6505->aux);
+
+@@ -3310,6 +3307,11 @@ static int it6505_i2c_probe(struct i2c_client *client,
+ DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev));
+ debugfs_init(it6505);
+
++ it6505->aux.name = "DP-AUX";
++ it6505->aux.dev = dev;
++ it6505->aux.transfer = it6505_aux_transfer;
++ drm_dp_aux_init(&it6505->aux);
++
+ it6505->bridge.funcs = &it6505_bridge_funcs;
+ it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+ it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
+index 8bf41aa240687..6526d6ade04bf 100644
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -899,7 +899,6 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
+ bool can_disable_primary_planes)
+ {
+ struct drm_device *dev = crtc_state->crtc->dev;
+- struct drm_atomic_state *state = crtc_state->state;
+
+ if (!crtc_state->enable)
+ return 0;
+@@ -910,14 +909,7 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
+ struct drm_plane *plane;
+
+ drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
+- struct drm_plane_state *plane_state;
+-
+- if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+- continue;
+- plane_state = drm_atomic_get_plane_state(state, plane);
+- if (IS_ERR(plane_state))
+- return PTR_ERR(plane_state);
+- if (plane_state->fb && plane_state->crtc) {
++ if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
+ has_primary_plane = true;
+ break;
+ }
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index eaa819381281b..fefcfac999d99 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -87,6 +87,8 @@ static int oui(u8 first, u8 second, u8 third)
+ #define EDID_QUIRK_FORCE_10BPC (1 << 11)
+ /* Non desktop display (i.e. HMD) */
+ #define EDID_QUIRK_NON_DESKTOP (1 << 12)
++/* Cap the DSC target bitrate to 15bpp */
++#define EDID_QUIRK_CAP_DSC_15BPP (1 << 13)
+
+ #define MICROSOFT_IEEE_OUI 0xca125c
+
+@@ -147,6 +149,12 @@ static const struct edid_quirk {
+ EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 |
+ EDID_QUIRK_DETAILED_IN_CM),
+
++ /* LG 27GP950 */
++ EDID_QUIRK('G', 'S', 'M', 0x5bbf, EDID_QUIRK_CAP_DSC_15BPP),
++
++ /* LG 27GN950 */
++ EDID_QUIRK('G', 'S', 'M', 0x5b9a, EDID_QUIRK_CAP_DSC_15BPP),
++
+ /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
+ EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC),
+
+@@ -6116,6 +6124,7 @@ static void drm_reset_display_info(struct drm_connector *connector)
+
+ info->mso_stream_count = 0;
+ info->mso_pixel_overlap = 0;
++ info->max_dsc_bpp = 0;
+ }
+
+ static u32 update_display_info(struct drm_connector *connector,
+@@ -6202,6 +6211,9 @@ out:
+ info->non_desktop = true;
+ }
+
++ if (quirks & EDID_QUIRK_CAP_DSC_15BPP)
++ info->max_dsc_bpp = 15;
++
+ return quirks;
+ }
+
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 07741b678798b..6768b7d18b6fb 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -263,12 +263,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
+ .vsub = 2, .is_yuv = true },
+ { .format = DRM_FORMAT_Q410, .depth = 0,
+ .num_planes = 3, .char_per_block = { 2, 2, 2 },
+- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+- .vsub = 0, .is_yuv = true },
++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++ .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_Q401, .depth = 0,
+ .num_planes = 3, .char_per_block = { 2, 2, 2 },
+- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+- .vsub = 0, .is_yuv = true },
++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++ .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,
+ .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 2, .vsub = 2, .is_yuv = true},
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 37018bc55810d..f667e7906d1f4 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+ if (gpu->identity.model == chipModel_GC700)
+ gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
+
++ /* These models/revisions don't have the 2D pipe bit */
++ if ((gpu->identity.model == chipModel_GC500 &&
++ gpu->identity.revision <= 2) ||
++ gpu->identity.model == chipModel_GC300)
++ gpu->identity.features |= chipFeatures_PIPE_2D;
++
+ if ((gpu->identity.model == chipModel_GC500 &&
+ gpu->identity.revision < 2) ||
+ (gpu->identity.model == chipModel_GC300 &&
+@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+ gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5);
+ }
+
+- /* GC600 idle register reports zero bits where modules aren't present */
+- if (gpu->identity.model == chipModel_GC600)
++ /* GC600/300 idle register reports zero bits where modules aren't present */
++ if (gpu->identity.model == chipModel_GC600 ||
++ gpu->identity.model == chipModel_GC300)
+ gpu->idle_mask = VIVS_HI_IDLE_STATE_TX |
+ VIVS_HI_IDLE_STATE_RA |
+ VIVS_HI_IDLE_STATE_SE |
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+index 4d4a715b429d1..2c2b92324a2e9 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector)
+ return drm_panel_get_modes(fsl_connector->panel, connector);
+ }
+
+-static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ if (mode->hdisplay & 0xf)
+ return MODE_ERROR;
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
+index 459571e2cc575..2bfcfbfa52a4f 100644
+--- a/drivers/gpu/drm/i915/display/intel_bios.c
++++ b/drivers/gpu/drm/i915/display/intel_bios.c
+@@ -414,7 +414,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ ptrs->lvds_entries++;
+
+ if (size != 0 || ptrs->lvds_entries != 3) {
+- kfree(ptrs);
++ kfree(ptrs_block);
+ return NULL;
+ }
+
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 21ba510716b6c..d852cfd1d6eba 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -3641,61 +3641,6 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
+ }
+ }
+
+-static void
+-intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp,
+- const struct intel_crtc_state *crtc_state)
+-{
+- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+- struct drm_device *dev = dig_port->base.base.dev;
+- struct drm_i915_private *dev_priv = to_i915(dev);
+- struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+- enum pipe pipe = crtc->pipe;
+- u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+-
+- trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+- TRANS_DDI_FUNC_CTL(pipe));
+- trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+- dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+-
+- trans_ddi_func_ctl_value &= ~(TRANS_DDI_FUNC_ENABLE |
+- TGL_TRANS_DDI_PORT_MASK);
+- trans_conf_value &= ~PIPECONF_ENABLE;
+- dp_tp_ctl_value &= ~DP_TP_CTL_ENABLE;
+-
+- intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+- trans_ddi_func_ctl_value);
+- intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+-}
+-
+-static void
+-intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
+- const struct intel_crtc_state *crtc_state)
+-{
+- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+- struct drm_device *dev = dig_port->base.base.dev;
+- struct drm_i915_private *dev_priv = to_i915(dev);
+- enum port port = dig_port->base.port;
+- struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+- enum pipe pipe = crtc->pipe;
+- u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+-
+- trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+- TRANS_DDI_FUNC_CTL(pipe));
+- trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+- dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+-
+- trans_ddi_func_ctl_value |= TRANS_DDI_FUNC_ENABLE |
+- TGL_TRANS_DDI_SELECT_PORT(port);
+- trans_conf_value |= PIPECONF_ENABLE;
+- dp_tp_ctl_value |= DP_TP_CTL_ENABLE;
+-
+- intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+- intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+- trans_ddi_func_ctl_value);
+-}
+-
+ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+ {
+@@ -3714,14 +3659,10 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+ intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ link_status);
+
+- intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
+-
+ intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
+
+ intel_dp_phy_pattern_update(intel_dp, crtc_state);
+
+- intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
+-
+ drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+ intel_dp->train_set, crtc_state->lane_count);
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
+index 04e435bce79bd..cbc8b857d5f7a 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine.h
++++ b/drivers/gpu/drm/i915/gt/intel_engine.h
+@@ -348,4 +348,10 @@ intel_engine_get_hung_context(struct intel_engine_cs *engine)
+ return engine->hung_ce;
+ }
+
++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value);
++
+ #endif /* _INTEL_RINGBUFFER_H_ */
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+index 37fa813af7661..3dd0af057e6b1 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+@@ -486,6 +486,17 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ engine->logical_mask = BIT(logical_instance);
+ __sprint_engine_name(engine);
+
++ if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) &&
++ __ffs(CCS_MASK(engine->gt)) == engine->instance) ||
++ engine->class == RENDER_CLASS)
++ engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE;
++
++ /* features common between engines sharing EUs */
++ if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) {
++ engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE;
++ engine->flags |= I915_ENGINE_HAS_EU_PRIORITY;
++ }
++
+ engine->props.heartbeat_interval_ms =
+ CONFIG_DRM_I915_HEARTBEAT_INTERVAL;
+ engine->props.max_busywait_duration_ns =
+@@ -498,19 +509,28 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ CONFIG_DRM_I915_TIMESLICE_DURATION;
+
+ /* Override to uninterruptible for OpenCL workloads. */
+- if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS)
++ if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE))
+ engine->props.preempt_timeout_ms = 0;
+
+- if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) &&
+- __ffs(CCS_MASK(engine->gt)) == engine->instance) ||
+- engine->class == RENDER_CLASS)
+- engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE;
+-
+- /* features common between engines sharing EUs */
+- if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) {
+- engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE;
+- engine->flags |= I915_ENGINE_HAS_EU_PRIORITY;
+- }
++ /* Cap properties according to any system limits */
++#define CLAMP_PROP(field) \
++ do { \
++ u64 clamp = intel_clamp_##field(engine, engine->props.field); \
++ if (clamp != engine->props.field) { \
++ drm_notice(&engine->i915->drm, \
++ "Warning, clamping %s to %lld to prevent overflow\n", \
++ #field, clamp); \
++ engine->props.field = clamp; \
++ } \
++ } while (0)
++
++ CLAMP_PROP(heartbeat_interval_ms);
++ CLAMP_PROP(max_busywait_duration_ns);
++ CLAMP_PROP(preempt_timeout_ms);
++ CLAMP_PROP(stop_timeout_ms);
++ CLAMP_PROP(timeslice_duration_ms);
++
++#undef CLAMP_PROP
+
+ engine->defaults = engine->props; /* never to change again */
+
+@@ -534,6 +554,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ return 0;
+ }
+
++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value)
++{
++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++ return value;
++}
++
++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value)
++{
++ value = min(value, jiffies_to_nsecs(2));
++
++ return value;
++}
++
++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value)
++{
++ /*
++ * NB: The GuC API only supports 32bit values. However, the limit is further
++ * reduced due to internal calculations which would otherwise overflow.
++ */
++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
++ value = min_t(u64, value, guc_policy_max_preempt_timeout_ms());
++
++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++ return value;
++}
++
++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value)
++{
++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++ return value;
++}
++
++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value)
++{
++ /*
++ * NB: The GuC API only supports 32bit values. However, the limit is further
++ * reduced due to internal calculations which would otherwise overflow.
++ */
++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
++ value = min_t(u64, value, guc_policy_max_exec_quantum_ms());
++
++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++ return value;
++}
++
+ static void __setup_engine_capabilities(struct intel_engine_cs *engine)
+ {
+ struct drm_i915_private *i915 = engine->i915;
+diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c
+index 9670310562029..f2d9858d827c2 100644
+--- a/drivers/gpu/drm/i915/gt/sysfs_engines.c
++++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c
+@@ -144,7 +144,7 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+ {
+ struct intel_engine_cs *engine = kobj_to_engine(kobj);
+- unsigned long long duration;
++ unsigned long long duration, clamped;
+ int err;
+
+ /*
+@@ -168,7 +168,8 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr,
+ if (err)
+ return err;
+
+- if (duration > jiffies_to_nsecs(2))
++ clamped = intel_clamp_max_busywait_duration_ns(engine, duration);
++ if (duration != clamped)
+ return -EINVAL;
+
+ WRITE_ONCE(engine->props.max_busywait_duration_ns, duration);
+@@ -203,7 +204,7 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+ {
+ struct intel_engine_cs *engine = kobj_to_engine(kobj);
+- unsigned long long duration;
++ unsigned long long duration, clamped;
+ int err;
+
+ /*
+@@ -218,7 +219,8 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr,
+ if (err)
+ return err;
+
+- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++ clamped = intel_clamp_timeslice_duration_ms(engine, duration);
++ if (duration != clamped)
+ return -EINVAL;
+
+ WRITE_ONCE(engine->props.timeslice_duration_ms, duration);
+@@ -256,7 +258,7 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+ {
+ struct intel_engine_cs *engine = kobj_to_engine(kobj);
+- unsigned long long duration;
++ unsigned long long duration, clamped;
+ int err;
+
+ /*
+@@ -272,7 +274,8 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr,
+ if (err)
+ return err;
+
+- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++ clamped = intel_clamp_stop_timeout_ms(engine, duration);
++ if (duration != clamped)
+ return -EINVAL;
+
+ WRITE_ONCE(engine->props.stop_timeout_ms, duration);
+@@ -306,7 +309,7 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+ {
+ struct intel_engine_cs *engine = kobj_to_engine(kobj);
+- unsigned long long timeout;
++ unsigned long long timeout, clamped;
+ int err;
+
+ /*
+@@ -322,7 +325,8 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr,
+ if (err)
+ return err;
+
+- if (timeout > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++ clamped = intel_clamp_preempt_timeout_ms(engine, timeout);
++ if (timeout != clamped)
+ return -EINVAL;
+
+ WRITE_ONCE(engine->props.preempt_timeout_ms, timeout);
+@@ -362,7 +366,7 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+ {
+ struct intel_engine_cs *engine = kobj_to_engine(kobj);
+- unsigned long long delay;
++ unsigned long long delay, clamped;
+ int err;
+
+ /*
+@@ -379,7 +383,8 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr,
+ if (err)
+ return err;
+
+- if (delay >= jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++ clamped = intel_clamp_heartbeat_interval_ms(engine, delay);
++ if (delay != clamped)
+ return -EINVAL;
+
+ err = intel_engine_set_heartbeat(engine, delay);
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+index 2706a8c650900..7fbcfeda91951 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+@@ -224,53 +224,22 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc)
+
+ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
+ {
+- u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT;
+- u32 flags;
+-
+- #if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
+- #define LOG_UNIT SZ_1M
+- #define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
+- #else
+- #define LOG_UNIT SZ_4K
+- #define LOG_FLAG 0
+- #endif
+-
+- #if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
+- #define CAPTURE_UNIT SZ_1M
+- #define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
+- #else
+- #define CAPTURE_UNIT SZ_4K
+- #define CAPTURE_FLAG 0
+- #endif
+-
+- BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
+- BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
+- BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
+- BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
+- BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
+- BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
+-
+- BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
+- (GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
+- BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
+- (GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
+- BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
+- (GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
++ struct intel_guc_log *log = &guc->log;
++ u32 offset, flags;
++
++ GEM_BUG_ON(!log->sizes_initialised);
++
++ offset = intel_guc_ggtt_offset(guc, log->vma) >> PAGE_SHIFT;
+
+ flags = GUC_LOG_VALID |
+ GUC_LOG_NOTIFY_ON_HALF_FULL |
+- CAPTURE_FLAG |
+- LOG_FLAG |
+- ((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
+- ((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+- ((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
++ log->sizes[GUC_LOG_SECTIONS_DEBUG].flag |
++ log->sizes[GUC_LOG_SECTIONS_CAPTURE].flag |
++ (log->sizes[GUC_LOG_SECTIONS_CRASH].count << GUC_LOG_CRASH_SHIFT) |
++ (log->sizes[GUC_LOG_SECTIONS_DEBUG].count << GUC_LOG_DEBUG_SHIFT) |
++ (log->sizes[GUC_LOG_SECTIONS_CAPTURE].count << GUC_LOG_CAPTURE_SHIFT) |
+ (offset << GUC_LOG_BUF_ADDR_SHIFT);
+
+- #undef LOG_UNIT
+- #undef LOG_FLAG
+- #undef CAPTURE_UNIT
+- #undef CAPTURE_FLAG
+-
+ return flags;
+ }
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+index 75257bd20ff01..4c51888fd78b4 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+@@ -165,7 +165,7 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = {
+ }
+
+ /* List of lists */
+-static struct __guc_mmio_reg_descr_group default_lists[] = {
++static const struct __guc_mmio_reg_descr_group default_lists[] = {
+ MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
+ MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
+ MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
+@@ -419,6 +419,44 @@ guc_capture_get_device_reglist(struct intel_guc *guc)
+ return default_lists;
+ }
+
++static const char *
++__stringify_type(u32 type)
++{
++ switch (type) {
++ case GUC_CAPTURE_LIST_TYPE_GLOBAL:
++ return "Global";
++ case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS:
++ return "Class";
++ case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE:
++ return "Instance";
++ default:
++ break;
++ }
++
++ return "unknown";
++}
++
++static const char *
++__stringify_engclass(u32 class)
++{
++ switch (class) {
++ case GUC_RENDER_CLASS:
++ return "Render";
++ case GUC_VIDEO_CLASS:
++ return "Video";
++ case GUC_VIDEOENHANCE_CLASS:
++ return "VideoEnhance";
++ case GUC_BLITTER_CLASS:
++ return "Blitter";
++ case GUC_COMPUTE_CLASS:
++ return "Compute";
++ default:
++ break;
++ }
++
++ return "unknown";
++}
++
+ static int
+ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+ struct guc_mmio_reg *ptr, u16 num_entries)
+@@ -482,32 +520,55 @@ guc_cap_list_num_regs(struct intel_guc_state_capture *gc, u32 owner, u32 type, u
+ return num_regs;
+ }
+
+-int
+-intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+- size_t *size)
++static int
++guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
++ size_t *size, bool is_purpose_est)
+ {
+ struct intel_guc_state_capture *gc = guc->capture;
++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+ struct __guc_capture_ads_cache *cache = &gc->ads_cache[owner][type][classid];
+ int num_regs;
+
+- if (!gc->reglists)
++ if (!gc->reglists) {
++ drm_warn(&i915->drm, "GuC-capture: No reglist on this device\n");
+ return -ENODEV;
++ }
+
+ if (cache->is_valid) {
+ *size = cache->size;
+ return cache->status;
+ }
+
++ if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF &&
++ !guc_capture_get_one_list(gc->reglists, owner, type, classid)) {
++ if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL)
++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist Global!\n");
++ else
++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist %s(%u):%s(%u)!\n",
++ __stringify_type(type), type,
++ __stringify_engclass(classid), classid);
++ return -ENODATA;
++ }
++
+ num_regs = guc_cap_list_num_regs(gc, owner, type, classid);
++ /* intentional empty lists can exist depending on hw config */
+ if (!num_regs)
+ return -ENODATA;
+
+- *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) +
+- (num_regs * sizeof(struct guc_mmio_reg)));
++ if (size)
++ *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) +
++ (num_regs * sizeof(struct guc_mmio_reg)));
+
+ return 0;
+ }
+
++int
++intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
++ size_t *size)
++{
++ return guc_capture_getlistsize(guc, owner, type, classid, size, false);
++}
++
+ static void guc_capture_create_prealloc_nodes(struct intel_guc *guc);
+
+ int
+@@ -600,15 +661,13 @@ intel_guc_capture_getnullheader(struct intel_guc *guc,
+ return 0;
+ }
+
+-#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
+-
+-int
+-intel_guc_capture_output_min_size_est(struct intel_guc *guc)
++static int
++guc_capture_output_min_size_est(struct intel_guc *guc)
+ {
+ struct intel_gt *gt = guc_to_gt(guc);
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+- int worst_min_size = 0, num_regs = 0;
++ int worst_min_size = 0;
+ size_t tmp = 0;
+
+ if (!guc->capture)
+@@ -623,33 +682,58 @@ intel_guc_capture_output_min_size_est(struct intel_guc *guc)
+ * For each engine instance, there would be 1 x guc_state_capture_group_t output
+ * followed by 3 x guc_state_capture_t lists. The latter is how the register
+ * dumps are split across different register types (where the '3' are global vs class
+- * vs instance). Finally, let's multiply the whole thing by 3x (just so we are
+- * not limited to just 1 round of data in a worst case full register dump log)
+- *
+- * NOTE: intel_guc_log that allocates the log buffer would round this size up to
+- * a power of two.
++ * vs instance).
+ */
+-
+ for_each_engine(engine, gt, id) {
+ worst_min_size += sizeof(struct guc_state_capture_group_header_t) +
+ (3 * sizeof(struct guc_state_capture_header_t));
+
+- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp))
+- num_regs += tmp;
++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp, true))
++ worst_min_size += tmp;
+
+- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS,
+- engine->class, &tmp)) {
+- num_regs += tmp;
++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS,
++ engine->class, &tmp, true)) {
++ worst_min_size += tmp;
+ }
+- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE,
+- engine->class, &tmp)) {
+- num_regs += tmp;
++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE,
++ engine->class, &tmp, true)) {
++ worst_min_size += tmp;
+ }
+ }
+
+- worst_min_size += (num_regs * sizeof(struct guc_mmio_reg));
++ return worst_min_size;
++}
++
++/*
++ * Add on a 3x multiplier to allow for multiple back-to-back captures occurring
++ * before the i915 can read the data out and process it
++ */
++#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
+
+- return (worst_min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER);
++static void check_guc_capture_size(struct intel_guc *guc)
++{
++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
++ int min_size = guc_capture_output_min_size_est(guc);
++ int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER;
++ u32 buffer_size = intel_guc_log_section_size_capture(&guc->log);
++
++ /*
++ * NOTE: min_size is much smaller than the capture region allocation (DG2: <80K vs 1MB)
++ * Additionally, its based on space needed to fit all engines getting reset at once
++ * within the same G2H handler task slot. This is very unlikely. However, if GuC really
++ * does run out of space for whatever reason, we will see an separate warning message
++ * when processing the G2H event capture-notification, search for:
++ * INTEL_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE.
++ */
++ if (min_size < 0)
++ drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n",
++ min_size);
++ else if (min_size > buffer_size)
++ drm_warn(&i915->drm, "GuC error state capture buffer maybe small: %d < %d\n",
++ buffer_size, min_size);
++ else if (spare_size > buffer_size)
++ drm_dbg(&i915->drm, "GuC error state capture buffer lacks spare size: %d < %d (min = %d)\n",
++ buffer_size, spare_size, min_size);
+ }
+
+ /*
+@@ -1278,7 +1362,8 @@ static void __guc_capture_process_output(struct intel_guc *guc)
+
+ log_buf_state = guc->log.buf_addr +
+ (sizeof(struct guc_log_buffer_state) * GUC_CAPTURE_LOG_BUFFER);
+- src_data = guc->log.buf_addr + intel_guc_get_log_buffer_offset(GUC_CAPTURE_LOG_BUFFER);
++ src_data = guc->log.buf_addr +
++ intel_guc_get_log_buffer_offset(&guc->log, GUC_CAPTURE_LOG_BUFFER);
+
+ /*
+ * Make a copy of the state structure, inside GuC log buffer
+@@ -1286,7 +1371,7 @@ static void __guc_capture_process_output(struct intel_guc *guc)
+ * from it multiple times.
+ */
+ memcpy(&log_buf_state_local, log_buf_state, sizeof(struct guc_log_buffer_state));
+- buffer_size = intel_guc_get_log_buffer_size(GUC_CAPTURE_LOG_BUFFER);
++ buffer_size = intel_guc_get_log_buffer_size(&guc->log, GUC_CAPTURE_LOG_BUFFER);
+ read_offset = log_buf_state_local.read_ptr;
+ write_offset = log_buf_state_local.sampled_write_ptr;
+ full_count = log_buf_state_local.buffer_full_cnt;
+@@ -1580,5 +1665,7 @@ int intel_guc_capture_init(struct intel_guc *guc)
+ INIT_LIST_HEAD(&guc->capture->outlist);
+ INIT_LIST_HEAD(&guc->capture->cachelist);
+
++ check_guc_capture_size(guc);
++
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+index d3d7bd0b6db64..fbd3713c7832d 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+@@ -21,7 +21,6 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *m,
+ void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct intel_engine_coredump *ee,
+ struct intel_context *ce);
+ void intel_guc_capture_process(struct intel_guc *guc);
+-int intel_guc_capture_output_min_size_est(struct intel_guc *guc);
+ int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+ void **outptr);
+ int intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+index 323b055e5db97..502e7cb5a3025 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+@@ -305,6 +305,27 @@ struct guc_update_context_policy {
+
+ #define GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US 500000
+
++/*
++ * GuC converts the timeout to clock ticks internally. Different platforms have
++ * different GuC clocks. Thus, the maximum value before overflow is platform
++ * dependent. Current worst case scenario is about 110s. So, the spec says to
++ * limit to 100s to be safe.
++ */
++#define GUC_POLICY_MAX_EXEC_QUANTUM_US (100 * 1000 * 1000UL)
++#define GUC_POLICY_MAX_PREEMPT_TIMEOUT_US (100 * 1000 * 1000UL)
++
++static inline u32 guc_policy_max_exec_quantum_ms(void)
++{
++ BUILD_BUG_ON(GUC_POLICY_MAX_EXEC_QUANTUM_US >= UINT_MAX);
++ return GUC_POLICY_MAX_EXEC_QUANTUM_US / 1000;
++}
++
++static inline u32 guc_policy_max_preempt_timeout_ms(void)
++{
++ BUILD_BUG_ON(GUC_POLICY_MAX_PREEMPT_TIMEOUT_US >= UINT_MAX);
++ return GUC_POLICY_MAX_PREEMPT_TIMEOUT_US / 1000;
++}
++
+ struct guc_policies {
+ u32 submission_queue_depth[GUC_MAX_ENGINE_CLASSES];
+ /* In micro seconds. How much time to allow before DPC processing is
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+index 25b2d7ce6640d..8d755d285247e 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+@@ -13,8 +13,187 @@
+ #include "intel_guc_capture.h"
+ #include "intel_guc_log.h"
+
++#if defined(CONFIG_DRM_I915_DEBUG_GUC)
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M
++#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_1M
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_2M
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M
++#else
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_8K
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_64K
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M
++#endif
++
+ static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log);
+
++struct guc_log_section {
++ u32 max;
++ u32 flag;
++ u32 default_val;
++ const char *name;
++};
++
++static s32 scale_log_param(struct intel_guc_log *log, const struct guc_log_section *section,
++ s32 param)
++{
++ /* -1 means default */
++ if (param < 0)
++ return section->default_val;
++
++ /* Check for 32-bit overflow */
++ if (param >= SZ_4K) {
++ drm_err(&guc_to_gt(log_to_guc(log))->i915->drm, "Size too large for GuC %s log: %dMB!",
++ section->name, param);
++ return section->default_val;
++ }
++
++ /* Param units are 1MB */
++ return param * SZ_1M;
++}
++
++static void _guc_log_init_sizes(struct intel_guc_log *log)
++{
++ struct intel_guc *guc = log_to_guc(log);
++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
++ static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = {
++ {
++ GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT,
++ GUC_LOG_LOG_ALLOC_UNITS,
++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE,
++ "crash dump"
++ },
++ {
++ GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT,
++ GUC_LOG_LOG_ALLOC_UNITS,
++ GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE,
++ "debug",
++ },
++ {
++ GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT,
++ GUC_LOG_CAPTURE_ALLOC_UNITS,
++ GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE,
++ "capture",
++ }
++ };
++ s32 params[GUC_LOG_SECTIONS_LIMIT] = {
++ i915->params.guc_log_size_crash,
++ i915->params.guc_log_size_debug,
++ i915->params.guc_log_size_capture,
++ };
++ int i;
++
++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++)
++ log->sizes[i].bytes = scale_log_param(log, sections + i, params[i]);
++
++ /* If debug size > 1MB then bump default crash size to keep the same units */
++ if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M &&
++ (i915->params.guc_log_size_crash == -1) &&
++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE < SZ_1M)
++ log->sizes[GUC_LOG_SECTIONS_CRASH].bytes = SZ_1M;
++
++ /* Prepare the GuC API structure fields: */
++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) {
++ /* Convert to correct units */
++ if ((log->sizes[i].bytes % SZ_1M) == 0) {
++ log->sizes[i].units = SZ_1M;
++ log->sizes[i].flag = sections[i].flag;
++ } else {
++ log->sizes[i].units = SZ_4K;
++ log->sizes[i].flag = 0;
++ }
++
++ if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units))
++ drm_err(&i915->drm, "Mis-aligned GuC log %s size: 0x%X vs 0x%X!",
++ sections[i].name, log->sizes[i].bytes, log->sizes[i].units);
++ log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units;
++
++ if (!log->sizes[i].count) {
++ drm_err(&i915->drm, "Zero GuC log %s size!", sections[i].name);
++ } else {
++ /* Size is +1 unit */
++ log->sizes[i].count--;
++ }
++
++ /* Clip to field size */
++ if (log->sizes[i].count > sections[i].max) {
++ drm_err(&i915->drm, "GuC log %s size too large: %d vs %d!",
++ sections[i].name, log->sizes[i].count + 1, sections[i].max + 1);
++ log->sizes[i].count = sections[i].max;
++ }
++ }
++
++ if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) {
++ drm_err(&i915->drm, "Unit mis-match for GuC log crash and debug sections: %d vs %d!",
++ log->sizes[GUC_LOG_SECTIONS_CRASH].units,
++ log->sizes[GUC_LOG_SECTIONS_DEBUG].units);
++ log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units;
++ log->sizes[GUC_LOG_SECTIONS_CRASH].count = 0;
++ }
++
++ log->sizes_initialised = true;
++}
++
++static void guc_log_init_sizes(struct intel_guc_log *log)
++{
++ if (log->sizes_initialised)
++ return;
++
++ _guc_log_init_sizes(log);
++}
++
++static u32 intel_guc_log_section_size_crash(struct intel_guc_log *log)
++{
++ guc_log_init_sizes(log);
++
++ return log->sizes[GUC_LOG_SECTIONS_CRASH].bytes;
++}
++
++static u32 intel_guc_log_section_size_debug(struct intel_guc_log *log)
++{
++ guc_log_init_sizes(log);
++
++ return log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes;
++}
++
++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log)
++{
++ guc_log_init_sizes(log);
++
++ return log->sizes[GUC_LOG_SECTIONS_CAPTURE].bytes;
++}
++
++static u32 intel_guc_log_size(struct intel_guc_log *log)
++{
++ /*
++ * GuC Log buffer Layout:
++ *
++ * NB: Ordering must follow "enum guc_log_buffer_type".
++ *
++ * +===============================+ 00B
++ * | Debug state header |
++ * +-------------------------------+ 32B
++ * | Crash dump state header |
++ * +-------------------------------+ 64B
++ * | Capture state header |
++ * +-------------------------------+ 96B
++ * | |
++ * +===============================+ PAGE_SIZE (4KB)
++ * | Debug logs |
++ * +===============================+ + DEBUG_SIZE
++ * | Crash Dump logs |
++ * +===============================+ + CRASH_SIZE
++ * | Capture logs |
++ * +===============================+ + CAPTURE_SIZE
++ */
++ return PAGE_SIZE +
++ intel_guc_log_section_size_crash(log) +
++ intel_guc_log_section_size_debug(log) +
++ intel_guc_log_section_size_capture(log);
++}
++
+ /**
+ * DOC: GuC firmware log
+ *
+@@ -139,7 +318,8 @@ static void guc_move_to_next_buf(struct intel_guc_log *log)
+ smp_wmb();
+
+ /* All data has been written, so now move the offset of sub buffer. */
+- relay_reserve(log->relay.channel, log->vma->obj->base.size - CAPTURE_BUFFER_SIZE);
++ relay_reserve(log->relay.channel, log->vma->obj->base.size -
++ intel_guc_log_section_size_capture(log));
+
+ /* Switch to the next sub buffer */
+ relay_flush(log->relay.channel);
+@@ -184,15 +364,16 @@ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log,
+ return overflow;
+ }
+
+-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type)
++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log,
++ enum guc_log_buffer_type type)
+ {
+ switch (type) {
+ case GUC_DEBUG_LOG_BUFFER:
+- return DEBUG_BUFFER_SIZE;
++ return intel_guc_log_section_size_debug(log);
+ case GUC_CRASH_DUMP_LOG_BUFFER:
+- return CRASH_BUFFER_SIZE;
++ return intel_guc_log_section_size_crash(log);
+ case GUC_CAPTURE_LOG_BUFFER:
+- return CAPTURE_BUFFER_SIZE;
++ return intel_guc_log_section_size_capture(log);
+ default:
+ MISSING_CASE(type);
+ }
+@@ -200,7 +381,8 @@ unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type)
+ return 0;
+ }
+
+-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type)
++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log,
++ enum guc_log_buffer_type type)
+ {
+ enum guc_log_buffer_type i;
+ size_t offset = PAGE_SIZE;/* for the log_buffer_states */
+@@ -208,7 +390,7 @@ size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type)
+ for (i = GUC_DEBUG_LOG_BUFFER; i < GUC_MAX_LOG_BUFFER; ++i) {
+ if (i == type)
+ break;
+- offset += intel_guc_get_log_buffer_size(i);
++ offset += intel_guc_get_log_buffer_size(log, i);
+ }
+
+ return offset;
+@@ -259,7 +441,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log)
+ */
+ memcpy(&log_buf_state_local, log_buf_state,
+ sizeof(struct guc_log_buffer_state));
+- buffer_size = intel_guc_get_log_buffer_size(type);
++ buffer_size = intel_guc_get_log_buffer_size(log, type);
+ read_offset = log_buf_state_local.read_ptr;
+ write_offset = log_buf_state_local.sampled_write_ptr;
+ full_cnt = log_buf_state_local.buffer_full_cnt;
+@@ -374,7 +556,7 @@ static int guc_log_relay_create(struct intel_guc_log *log)
+ * Keep the size of sub buffers same as shared log buffer
+ * but GuC log-events excludes the error-state-capture logs
+ */
+- subbuf_size = log->vma->size - CAPTURE_BUFFER_SIZE;
++ subbuf_size = log->vma->size - intel_guc_log_section_size_capture(log);
+
+ /*
+ * Store up to 8 snapshots, which is large enough to buffer sufficient
+@@ -461,32 +643,7 @@ int intel_guc_log_create(struct intel_guc_log *log)
+
+ GEM_BUG_ON(log->vma);
+
+- /*
+- * GuC Log buffer Layout
+- * (this ordering must follow "enum guc_log_buffer_type" definition)
+- *
+- * +===============================+ 00B
+- * | Debug state header |
+- * +-------------------------------+ 32B
+- * | Crash dump state header |
+- * +-------------------------------+ 64B
+- * | Capture state header |
+- * +-------------------------------+ 96B
+- * | |
+- * +===============================+ PAGE_SIZE (4KB)
+- * | Debug logs |
+- * +===============================+ + DEBUG_SIZE
+- * | Crash Dump logs |
+- * +===============================+ + CRASH_SIZE
+- * | Capture logs |
+- * +===============================+ + CAPTURE_SIZE
+- */
+- if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE)
+- DRM_WARN("GuC log buffer for state_capture maybe too small. %d < %d\n",
+- CAPTURE_BUFFER_SIZE, intel_guc_capture_output_min_size_est(guc));
+-
+- guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
+- CAPTURE_BUFFER_SIZE;
++ guc_log_size = intel_guc_log_size(log);
+
+ vma = intel_guc_allocate_vma(guc, guc_log_size);
+ if (IS_ERR(vma)) {
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+index 18007e639be99..02127703be809 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+@@ -15,20 +15,6 @@
+
+ struct intel_guc;
+
+-#if defined(CONFIG_DRM_I915_DEBUG_GUC)
+-#define CRASH_BUFFER_SIZE SZ_2M
+-#define DEBUG_BUFFER_SIZE SZ_16M
+-#define CAPTURE_BUFFER_SIZE SZ_4M
+-#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
+-#define CRASH_BUFFER_SIZE SZ_1M
+-#define DEBUG_BUFFER_SIZE SZ_2M
+-#define CAPTURE_BUFFER_SIZE SZ_1M
+-#else
+-#define CRASH_BUFFER_SIZE SZ_8K
+-#define DEBUG_BUFFER_SIZE SZ_64K
+-#define CAPTURE_BUFFER_SIZE SZ_16K
+-#endif
+-
+ /*
+ * While we're using plain log level in i915, GuC controls are much more...
+ * "elaborate"? We have a couple of bits for verbosity, separate bit for actual
+@@ -46,10 +32,30 @@ struct intel_guc;
+ #define GUC_VERBOSITY_TO_LOG_LEVEL(x) ((x) + 2)
+ #define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX)
+
++enum {
++ GUC_LOG_SECTIONS_CRASH,
++ GUC_LOG_SECTIONS_DEBUG,
++ GUC_LOG_SECTIONS_CAPTURE,
++ GUC_LOG_SECTIONS_LIMIT
++};
++
+ struct intel_guc_log {
+ u32 level;
++
++ /* Allocation settings */
++ struct {
++ s32 bytes; /* Size in bytes */
++ s32 units; /* GuC API units - 1MB or 4KB */
++ s32 count; /* Number of API units */
++ u32 flag; /* GuC API units flag */
++ } sizes[GUC_LOG_SECTIONS_LIMIT];
++ bool sizes_initialised;
++
++ /* Combined buffer allocation */
+ struct i915_vma *vma;
+ void *buf_addr;
++
++ /* RelayFS support */
+ struct {
+ bool buf_in_use;
+ bool started;
+@@ -58,6 +64,7 @@ struct intel_guc_log {
+ struct mutex lock;
+ u32 full_count;
+ } relay;
++
+ /* logging related stats */
+ struct {
+ u32 sampled_overflow;
+@@ -69,8 +76,9 @@ struct intel_guc_log {
+ void intel_guc_log_init_early(struct intel_guc_log *log);
+ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, enum guc_log_buffer_type type,
+ unsigned int full_cnt);
+-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type);
+-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type);
++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log,
++ enum guc_log_buffer_type type);
++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, enum guc_log_buffer_type type);
+ int intel_guc_log_create(struct intel_guc_log *log);
+ void intel_guc_log_destroy(struct intel_guc_log *log);
+
+@@ -92,4 +100,6 @@ void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p);
+ int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p,
+ bool dump_load_err);
+
++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log);
++
+ #endif
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index fe179146d51b9..cd0c5043863b6 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -2430,6 +2430,10 @@ static int guc_context_policy_init_v70(struct intel_context *ce, bool loop)
+ int ret;
+
+ /* NB: For both of these, zero means disabled. */
++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000,
++ execution_quantum));
++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000,
++ preemption_timeout));
+ execution_quantum = engine->props.timeslice_duration_ms * 1000;
+ preemption_timeout = engine->props.preempt_timeout_ms * 1000;
+
+@@ -2486,6 +2490,10 @@ static void guc_context_policy_init_v69(struct intel_engine_cs *engine,
+ desc->policy_flags |= CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69;
+
+ /* NB: For both of these, zero means disabled. */
++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000,
++ desc->execution_quantum));
++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000,
++ desc->preemption_timeout));
+ desc->execution_quantum = engine->props.timeslice_duration_ms * 1000;
+ desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000;
+ }
+diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
+index 6fc475a5db615..06ca5b8221118 100644
+--- a/drivers/gpu/drm/i915/i915_params.c
++++ b/drivers/gpu/drm/i915/i915_params.c
+@@ -171,6 +171,18 @@ i915_param_named(guc_log_level, int, 0400,
+ "GuC firmware logging level. Requires GuC to be loaded. "
+ "(-1=auto [default], 0=disable, 1..4=enable with verbosity min..max)");
+
++i915_param_named(guc_log_size_crash, int, 0400,
++ "GuC firmware logging buffer size for crash dumps (in MB)"
++ "(-1=auto [default], NB: max = 4, other restrictions apply)");
++
++i915_param_named(guc_log_size_debug, int, 0400,
++ "GuC firmware logging buffer size for debug logs (in MB)"
++ "(-1=auto [default], NB: max = 16, other restrictions apply)");
++
++i915_param_named(guc_log_size_capture, int, 0400,
++ "GuC error capture register dump buffer size (in MB)"
++ "(-1=auto [default], NB: max = 4, other restrictions apply)");
++
+ i915_param_named_unsafe(guc_firmware_path, charp, 0400,
+ "GuC firmware path to use instead of the default one");
+
+diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
+index 2733cb6cfe094..f684d1ab87078 100644
+--- a/drivers/gpu/drm/i915/i915_params.h
++++ b/drivers/gpu/drm/i915/i915_params.h
+@@ -61,6 +61,9 @@ struct drm_printer;
+ param(int, invert_brightness, 0, 0600) \
+ param(int, enable_guc, -1, 0400) \
+ param(int, guc_log_level, -1, 0400) \
++ param(int, guc_log_size_crash, -1, 0400) \
++ param(int, guc_log_size_debug, -1, 0400) \
++ param(int, guc_log_size_capture, -1, 0400) \
+ param(char *, guc_firmware_path, NULL, 0400) \
+ param(char *, huc_firmware_path, NULL, 0400) \
+ param(char *, dmc_firmware_path, NULL, 0400) \
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index 630a4e301ef6c..b11b5a2c06639 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -462,9 +462,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
+ if (--dpi->refcount != 0)
+ return;
+
+- if (dpi->pinctrl && dpi->pins_gpio)
+- pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+-
+ mtk_dpi_disable(dpi);
+ clk_disable_unprepare(dpi->pixel_clk);
+ clk_disable_unprepare(dpi->engine_clk);
+@@ -489,9 +486,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
+ goto err_pixel;
+ }
+
+- if (dpi->pinctrl && dpi->pins_dpi)
+- pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+-
+ return 0;
+
+ err_pixel:
+@@ -722,12 +716,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
+ struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+
+ mtk_dpi_power_off(dpi);
++
++ if (dpi->pinctrl && dpi->pins_gpio)
++ pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+ }
+
+ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
+ {
+ struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+
++ if (dpi->pinctrl && dpi->pins_dpi)
++ pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
++
+ mtk_dpi_power_on(dpi);
+ mtk_dpi_set_display_mode(dpi, &dpi->mode);
+ mtk_dpi_enable(dpi);
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index 3196189429bcf..7613b0fa2be6e 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -1203,9 +1203,10 @@ static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi)
+ return mtk_hdmi_update_plugged_status(hdmi);
+ }
+
+-static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+- const struct drm_display_info *info,
+- const struct drm_display_mode *mode)
++static enum drm_mode_status
++mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
++ const struct drm_display_info *info,
++ const struct drm_display_mode *mode)
+ {
+ struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+ struct drm_bridge *next_bridge;
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+index 5675bc2a92cf8..3f73b211fa8e3 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+@@ -116,9 +116,10 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
+ return i;
+ }
+
+-static int meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge,
+- const struct drm_display_info *display_info,
+- const struct drm_display_mode *mode)
++static enum drm_mode_status
++meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge,
++ const struct drm_display_info *display_info,
++ const struct drm_display_mode *mode)
+ {
+ if (meson_cvbs_get_mode(mode))
+ return MODE_OK;
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 4d501100b9e45..5804c35ae74b3 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -1869,7 +1869,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse)
+
+ if (val == UINT_MAX) {
+ DRM_DEV_ERROR(dev,
+- "missing support for speed-bin: %u. Some OPPs may not be supported by hardware",
++ "missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n",
+ fuse);
+ return UINT_MAX;
+ }
+@@ -1879,7 +1879,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse)
+
+ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev)
+ {
+- u32 supp_hw = UINT_MAX;
++ u32 supp_hw;
+ u32 speedbin;
+ int ret;
+
+@@ -1891,15 +1891,13 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev)
+ if (ret == -ENOENT) {
+ return 0;
+ } else if (ret) {
+- DRM_DEV_ERROR(dev,
+- "failed to read speed-bin (%d). Some OPPs may not be supported by hardware",
+- ret);
+- goto done;
++ dev_err_probe(dev, ret,
++ "failed to read speed-bin. Some OPPs may not be supported by hardware\n");
++ return ret;
+ }
+
+ supp_hw = fuse_to_supp_hw(dev, rev, speedbin);
+
+-done:
+ ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
+ if (ret)
+ return ret;
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 52a626117f70f..7f5dba96b2ffa 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -162,7 +162,7 @@ enum dpu_enc_rc_states {
+ * @vsync_event_work: worker to handle vsync event for autorefresh
+ * @topology: topology of the display
+ * @idle_timeout: idle timeout duration in milliseconds
+- * @dsc: msm_display_dsc_config pointer, for DSC-enabled encoders
++ * @dsc: drm_dsc_config pointer, for DSC-enabled encoders
+ */
+ struct dpu_encoder_virt {
+ struct drm_encoder base;
+@@ -208,7 +208,7 @@ struct dpu_encoder_virt {
+ bool wide_bus_en;
+
+ /* DSC configuration */
+- struct msm_display_dsc_config *dsc;
++ struct drm_dsc_config *dsc;
+ };
+
+ #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base)
+@@ -1791,12 +1791,12 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work)
+ }
+
+ static u32
+-dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc,
++dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc,
+ u32 enc_ip_width)
+ {
+ int ssm_delay, total_pixels, soft_slice_per_enc;
+
+- soft_slice_per_enc = enc_ip_width / dsc->drm->slice_width;
++ soft_slice_per_enc = enc_ip_width / dsc->slice_width;
+
+ /*
+ * minimum number of initial line pixels is a sum of:
+@@ -1808,16 +1808,16 @@ dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc,
+ * 5. 6 additional pixels as the output of the rate buffer is
+ * 48 bits wide
+ */
+- ssm_delay = ((dsc->drm->bits_per_component < 10) ? 84 : 92);
+- total_pixels = ssm_delay * 3 + dsc->drm->initial_xmit_delay + 47;
++ ssm_delay = ((dsc->bits_per_component < 10) ? 84 : 92);
++ total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47;
+ if (soft_slice_per_enc > 1)
+ total_pixels += (ssm_delay * 3);
+- return DIV_ROUND_UP(total_pixels, dsc->drm->slice_width);
++ return DIV_ROUND_UP(total_pixels, dsc->slice_width);
+ }
+
+ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
+ struct dpu_hw_pingpong *hw_pp,
+- struct msm_display_dsc_config *dsc,
++ struct drm_dsc_config *dsc,
+ u32 common_mode,
+ u32 initial_lines)
+ {
+@@ -1835,7 +1835,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
+ }
+
+ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+- struct msm_display_dsc_config *dsc)
++ struct drm_dsc_config *dsc)
+ {
+ /* coding only for 2LM, 2enc, 1 dsc config */
+ struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
+@@ -1858,14 +1858,15 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+ }
+ }
+
+- pic_width = dsc->drm->pic_width;
++ dsc_common_mode = 0;
++ pic_width = dsc->pic_width;
+
+ dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
+ if (enc_master->intf_mode == INTF_MODE_VIDEO)
+ dsc_common_mode |= DSC_MODE_VIDEO;
+
+- this_frame_slices = pic_width / dsc->drm->slice_width;
+- intf_ip_w = this_frame_slices * dsc->drm->slice_width;
++ this_frame_slices = pic_width / dsc->slice_width;
++ intf_ip_w = this_frame_slices * dsc->slice_width;
+
+ /*
+ * dsc merge case: when using 2 encoders for the same stream,
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+index d4d1ecd416e39..9e7236ef34e6d 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+@@ -36,7 +36,7 @@ struct msm_display_info {
+ uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
+ bool is_cmd_mode;
+ bool is_te_using_watchdog_timer;
+- struct msm_display_dsc_config *dsc;
++ struct drm_dsc_config *dsc;
+ };
+
+ /**
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+index 411689ae63825..3662df698dae5 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+@@ -37,12 +37,12 @@ static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
+ }
+
+ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
+- struct msm_display_dsc_config *dsc,
++ struct drm_dsc_config *dsc,
+ u32 mode,
+ u32 initial_lines)
+ {
+ struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+- u32 data, lsb, bpp;
++ u32 data;
+ u32 slice_last_group_size;
+ u32 det_thresh_flatness;
+ bool is_cmd_mode = !(mode & DSC_MODE_VIDEO);
+@@ -52,89 +52,82 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
+ if (is_cmd_mode)
+ initial_lines += 1;
+
+- slice_last_group_size = 3 - (dsc->drm->slice_width % 3);
++ slice_last_group_size = 3 - (dsc->slice_width % 3);
+ data = (initial_lines << 20);
+ data |= ((slice_last_group_size - 1) << 18);
+ /* bpp is 6.4 format, 4 LSBs bits are for fractional part */
+- data |= dsc->drm->bits_per_pixel << 12;
+- lsb = dsc->drm->bits_per_pixel % 4;
+- bpp = dsc->drm->bits_per_pixel / 4;
+- bpp *= 4;
+- bpp <<= 4;
+- bpp |= lsb;
+-
+- data |= bpp << 8;
+- data |= (dsc->drm->block_pred_enable << 7);
+- data |= (dsc->drm->line_buf_depth << 3);
+- data |= (dsc->drm->simple_422 << 2);
+- data |= (dsc->drm->convert_rgb << 1);
+- data |= dsc->drm->bits_per_component;
++ data |= (dsc->bits_per_pixel << 8);
++ data |= (dsc->block_pred_enable << 7);
++ data |= (dsc->line_buf_depth << 3);
++ data |= (dsc->simple_422 << 2);
++ data |= (dsc->convert_rgb << 1);
++ data |= dsc->bits_per_component;
+
+ DPU_REG_WRITE(c, DSC_ENC, data);
+
+- data = dsc->drm->pic_width << 16;
+- data |= dsc->drm->pic_height;
++ data = dsc->pic_width << 16;
++ data |= dsc->pic_height;
+ DPU_REG_WRITE(c, DSC_PICTURE, data);
+
+- data = dsc->drm->slice_width << 16;
+- data |= dsc->drm->slice_height;
++ data = dsc->slice_width << 16;
++ data |= dsc->slice_height;
+ DPU_REG_WRITE(c, DSC_SLICE, data);
+
+- data = dsc->drm->slice_chunk_size << 16;
++ data = dsc->slice_chunk_size << 16;
+ DPU_REG_WRITE(c, DSC_CHUNK_SIZE, data);
+
+- data = dsc->drm->initial_dec_delay << 16;
+- data |= dsc->drm->initial_xmit_delay;
++ data = dsc->initial_dec_delay << 16;
++ data |= dsc->initial_xmit_delay;
+ DPU_REG_WRITE(c, DSC_DELAY, data);
+
+- data = dsc->drm->initial_scale_value;
++ data = dsc->initial_scale_value;
+ DPU_REG_WRITE(c, DSC_SCALE_INITIAL, data);
+
+- data = dsc->drm->scale_decrement_interval;
++ data = dsc->scale_decrement_interval;
+ DPU_REG_WRITE(c, DSC_SCALE_DEC_INTERVAL, data);
+
+- data = dsc->drm->scale_increment_interval;
++ data = dsc->scale_increment_interval;
+ DPU_REG_WRITE(c, DSC_SCALE_INC_INTERVAL, data);
+
+- data = dsc->drm->first_line_bpg_offset;
++ data = dsc->first_line_bpg_offset;
+ DPU_REG_WRITE(c, DSC_FIRST_LINE_BPG_OFFSET, data);
+
+- data = dsc->drm->nfl_bpg_offset << 16;
+- data |= dsc->drm->slice_bpg_offset;
++ data = dsc->nfl_bpg_offset << 16;
++ data |= dsc->slice_bpg_offset;
+ DPU_REG_WRITE(c, DSC_BPG_OFFSET, data);
+
+- data = dsc->drm->initial_offset << 16;
+- data |= dsc->drm->final_offset;
++ data = dsc->initial_offset << 16;
++ data |= dsc->final_offset;
+ DPU_REG_WRITE(c, DSC_DSC_OFFSET, data);
+
+- det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8);
++ det_thresh_flatness = 7 + 2 * (dsc->bits_per_component - 8);
+ data = det_thresh_flatness << 10;
+- data |= dsc->drm->flatness_max_qp << 5;
+- data |= dsc->drm->flatness_min_qp;
++ data |= dsc->flatness_max_qp << 5;
++ data |= dsc->flatness_min_qp;
+ DPU_REG_WRITE(c, DSC_FLATNESS, data);
+
+- data = dsc->drm->rc_model_size;
++ data = dsc->rc_model_size;
+ DPU_REG_WRITE(c, DSC_RC_MODEL_SIZE, data);
+
+- data = dsc->drm->rc_tgt_offset_low << 18;
+- data |= dsc->drm->rc_tgt_offset_high << 14;
+- data |= dsc->drm->rc_quant_incr_limit1 << 9;
+- data |= dsc->drm->rc_quant_incr_limit0 << 4;
+- data |= dsc->drm->rc_edge_factor;
++ data = dsc->rc_tgt_offset_low << 18;
++ data |= dsc->rc_tgt_offset_high << 14;
++ data |= dsc->rc_quant_incr_limit1 << 9;
++ data |= dsc->rc_quant_incr_limit0 << 4;
++ data |= dsc->rc_edge_factor;
+ DPU_REG_WRITE(c, DSC_RC, data);
+ }
+
+ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
+- struct msm_display_dsc_config *dsc)
++ struct drm_dsc_config *dsc)
+ {
+- struct drm_dsc_rc_range_parameters *rc = dsc->drm->rc_range_params;
++ struct drm_dsc_rc_range_parameters *rc = dsc->rc_range_params;
+ struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+ u32 off;
+ int i;
+
+ off = DSC_RC_BUF_THRESH;
+ for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) {
+- DPU_REG_WRITE(c, off, dsc->drm->rc_buf_thresh[i]);
++ DPU_REG_WRITE(c, off, dsc->rc_buf_thresh[i]);
+ off += 4;
+ }
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+index 45e4118f1fa27..c0b77fe1a6968 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+@@ -31,7 +31,7 @@ struct dpu_hw_dsc_ops {
+ * @initial_lines: amount of initial lines to be used
+ */
+ void (*dsc_config)(struct dpu_hw_dsc *hw_dsc,
+- struct msm_display_dsc_config *dsc,
++ struct drm_dsc_config *dsc,
+ u32 mode,
+ u32 initial_lines);
+
+@@ -41,7 +41,7 @@ struct dpu_hw_dsc_ops {
+ * @dsc: panel dsc parameters
+ */
+ void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
+- struct msm_display_dsc_config *dsc);
++ struct drm_dsc_config *dsc);
+ };
+
+ struct dpu_hw_dsc {
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+index b0d21838a1343..29ae5c9613f36 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+@@ -203,7 +203,7 @@ static int mdp5_set_split_display(struct msm_kms *kms,
+ slave_encoder);
+ }
+
+-static void mdp5_destroy(struct platform_device *pdev);
++static void mdp5_destroy(struct mdp5_kms *mdp5_kms);
+
+ static void mdp5_kms_destroy(struct msm_kms *kms)
+ {
+@@ -223,7 +223,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
+ }
+
+ mdp_kms_destroy(&mdp5_kms->base);
+- mdp5_destroy(mdp5_kms->pdev);
++ mdp5_destroy(mdp5_kms);
+ }
+
+ #ifdef CONFIG_DEBUG_FS
+@@ -559,6 +559,8 @@ static int mdp5_kms_init(struct drm_device *dev)
+ int irq, i, ret;
+
+ ret = mdp5_init(to_platform_device(dev->dev), dev);
++ if (ret)
++ return ret;
+
+ /* priv->kms would have been populated by the MDP5 driver */
+ kms = priv->kms;
+@@ -632,9 +634,8 @@ fail:
+ return ret;
+ }
+
+-static void mdp5_destroy(struct platform_device *pdev)
++static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
+ {
+- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+ int i;
+
+ if (mdp5_kms->ctlm)
+@@ -648,7 +649,7 @@ static void mdp5_destroy(struct platform_device *pdev)
+ kfree(mdp5_kms->intfs[i]);
+
+ if (mdp5_kms->rpm_enabled)
+- pm_runtime_disable(&pdev->dev);
++ pm_runtime_disable(&mdp5_kms->pdev->dev);
+
+ drm_atomic_private_obj_fini(&mdp5_kms->glob_state);
+ drm_modeset_lock_fini(&mdp5_kms->glob_state_lock);
+@@ -797,8 +798,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ goto fail;
+ }
+
+- platform_set_drvdata(pdev, mdp5_kms);
+-
+ spin_lock_init(&mdp5_kms->resource_lock);
+
+ mdp5_kms->dev = dev;
+@@ -839,6 +838,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ */
+ clk_set_rate(mdp5_kms->core_clk, 200000000);
+
++ /* set uninit-ed kms */
++ priv->kms = &mdp5_kms->base.base;
++
+ pm_runtime_enable(&pdev->dev);
+ mdp5_kms->rpm_enabled = true;
+
+@@ -890,13 +892,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ if (ret)
+ goto fail;
+
+- /* set uninit-ed kms */
+- priv->kms = &mdp5_kms->base.base;
+-
+ return 0;
+ fail:
+ if (mdp5_kms)
+- mdp5_destroy(pdev);
++ mdp5_destroy(mdp5_kms);
+ return ret;
+ }
+
+@@ -953,7 +952,8 @@ static int mdp5_dev_remove(struct platform_device *pdev)
+ static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+ {
+ struct platform_device *pdev = to_platform_device(dev);
+- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
++ struct msm_drm_private *priv = platform_get_drvdata(pdev);
++ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+
+ DBG("");
+
+@@ -963,7 +963,8 @@ static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+ static __maybe_unused int mdp5_runtime_resume(struct device *dev)
+ {
+ struct platform_device *pdev = to_platform_device(dev);
+- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
++ struct msm_drm_private *priv = platform_get_drvdata(pdev);
++ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+
+ DBG("");
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index a49f6dbbe8883..c9d9b384ddd03 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -857,7 +857,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display,
+
+ dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+- dp->panel->dp_mode.drm_mode = mode->drm_mode;
++ drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);
+ dp->panel->dp_mode.bpp = mode->bpp;
+ dp->panel->dp_mode.capabilities = mode->capabilities;
+ dp_panel_init_panel_info(dp->panel);
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
+index 3db85b5c0febd..31e452ede71f0 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.c
++++ b/drivers/gpu/drm/msm/dsi/dsi.c
+@@ -21,7 +21,7 @@ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
+ return !(host_flags & MIPI_DSI_MODE_VIDEO);
+ }
+
+-struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
++struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+ {
+ return msm_dsi_host_get_dsc_config(msm_dsi->host);
+ }
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
+index 580a1e6358bfc..df46cdda1b433 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.h
++++ b/drivers/gpu/drm/msm/dsi/dsi.h
+@@ -154,7 +154,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+ void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host);
+ void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
+-struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
++struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
+
+ /* dsi phy */
+ struct msm_dsi_phy;
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index a34078497af12..cf7d5b69aac58 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -21,6 +21,7 @@
+
+ #include <video/mipi_display.h>
+
++#include <drm/display/drm_dsc_helper.h>
+ #include <drm/drm_of.h>
+
+ #include "dsi.h"
+@@ -33,7 +34,7 @@
+
+ #define DSI_RESET_TOGGLE_DELAY_MS 20
+
+-static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc);
++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
+
+ static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
+ {
+@@ -161,7 +162,7 @@ struct msm_dsi_host {
+ struct regmap *sfpb;
+
+ struct drm_display_mode *mode;
+- struct msm_display_dsc_config *dsc;
++ struct drm_dsc_config *dsc;
+
+ /* connected device info */
+ struct device_node *device_node;
+@@ -916,35 +917,28 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
+
+ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay)
+ {
+- struct msm_display_dsc_config *dsc = msm_host->dsc;
+- u32 reg, intf_width, reg_ctrl, reg_ctrl2;
++ struct drm_dsc_config *dsc = msm_host->dsc;
++ u32 reg, reg_ctrl, reg_ctrl2;
+ u32 slice_per_intf, total_bytes_per_intf;
+ u32 pkt_per_line;
+- u32 bytes_in_slice;
+ u32 eol_byte_num;
+
+ /* first calculate dsc parameters and then program
+ * compress mode registers
+ */
+- intf_width = hdisplay;
+- slice_per_intf = DIV_ROUND_UP(intf_width, dsc->drm->slice_width);
++ slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
+
+ /* If slice_per_pkt is greater than slice_per_intf
+ * then default to 1. This can happen during partial
+ * update.
+ */
+- if (slice_per_intf > dsc->drm->slice_count)
+- dsc->drm->slice_count = 1;
++ if (slice_per_intf > dsc->slice_count)
++ dsc->slice_count = 1;
+
+- slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->drm->slice_width);
+- bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * dsc->drm->bits_per_pixel, 8);
+-
+- dsc->drm->slice_chunk_size = bytes_in_slice;
+-
+- total_bytes_per_intf = bytes_in_slice * slice_per_intf;
++ total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+
+ eol_byte_num = total_bytes_per_intf % 3;
+- pkt_per_line = slice_per_intf / dsc->drm->slice_count;
++ pkt_per_line = slice_per_intf / dsc->slice_count;
+
+ if (is_cmd_mode) /* packet data type */
+ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
+@@ -967,7 +961,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
+ reg_ctrl |= reg;
+
+ reg_ctrl2 &= ~DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH__MASK;
+- reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(bytes_in_slice);
++ reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(dsc->slice_chunk_size);
+
+ dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
+ dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
+@@ -990,6 +984,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ u32 va_end = va_start + mode->vdisplay;
+ u32 hdisplay = mode->hdisplay;
+ u32 wc;
++ int ret;
+
+ DBG("");
+
+@@ -1009,7 +1004,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ }
+
+ if (msm_host->dsc) {
+- struct msm_display_dsc_config *dsc = msm_host->dsc;
++ struct drm_dsc_config *dsc = msm_host->dsc;
+
+ /* update dsc params with timing params */
+ if (!dsc || !mode->hdisplay || !mode->vdisplay) {
+@@ -1018,14 +1013,16 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ return;
+ }
+
+- dsc->drm->pic_width = mode->hdisplay;
+- dsc->drm->pic_height = mode->vdisplay;
+- DBG("Mode %dx%d\n", dsc->drm->pic_width, dsc->drm->pic_height);
++ dsc->pic_width = mode->hdisplay;
++ dsc->pic_height = mode->vdisplay;
++ DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
+
+ /* we do the calculations for dsc parameters here so that
+ * panel can use these parameters
+ */
+- dsi_populate_dsc_params(dsc);
++ ret = dsi_populate_dsc_params(msm_host, dsc);
++ if (ret)
++ return;
+
+ /* Divide the display by 3 but keep back/font porch and
+ * pulse width same
+@@ -1841,113 +1838,65 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
+ 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
+ };
+
+-static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc)
+-{
+- int mux_words_size;
+- int groups_per_line, groups_total;
+- int min_rate_buffer_size;
+- int hrd_delay;
+- int pre_num_extra_mux_bits, num_extra_mux_bits;
+- int slice_bits;
+- int target_bpp_x16;
+- int data;
+- int final_value, final_scale;
++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
++{
+ int i;
++ u16 bpp = dsc->bits_per_pixel >> 4;
++
++ if (dsc->bits_per_pixel & 0xf) {
++ DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
++ return -EINVAL;
++ }
+
+- dsc->drm->rc_model_size = 8192;
+- dsc->drm->first_line_bpg_offset = 12;
+- dsc->drm->rc_edge_factor = 6;
+- dsc->drm->rc_tgt_offset_high = 3;
+- dsc->drm->rc_tgt_offset_low = 3;
+- dsc->drm->simple_422 = 0;
+- dsc->drm->convert_rgb = 1;
+- dsc->drm->vbr_enable = 0;
++ if (dsc->bits_per_component != 8) {
++ DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support bits_per_component != 8 yet\n");
++ return -EOPNOTSUPP;
++ }
++
++ dsc->rc_model_size = 8192;
++ dsc->first_line_bpg_offset = 12;
++ dsc->rc_edge_factor = 6;
++ dsc->rc_tgt_offset_high = 3;
++ dsc->rc_tgt_offset_low = 3;
++ dsc->simple_422 = 0;
++ dsc->convert_rgb = 1;
++ dsc->vbr_enable = 0;
+
+ /* handle only bpp = bpc = 8 */
+ for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++)
+- dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i];
++ dsc->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i];
+
+ for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
+- dsc->drm->rc_range_params[i].range_min_qp = min_qp[i];
+- dsc->drm->rc_range_params[i].range_max_qp = max_qp[i];
+- dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i];
++ dsc->rc_range_params[i].range_min_qp = min_qp[i];
++ dsc->rc_range_params[i].range_max_qp = max_qp[i];
++ /*
++ * Range BPG Offset contains two's-complement signed values that fill
++ * 8 bits, yet the registers and DCS PPS field are only 6 bits wide.
++ */
++ dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i] & DSC_RANGE_BPG_OFFSET_MASK;
+ }
+
+- dsc->drm->initial_offset = 6144; /* Not bpp 12 */
+- if (dsc->drm->bits_per_pixel != 8)
+- dsc->drm->initial_offset = 2048; /* bpp = 12 */
++ dsc->initial_offset = 6144; /* Not bpp 12 */
++ if (bpp != 8)
++ dsc->initial_offset = 2048; /* bpp = 12 */
+
+- mux_words_size = 48; /* bpc == 8/10 */
+- if (dsc->drm->bits_per_component == 12)
+- mux_words_size = 64;
++ if (dsc->bits_per_component <= 10)
++ dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
++ else
++ dsc->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
+
+- dsc->drm->initial_xmit_delay = 512;
+- dsc->drm->initial_scale_value = 32;
+- dsc->drm->first_line_bpg_offset = 12;
+- dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1;
++ dsc->initial_xmit_delay = 512;
++ dsc->initial_scale_value = 32;
++ dsc->first_line_bpg_offset = 12;
++ dsc->line_buf_depth = dsc->bits_per_component + 1;
+
+ /* bpc 8 */
+- dsc->drm->flatness_min_qp = 3;
+- dsc->drm->flatness_max_qp = 12;
+- dsc->drm->rc_quant_incr_limit0 = 11;
+- dsc->drm->rc_quant_incr_limit1 = 11;
+- dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
+-
+- /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of
+- * params are calculated
+- */
+- groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3);
+- dsc->drm->slice_chunk_size = dsc->drm->slice_width * dsc->drm->bits_per_pixel / 8;
+- if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8)
+- dsc->drm->slice_chunk_size++;
+-
+- /* rbs-min */
+- min_rate_buffer_size = dsc->drm->rc_model_size - dsc->drm->initial_offset +
+- dsc->drm->initial_xmit_delay * dsc->drm->bits_per_pixel +
+- groups_per_line * dsc->drm->first_line_bpg_offset;
+-
+- hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->drm->bits_per_pixel);
+-
+- dsc->drm->initial_dec_delay = hrd_delay - dsc->drm->initial_xmit_delay;
++ dsc->flatness_min_qp = 3;
++ dsc->flatness_max_qp = 12;
++ dsc->rc_quant_incr_limit0 = 11;
++ dsc->rc_quant_incr_limit1 = 11;
+
+- dsc->drm->initial_scale_value = 8 * dsc->drm->rc_model_size /
+- (dsc->drm->rc_model_size - dsc->drm->initial_offset);
+-
+- slice_bits = 8 * dsc->drm->slice_chunk_size * dsc->drm->slice_height;
+-
+- groups_total = groups_per_line * dsc->drm->slice_height;
+-
+- data = dsc->drm->first_line_bpg_offset * 2048;
+-
+- dsc->drm->nfl_bpg_offset = DIV_ROUND_UP(data, (dsc->drm->slice_height - 1));
+-
+- pre_num_extra_mux_bits = 3 * (mux_words_size + (4 * dsc->drm->bits_per_component + 4) - 2);
+-
+- num_extra_mux_bits = pre_num_extra_mux_bits - (mux_words_size -
+- ((slice_bits - pre_num_extra_mux_bits) % mux_words_size));
+-
+- data = 2048 * (dsc->drm->rc_model_size - dsc->drm->initial_offset + num_extra_mux_bits);
+- dsc->drm->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);
+-
+- /* bpp * 16 + 0.5 */
+- data = dsc->drm->bits_per_pixel * 16;
+- data *= 2;
+- data++;
+- data /= 2;
+- target_bpp_x16 = data;
+-
+- data = (dsc->drm->initial_xmit_delay * target_bpp_x16) / 16;
+- final_value = dsc->drm->rc_model_size - data + num_extra_mux_bits;
+- dsc->drm->final_offset = final_value;
+-
+- final_scale = 8 * dsc->drm->rc_model_size / (dsc->drm->rc_model_size - final_value);
+-
+- data = (final_scale - 9) * (dsc->drm->nfl_bpg_offset + dsc->drm->slice_bpg_offset);
+- dsc->drm->scale_increment_interval = (2048 * dsc->drm->final_offset) / data;
+-
+- dsc->drm->scale_decrement_interval = groups_per_line / (dsc->drm->initial_scale_value - 8);
+-
+- return 0;
++ return drm_dsc_compute_rc_parameters(dsc);
+ }
+
+ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host)
+@@ -2165,17 +2114,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
+ msm_host->dev = dev;
+ panel = msm_dsi_host_get_panel(&msm_host->base);
+
+- if (!IS_ERR(panel) && panel->dsc) {
+- struct msm_display_dsc_config *dsc = msm_host->dsc;
+-
+- if (!dsc) {
+- dsc = devm_kzalloc(&msm_host->pdev->dev, sizeof(*dsc), GFP_KERNEL);
+- if (!dsc)
+- return -ENOMEM;
+- dsc->drm = panel->dsc;
+- msm_host->dsc = dsc;
+- }
+- }
++ if (!IS_ERR(panel) && panel->dsc)
++ msm_host->dsc = panel->dsc;
+
+ ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
+ if (ret) {
+@@ -2659,22 +2599,22 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
+ const struct drm_display_mode *mode)
+ {
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+- struct msm_display_dsc_config *dsc = msm_host->dsc;
++ struct drm_dsc_config *dsc = msm_host->dsc;
+ int pic_width = mode->hdisplay;
+ int pic_height = mode->vdisplay;
+
+ if (!msm_host->dsc)
+ return MODE_OK;
+
+- if (pic_width % dsc->drm->slice_width) {
++ if (pic_width % dsc->slice_width) {
+ pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
+- pic_width, dsc->drm->slice_width);
++ pic_width, dsc->slice_width);
+ return MODE_H_ILLEGAL;
+ }
+
+- if (pic_height % dsc->drm->slice_height) {
++ if (pic_height % dsc->slice_height) {
+ pr_err("DSI: pic_height %d has to be multiple of slice %d\n",
+- pic_height, dsc->drm->slice_height);
++ pic_height, dsc->slice_height);
+ return MODE_V_ILLEGAL;
+ }
+
+@@ -2771,7 +2711,7 @@ void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host)
+ DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER);
+ }
+
+-struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host)
++struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host)
+ {
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index f28fb21e38911..8cd5d50639a53 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -252,7 +252,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
+ if (hdmi->hpd_gpiod)
+ gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+
+- pm_runtime_enable(&pdev->dev);
++ devm_pm_runtime_enable(&pdev->dev);
+
+ hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
+
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index 80da0d3cfdc13..03e5b6863319d 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -96,11 +96,6 @@ struct msm_drm_thread {
+ struct kthread_worker *worker;
+ };
+
+-/* DSC config */
+-struct msm_display_dsc_config {
+- struct drm_dsc_config *drm;
+-};
+-
+ struct msm_drm_private {
+
+ struct drm_device *dev;
+@@ -290,7 +285,7 @@ void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi
+ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
+ bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
+ bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi);
+-struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
++struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
+ #else
+ static inline void __init msm_dsi_register(void)
+ {
+@@ -320,7 +315,7 @@ static inline bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
+ return false;
+ }
+
+-static inline struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
++static inline struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+ {
+ return NULL;
+ }
+diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c
+index 1bec1279c8b56..d419c61c3407c 100644
+--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c
++++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c
+@@ -5,6 +5,7 @@
+ * This code is based on drivers/gpu/drm/mxsfb/mxsfb*
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/iopoll.h>
+@@ -53,16 +54,22 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
+ writel(DISP_PARA_LINE_PATTERN_UYVY_H,
+ lcdif->base + LCDC_V8_DISP_PARA);
+
+- /* CSC: BT.601 Full Range RGB to YCbCr coefficients. */
+- writel(CSC0_COEF0_A2(0x096) | CSC0_COEF0_A1(0x04c),
++ /*
++ * CSC: BT.601 Limited Range RGB to YCbCr coefficients.
++ *
++ * |Y | | 0.2568 0.5041 0.0979| |R| |16 |
++ * |Cb| = |-0.1482 -0.2910 0.4392| * |G| + |128|
++ * |Cr| | 0.4392 0.4392 -0.3678| |B| |128|
++ */
++ writel(CSC0_COEF0_A2(0x081) | CSC0_COEF0_A1(0x041),
+ lcdif->base + LCDC_V8_CSC0_COEF0);
+- writel(CSC0_COEF1_B1(0x7d5) | CSC0_COEF1_A3(0x01d),
++ writel(CSC0_COEF1_B1(0x7db) | CSC0_COEF1_A3(0x019),
+ lcdif->base + LCDC_V8_CSC0_COEF1);
+- writel(CSC0_COEF2_B3(0x080) | CSC0_COEF2_B2(0x7ac),
++ writel(CSC0_COEF2_B3(0x070) | CSC0_COEF2_B2(0x7b6),
+ lcdif->base + LCDC_V8_CSC0_COEF2);
+- writel(CSC0_COEF3_C2(0x795) | CSC0_COEF3_C1(0x080),
++ writel(CSC0_COEF3_C2(0x7a2) | CSC0_COEF3_C1(0x070),
+ lcdif->base + LCDC_V8_CSC0_COEF3);
+- writel(CSC0_COEF4_D1(0x000) | CSC0_COEF4_C3(0x7ec),
++ writel(CSC0_COEF4_D1(0x010) | CSC0_COEF4_C3(0x7ee),
+ lcdif->base + LCDC_V8_CSC0_COEF4);
+ writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080),
+ lcdif->base + LCDC_V8_CSC0_COEF5);
+@@ -143,14 +150,36 @@ static void lcdif_set_mode(struct lcdif_drm_private *lcdif, u32 bus_flags)
+ CTRLDESCL0_1_WIDTH(m->crtc_hdisplay),
+ lcdif->base + LCDC_V8_CTRLDESCL0_1);
+
+- writel(CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]),
+- lcdif->base + LCDC_V8_CTRLDESCL0_3);
++ /*
++ * Undocumented P_SIZE and T_SIZE register but those written in the
++ * downstream kernel those registers control the AXI burst size. As of
++ * now there are two known values:
++ * 1 - 128Byte
++ * 2 - 256Byte
++ * Downstream set it to 256B burst size to improve the memory
++ * efficiency so set it here too.
++ */
++ ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) |
++ CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]);
++ writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3);
+ }
+
+ static void lcdif_enable_controller(struct lcdif_drm_private *lcdif)
+ {
+ u32 reg;
+
++ /* Set FIFO Panic watermarks, low 1/3, high 2/3 . */
++ writel(FIELD_PREP(PANIC0_THRES_LOW_MASK, 1 * PANIC0_THRES_MAX / 3) |
++ FIELD_PREP(PANIC0_THRES_HIGH_MASK, 2 * PANIC0_THRES_MAX / 3),
++ lcdif->base + LCDC_V8_PANIC0_THRES);
++
++ /*
++ * Enable FIFO Panic, this does not generate interrupt, but
++ * boosts NoC priority based on FIFO Panic watermarks.
++ */
++ writel(INT_ENABLE_D1_PLANE_PANIC_EN,
++ lcdif->base + LCDC_V8_INT_ENABLE_D1);
++
+ reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
+ reg |= DISP_PARA_DISP_ON;
+ writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
+@@ -178,6 +207,9 @@ static void lcdif_disable_controller(struct lcdif_drm_private *lcdif)
+ reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
+ reg &= ~DISP_PARA_DISP_ON;
+ writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
++
++ /* Disable FIFO Panic NoC priority booster. */
++ writel(0, lcdif->base + LCDC_V8_INT_ENABLE_D1);
+ }
+
+ static void lcdif_reset_block(struct lcdif_drm_private *lcdif)
+diff --git a/drivers/gpu/drm/mxsfb/lcdif_regs.h b/drivers/gpu/drm/mxsfb/lcdif_regs.h
+index c70220651e3a5..37f0d9a06b104 100644
+--- a/drivers/gpu/drm/mxsfb/lcdif_regs.h
++++ b/drivers/gpu/drm/mxsfb/lcdif_regs.h
+@@ -190,6 +190,10 @@
+ #define CTRLDESCL0_1_WIDTH(n) ((n) & 0xffff)
+ #define CTRLDESCL0_1_WIDTH_MASK GENMASK(15, 0)
+
++#define CTRLDESCL0_3_P_SIZE(n) (((n) << 20) & CTRLDESCL0_3_P_SIZE_MASK)
++#define CTRLDESCL0_3_P_SIZE_MASK GENMASK(22, 20)
++#define CTRLDESCL0_3_T_SIZE(n) (((n) << 16) & CTRLDESCL0_3_T_SIZE_MASK)
++#define CTRLDESCL0_3_T_SIZE_MASK GENMASK(17, 16)
+ #define CTRLDESCL0_3_PITCH(n) ((n) & 0xffff)
+ #define CTRLDESCL0_3_PITCH_MASK GENMASK(15, 0)
+
+@@ -248,6 +252,7 @@
+
+ #define PANIC0_THRES_LOW_MASK GENMASK(24, 16)
+ #define PANIC0_THRES_HIGH_MASK GENMASK(8, 0)
++#define PANIC0_THRES_MAX 511
+
+ #define LCDIF_MIN_XRES 120
+ #define LCDIF_MIN_YRES 120
+diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+index 320a2a8fd4592..098955526b687 100644
+--- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c
++++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+@@ -384,7 +384,15 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
+ st7701->dsi = dsi;
+ st7701->desc = desc;
+
+- return mipi_dsi_attach(dsi);
++ ret = mipi_dsi_attach(dsi);
++ if (ret)
++ goto err_attach;
++
++ return 0;
++
++err_attach:
++ drm_panel_remove(&st7701->panel);
++ return ret;
+ }
+
+ static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
+diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
+index 33121655d50bb..63bdc9f6fc243 100644
+--- a/drivers/gpu/drm/radeon/radeon_bios.c
++++ b/drivers/gpu/drm/radeon/radeon_bios.c
+@@ -227,6 +227,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+
+ if (!found)
+ return false;
++ pci_dev_put(pdev);
+
+ rdev->bios = kmalloc(size, GFP_KERNEL);
+ if (!rdev->bios) {
+@@ -612,13 +613,14 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ acpi_size tbl_size;
+ UEFI_ACPI_VFCT *vfct;
+ unsigned offset;
++ bool r = false;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ tbl_size = hdr->length;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+- return false;
++ goto out;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+@@ -631,13 +633,13 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ offset += sizeof(VFCT_IMAGE_HEADER);
+ if (offset > tbl_size) {
+ DRM_ERROR("ACPI VFCT image header truncated\n");
+- return false;
++ goto out;
+ }
+
+ offset += vhdr->ImageLength;
+ if (offset > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+- return false;
++ goto out;
+ }
+
+ if (vhdr->ImageLength &&
+@@ -649,15 +651,18 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ rdev->bios = kmemdup(&vbios->VbiosContent,
+ vhdr->ImageLength,
+ GFP_KERNEL);
++ if (rdev->bios)
++ r = true;
+
+- if (!rdev->bios)
+- return false;
+- return true;
++ goto out;
+ }
+ }
+
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+- return false;
++
++out:
++ acpi_put_table(hdr);
++ return r;
+ }
+ #else
+ static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
+index f6e6a6d5d987b..b3c29ca7726e0 100644
+--- a/drivers/gpu/drm/rcar-du/Kconfig
++++ b/drivers/gpu/drm/rcar-du/Kconfig
+@@ -41,8 +41,6 @@ config DRM_RCAR_LVDS
+ depends on DRM_RCAR_USE_LVDS
+ select DRM_KMS_HELPER
+ select DRM_PANEL
+- select OF_FLATTREE
+- select OF_OVERLAY
+
+ config DRM_RCAR_MIPI_DSI
+ tristate "R-Car DU MIPI DSI Encoder Support"
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+index 518ee13b1d6f4..8526dda919317 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+@@ -571,7 +571,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder *encoder,
+ video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+ video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+- memcpy(&dp->mode, adjusted, sizeof(*mode));
++ drm_mode_copy(&dp->mode, adjusted);
+ }
+
+ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index 1aa3700551f4d..1e1a8bc6c8567 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -1201,7 +1201,7 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy)
+ return i;
+ }
+
+- ret = pm_runtime_get_sync(dsi->dev);
++ ret = pm_runtime_resume_and_get(dsi->dev);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dsi->dev, "failed to enable device: %d\n", ret);
+ return ret;
+diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
+index 87b2243ea23e3..f51774866f412 100644
+--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
+@@ -499,7 +499,7 @@ static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+ inno_hdmi_setup(hdmi, adj_mode);
+
+ /* Store the display mode for plugin/DPMS poweron events */
+- memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++ drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+
+ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
+diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+index cf2cf51091a3e..90145ad969841 100644
+--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+@@ -395,7 +395,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+ struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
+
+ /* Store the display mode for plugin/DPMS poweron events. */
+- memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++ drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+
+ static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index ad3958b6f8bf3..9a039a31fe48e 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -605,7 +605,7 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
+ struct vop *vop = to_vop(crtc);
+ int ret, i;
+
+- ret = pm_runtime_get_sync(vop->dev);
++ ret = pm_runtime_resume_and_get(vop->dev);
+ if (ret < 0) {
+ DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
+ return ret;
+@@ -1953,7 +1953,7 @@ static int vop_initial(struct vop *vop)
+ return PTR_ERR(vop->dclk);
+ }
+
+- ret = pm_runtime_get_sync(vop->dev);
++ ret = pm_runtime_resume_and_get(vop->dev);
+ if (ret < 0) {
+ DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
+ return ret;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+index 1fc04019dfd83..6dc14ea7f6fc8 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+@@ -823,7 +823,7 @@ static void vop2_enable(struct vop2 *vop2)
+ {
+ int ret;
+
+- ret = pm_runtime_get_sync(vop2->dev);
++ ret = pm_runtime_resume_and_get(vop2->dev);
+ if (ret < 0) {
+ drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
+ return;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index 5a284332ec49e..68f6ebb33460b 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -152,7 +152,7 @@ static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
+ DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
+ return ret;
+ }
+- ret = pm_runtime_get_sync(lvds->dev);
++ ret = pm_runtime_resume_and_get(lvds->dev);
+ if (ret < 0) {
+ DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+ clk_disable(lvds->pclk);
+@@ -336,16 +336,20 @@ static int px30_lvds_poweron(struct rockchip_lvds *lvds)
+ {
+ int ret;
+
+- ret = pm_runtime_get_sync(lvds->dev);
++ ret = pm_runtime_resume_and_get(lvds->dev);
+ if (ret < 0) {
+ DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable LVDS mode */
+- return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
++ ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
+ PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
+ PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1));
++ if (ret)
++ pm_runtime_put(lvds->dev);
++
++ return ret;
+ }
+
+ static void px30_lvds_poweroff(struct rockchip_lvds *lvds)
+diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
+index b6ee8a82e656c..577c477b5f467 100644
+--- a/drivers/gpu/drm/sti/sti_dvo.c
++++ b/drivers/gpu/drm/sti/sti_dvo.c
+@@ -288,7 +288,7 @@ static void sti_dvo_set_mode(struct drm_bridge *bridge,
+
+ DRM_DEBUG_DRIVER("\n");
+
+- memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
++ drm_mode_copy(&dvo->mode, mode);
+
+ /* According to the path used (main or aux), the dvo clocks should
+ * have a different parent clock. */
+@@ -346,8 +346,9 @@ static int sti_dvo_connector_get_modes(struct drm_connector *connector)
+
+ #define CLK_TOLERANCE_HZ 50
+
+-static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_dvo_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
+index 03cc401ed5934..15097ac679314 100644
+--- a/drivers/gpu/drm/sti/sti_hda.c
++++ b/drivers/gpu/drm/sti/sti_hda.c
+@@ -524,7 +524,7 @@ static void sti_hda_set_mode(struct drm_bridge *bridge,
+
+ DRM_DEBUG_DRIVER("\n");
+
+- memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
++ drm_mode_copy(&hda->mode, mode);
+
+ if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
+ DRM_ERROR("Undefined mode\n");
+@@ -601,8 +601,9 @@ static int sti_hda_connector_get_modes(struct drm_connector *connector)
+
+ #define CLK_TOLERANCE_HZ 50
+
+-static int sti_hda_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hda_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
+index cb82622877d20..8539fe1fedc4c 100644
+--- a/drivers/gpu/drm/sti/sti_hdmi.c
++++ b/drivers/gpu/drm/sti/sti_hdmi.c
+@@ -941,7 +941,7 @@ static void sti_hdmi_set_mode(struct drm_bridge *bridge,
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Copy the drm display mode in the connector local structure */
+- memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
++ drm_mode_copy(&hdmi->mode, mode);
+
+ /* Update clock framerate according to the selected mode */
+ ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
+@@ -1004,8 +1004,9 @@ fail:
+
+ #define CLK_TOLERANCE_HZ 50
+
+-static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hdmi_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
+ {
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
+index 747abafb6a5cf..b8035b3be3d32 100644
+--- a/drivers/gpu/drm/tegra/dc.c
++++ b/drivers/gpu/drm/tegra/dc.c
+@@ -3206,8 +3206,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
+ usleep_range(2000, 4000);
+
+ err = reset_control_assert(dc->rst);
+- if (err < 0)
++ if (err < 0) {
++ clk_disable_unprepare(dc->clk);
+ return err;
++ }
+
+ usleep_range(2000, 4000);
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+index 8275bba636119..ab125f79408f2 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+@@ -237,6 +237,10 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
+ in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
+ &cl_data->sensor_dma_addr[i],
+ GFP_KERNEL);
++ if (!in_data->sensor_virt_addr[i]) {
++ rc = -ENOMEM;
++ goto cleanup;
++ }
+ cl_data->sensor_sts[i] = SENSOR_DISABLED;
+ cl_data->sensor_requested_cnt[i] = 0;
+ cl_data->cur_hid_dev = i;
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 6970797cdc56d..c671ce94671ca 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -314,6 +314,7 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = {
+
+ static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
+ { KEY_FN, KEY_LEFTCTRL },
++ { KEY_LEFTCTRL, KEY_FN },
+ { }
+ };
+
+@@ -375,24 +376,40 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ struct apple_sc *asc = hid_get_drvdata(hid);
+ const struct apple_key_translation *trans, *table;
+ bool do_translate;
+- u16 code = 0;
++ u16 code = usage->code;
+ unsigned int real_fnmode;
+
+- u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
+-
+- if (usage->code == fn_keycode) {
+- asc->fn_on = !!value;
+- input_event_with_scancode(input, usage->type, KEY_FN,
+- usage->hid, value);
+- return 1;
+- }
+-
+ if (fnmode == 3) {
+ real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1;
+ } else {
+ real_fnmode = fnmode;
+ }
+
++ if (swap_fn_leftctrl) {
++ trans = apple_find_translation(swapped_fn_leftctrl_keys, code);
++
++ if (trans)
++ code = trans->to;
++ }
++
++ if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
++ hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
++ trans = apple_find_translation(apple_iso_keyboard, code);
++
++ if (trans)
++ code = trans->to;
++ }
++
++ if (swap_opt_cmd) {
++ trans = apple_find_translation(swapped_option_cmd_keys, code);
++
++ if (trans)
++ code = trans->to;
++ }
++
++ if (code == KEY_FN)
++ asc->fn_on = !!value;
++
+ if (real_fnmode) {
+ if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
+ hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
+@@ -430,15 +447,18 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ else
+ table = apple_fn_keys;
+
+- trans = apple_find_translation (table, usage->code);
++ trans = apple_find_translation(table, code);
+
+ if (trans) {
+- if (test_bit(trans->from, input->key))
++ bool from_is_set = test_bit(trans->from, input->key);
++ bool to_is_set = test_bit(trans->to, input->key);
++
++ if (from_is_set)
+ code = trans->from;
+- else if (test_bit(trans->to, input->key))
++ else if (to_is_set)
+ code = trans->to;
+
+- if (!code) {
++ if (!(from_is_set || to_is_set)) {
+ if (trans->flags & APPLE_FLAG_FKEY) {
+ switch (real_fnmode) {
+ case 1:
+@@ -455,62 +475,31 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ do_translate = asc->fn_on;
+ }
+
+- code = do_translate ? trans->to : trans->from;
++ if (do_translate)
++ code = trans->to;
+ }
+-
+- input_event_with_scancode(input, usage->type, code,
+- usage->hid, value);
+- return 1;
+ }
+
+ if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
+- (test_bit(usage->code, asc->pressed_numlock) ||
++ (test_bit(code, asc->pressed_numlock) ||
+ test_bit(LED_NUML, input->led))) {
+- trans = apple_find_translation(powerbook_numlock_keys,
+- usage->code);
++ trans = apple_find_translation(powerbook_numlock_keys, code);
+
+ if (trans) {
+ if (value)
+- set_bit(usage->code,
+- asc->pressed_numlock);
++ set_bit(code, asc->pressed_numlock);
+ else
+- clear_bit(usage->code,
+- asc->pressed_numlock);
++ clear_bit(code, asc->pressed_numlock);
+
+- input_event_with_scancode(input, usage->type,
+- trans->to, usage->hid, value);
++ code = trans->to;
+ }
+-
+- return 1;
+ }
+ }
+
+- if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
+- hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
+- trans = apple_find_translation(apple_iso_keyboard, usage->code);
+- if (trans) {
+- input_event_with_scancode(input, usage->type,
+- trans->to, usage->hid, value);
+- return 1;
+- }
+- }
+-
+- if (swap_opt_cmd) {
+- trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
+- if (trans) {
+- input_event_with_scancode(input, usage->type,
+- trans->to, usage->hid, value);
+- return 1;
+- }
+- }
++ if (usage->code != code) {
++ input_event_with_scancode(input, usage->type, code, usage->hid, value);
+
+- if (swap_fn_leftctrl) {
+- trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
+- if (trans) {
+- input_event_with_scancode(input, usage->type,
+- trans->to, usage->hid, value);
+- return 1;
+- }
++ return 1;
+ }
+
+ return 0;
+@@ -640,9 +629,6 @@ static void apple_setup_input(struct input_dev *input)
+ apple_setup_key_translation(input, apple2021_fn_keys);
+ apple_setup_key_translation(input, macbookpro_no_esc_fn_keys);
+ apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys);
+-
+- if (swap_fn_leftctrl)
+- apple_setup_key_translation(input, swapped_fn_leftctrl_keys);
+ }
+
+ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -1011,21 +997,21 @@ static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
+- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
+- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
+- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
+- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 859aeb07542e3..d728a94c642eb 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -340,6 +340,7 @@ static enum power_supply_property hidinput_battery_props[] = {
+ #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */
+ #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
+ #define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
++#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */
+
+ static const struct hid_device_id hid_battery_quirks[] = {
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+@@ -373,6 +374,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
+ HID_BATTERY_QUIRK_IGNORE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
+ HID_BATTERY_QUIRK_IGNORE },
++ { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
++ HID_BATTERY_QUIRK_AVOID_QUERY },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
+ HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
+@@ -554,6 +557,9 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
+ field->physical == HID_DG_STYLUS;
+
++ if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
++ dev->battery_avoid_query = true;
++
+ dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
+ if (IS_ERR(dev->battery)) {
+ error = PTR_ERR(dev->battery);
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 68f9e9d207f42..ba14b6f69ff7a 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -2545,12 +2545,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
+ struct hid_device *hid = hidpp->hid_dev;
+ struct hid_input *hidinput;
+ struct input_dev *dev;
+- const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
+- const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
++ struct usb_device_descriptor *udesc;
++ u16 bcdDevice;
+ struct ff_device *ff;
+ int error, j, num_slots = data->num_effects;
+ u8 version;
+
++ if (!hid_is_usb(hid)) {
++ hid_err(hid, "device is not USB\n");
++ return -ENODEV;
++ }
++
+ if (list_empty(&hid->inputs)) {
+ hid_err(hid, "no inputs found\n");
+ return -ENODEV;
+@@ -2564,6 +2569,8 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
+ }
+
+ /* Get firmware release */
++ udesc = &(hid_to_usb_dev(hid)->descriptor);
++ bcdDevice = le16_to_cpu(udesc->bcdDevice);
+ version = bcdDevice & 255;
+
+ /* Set supported force feedback capabilities */
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index de52e9f7bb8cb..560eeec4035aa 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -840,12 +840,19 @@ static int mcp2221_probe(struct hid_device *hdev,
+ return ret;
+ }
+
+- ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
++ /*
++ * This driver uses the .raw_event callback and therefore does not need any
++ * HID_CONNECT_xxx flags.
++ */
++ ret = hid_hw_start(hdev, 0);
+ if (ret) {
+ hid_err(hdev, "can't start hardware\n");
+ return ret;
+ }
+
++ hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
++ hdev->version & 0xff, hdev->name, hdev->phys);
++
+ ret = hid_hw_open(hdev);
+ if (ret) {
+ hid_err(hdev, "can't open device\n");
+@@ -870,8 +877,7 @@ static int mcp2221_probe(struct hid_device *hdev,
+ mcp->adapter.retries = 1;
+ mcp->adapter.dev.parent = &hdev->dev;
+ snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
+- "MCP2221 usb-i2c bridge on hidraw%d",
+- ((struct hidraw *)hdev->hidraw)->minor);
++ "MCP2221 usb-i2c bridge");
+
+ ret = i2c_add_adapter(&mcp->adapter);
+ if (ret) {
+diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
+index 311eee599ce97..b2bf588d18c39 100644
+--- a/drivers/hid/hid-rmi.c
++++ b/drivers/hid/hid-rmi.c
+@@ -327,6 +327,8 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
+ if (!(test_bit(RMI_STARTED, &hdata->flags)))
+ return 0;
+
++ pm_wakeup_event(hdev->dev.parent, 0);
++
+ local_irq_save(flags);
+
+ rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2);
+diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c
+index 32c2306e240d6..602465ad27458 100644
+--- a/drivers/hid/hid-sensor-custom.c
++++ b/drivers/hid/hid-sensor-custom.c
+@@ -62,7 +62,7 @@ struct hid_sensor_sample {
+ u32 raw_len;
+ } __packed;
+
+-static struct attribute hid_custom_attrs[] = {
++static struct attribute hid_custom_attrs[HID_CUSTOM_TOTAL_ATTRS] = {
+ {.name = "name", .mode = S_IRUGO},
+ {.name = "units", .mode = S_IRUGO},
+ {.name = "unit-expo", .mode = S_IRUGO},
+diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
+index c078f09a2318a..5a365648206e7 100644
+--- a/drivers/hid/i2c-hid/i2c-hid-core.c
++++ b/drivers/hid/i2c-hid/i2c-hid-core.c
+@@ -554,7 +554,8 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
+ i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf);
+
+ if (test_bit(I2C_HID_STARTED, &ihid->flags)) {
+- pm_wakeup_event(&ihid->client->dev, 0);
++ if (ihid->hid->group != HID_GROUP_RMI)
++ pm_wakeup_event(&ihid->client->dev, 0);
+
+ hid_input_report(ihid->hid, HID_INPUT_REPORT,
+ ihid->inbuf + sizeof(__le16),
+diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
+index 194a2e3275914..45aee464e31ab 100644
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -160,6 +160,9 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
+ {
+ struct wacom *wacom = hid_get_drvdata(hdev);
+
++ if (wacom->wacom_wac.features.type == BOOTLOADER)
++ return 0;
++
+ if (size > WACOM_PKGLEN_MAX)
+ return 1;
+
+@@ -2790,6 +2793,11 @@ static int wacom_probe(struct hid_device *hdev,
+ return error;
+ }
+
++ if (features->type == BOOTLOADER) {
++ hid_warn(hdev, "Using device in hidraw-only mode");
++ return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
++ }
++
+ error = wacom_parse_and_register(wacom, false);
+ if (error)
+ return error;
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index 2bd1a43021c92..dc5478dc855be 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -4880,6 +4880,9 @@ static const struct wacom_features wacom_features_0x3c8 =
+ static const struct wacom_features wacom_features_HID_ANY_ID =
+ { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
+
++static const struct wacom_features wacom_features_0x94 =
++ { "Wacom Bootloader", .type = BOOTLOADER };
++
+ #define USB_DEVICE_WACOM(prod) \
+ HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
+ .driver_data = (kernel_ulong_t)&wacom_features_##prod
+@@ -4953,6 +4956,7 @@ const struct hid_device_id wacom_ids[] = {
+ { USB_DEVICE_WACOM(0x84) },
+ { USB_DEVICE_WACOM(0x90) },
+ { USB_DEVICE_WACOM(0x93) },
++ { USB_DEVICE_WACOM(0x94) },
+ { USB_DEVICE_WACOM(0x97) },
+ { USB_DEVICE_WACOM(0x9A) },
+ { USB_DEVICE_WACOM(0x9F) },
+diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
+index fef1538005b5d..174b300c49ddb 100644
+--- a/drivers/hid/wacom_wac.h
++++ b/drivers/hid/wacom_wac.h
+@@ -245,6 +245,7 @@ enum {
+ MTTPC,
+ MTTPC_B,
+ HID_GENERIC,
++ BOOTLOADER,
+ MAX_TYPE
+ };
+
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index eb98201583185..26f2c3c012978 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -502,8 +502,10 @@ static int ssi_probe(struct platform_device *pd)
+ platform_set_drvdata(pd, ssi);
+
+ err = ssi_add_controller(ssi, pd);
+- if (err < 0)
++ if (err < 0) {
++ hsi_put_controller(ssi);
+ goto out1;
++ }
+
+ pm_runtime_enable(&pd->dev);
+
+@@ -536,9 +538,9 @@ out3:
+ device_for_each_child(&pd->dev, NULL, ssi_remove_ports);
+ out2:
+ ssi_remove_controller(ssi);
++ pm_runtime_disable(&pd->dev);
+ out1:
+ platform_set_drvdata(pd, NULL);
+- pm_runtime_disable(&pd->dev);
+
+ return err;
+ }
+@@ -629,7 +631,13 @@ static int __init ssi_init(void) {
+ if (ret)
+ return ret;
+
+- return platform_driver_register(&ssi_port_pdriver);
++ ret = platform_driver_register(&ssi_port_pdriver);
++ if (ret) {
++ platform_driver_unregister(&ssi_pdriver);
++ return ret;
++ }
++
++ return 0;
+ }
+ module_init(ssi_init);
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+index 59a4aa86d1f35..c6692fd5ab155 100644
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -280,6 +280,19 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
+ ring_info->pkt_buffer_size = 0;
+ }
+
++/*
++ * Check if the ring buffer spinlock is available to take or not; used on
++ * atomic contexts, like panic path (see the Hyper-V framebuffer driver).
++ */
++
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel)
++{
++ struct hv_ring_buffer_info *rinfo = &channel->outbound;
++
++ return spin_is_locked(&rinfo->ring_lock);
++}
++EXPORT_SYMBOL_GPL(hv_ringbuffer_spinlock_busy);
++
+ /* Write to the ring buffer. */
+ int hv_ringbuffer_write(struct vmbus_channel *channel,
+ const struct kvec *kv_list, u32 kv_count,
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index e70d9614bec2c..1533127960e7e 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -798,6 +798,7 @@ config SENSORS_IT87
+ config SENSORS_JC42
+ tristate "JEDEC JC42.4 compliant memory module temperature sensors"
+ depends on I2C
++ select REGMAP_I2C
+ help
+ If you say yes here, you get support for JEDEC JC42.4 compliant
+ temperature sensors, which are used on many DDR3 memory modules for
+diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
+index 07f7f8b5b73d7..50aea882ac09b 100644
+--- a/drivers/hwmon/jc42.c
++++ b/drivers/hwmon/jc42.c
+@@ -19,6 +19,7 @@
+ #include <linux/err.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
++#include <linux/regmap.h>
+
+ /* Addresses to scan */
+ static const unsigned short normal_i2c[] = {
+@@ -199,31 +200,14 @@ static struct jc42_chips jc42_chips[] = {
+ { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },
+ };
+
+-enum temp_index {
+- t_input = 0,
+- t_crit,
+- t_min,
+- t_max,
+- t_num_temp
+-};
+-
+-static const u8 temp_regs[t_num_temp] = {
+- [t_input] = JC42_REG_TEMP,
+- [t_crit] = JC42_REG_TEMP_CRITICAL,
+- [t_min] = JC42_REG_TEMP_LOWER,
+- [t_max] = JC42_REG_TEMP_UPPER,
+-};
+-
+ /* Each client has this additional data */
+ struct jc42_data {
+- struct i2c_client *client;
+ struct mutex update_lock; /* protect register access */
++ struct regmap *regmap;
+ bool extended; /* true if extended range supported */
+ bool valid;
+- unsigned long last_updated; /* In jiffies */
+ u16 orig_config; /* original configuration */
+ u16 config; /* current configuration */
+- u16 temp[t_num_temp];/* Temperatures */
+ };
+
+ #define JC42_TEMP_MIN_EXTENDED (-40000)
+@@ -248,85 +232,102 @@ static int jc42_temp_from_reg(s16 reg)
+ return reg * 125 / 2;
+ }
+
+-static struct jc42_data *jc42_update_device(struct device *dev)
+-{
+- struct jc42_data *data = dev_get_drvdata(dev);
+- struct i2c_client *client = data->client;
+- struct jc42_data *ret = data;
+- int i, val;
+-
+- mutex_lock(&data->update_lock);
+-
+- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+- for (i = 0; i < t_num_temp; i++) {
+- val = i2c_smbus_read_word_swapped(client, temp_regs[i]);
+- if (val < 0) {
+- ret = ERR_PTR(val);
+- goto abort;
+- }
+- data->temp[i] = val;
+- }
+- data->last_updated = jiffies;
+- data->valid = true;
+- }
+-abort:
+- mutex_unlock(&data->update_lock);
+- return ret;
+-}
+-
+ static int jc42_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+ {
+- struct jc42_data *data = jc42_update_device(dev);
+- int temp, hyst;
++ struct jc42_data *data = dev_get_drvdata(dev);
++ unsigned int regval;
++ int ret, temp, hyst;
+
+- if (IS_ERR(data))
+- return PTR_ERR(data);
++ mutex_lock(&data->update_lock);
+
+ switch (attr) {
+ case hwmon_temp_input:
+- *val = jc42_temp_from_reg(data->temp[t_input]);
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);
++ if (ret)
++ break;
++
++ *val = jc42_temp_from_reg(regval);
++ break;
+ case hwmon_temp_min:
+- *val = jc42_temp_from_reg(data->temp[t_min]);
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val);
++ if (ret)
++ break;
++
++ *val = jc42_temp_from_reg(regval);
++ break;
+ case hwmon_temp_max:
+- *val = jc42_temp_from_reg(data->temp[t_max]);
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val);
++ if (ret)
++ break;
++
++ *val = jc42_temp_from_reg(regval);
++ break;
+ case hwmon_temp_crit:
+- *val = jc42_temp_from_reg(data->temp[t_crit]);
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++ ®val);
++ if (ret)
++ break;
++
++ *val = jc42_temp_from_reg(regval);
++ break;
+ case hwmon_temp_max_hyst:
+- temp = jc42_temp_from_reg(data->temp[t_max]);
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val);
++ if (ret)
++ break;
++
++ temp = jc42_temp_from_reg(regval);
+ hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+ >> JC42_CFG_HYST_SHIFT];
+ *val = temp - hyst;
+- return 0;
++ break;
+ case hwmon_temp_crit_hyst:
+- temp = jc42_temp_from_reg(data->temp[t_crit]);
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++ ®val);
++ if (ret)
++ break;
++
++ temp = jc42_temp_from_reg(regval);
+ hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+ >> JC42_CFG_HYST_SHIFT];
+ *val = temp - hyst;
+- return 0;
++ break;
+ case hwmon_temp_min_alarm:
+- *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1;
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);
++ if (ret)
++ break;
++
++ *val = (regval >> JC42_ALARM_MIN_BIT) & 1;
++ break;
+ case hwmon_temp_max_alarm:
+- *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1;
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);
++ if (ret)
++ break;
++
++ *val = (regval >> JC42_ALARM_MAX_BIT) & 1;
++ break;
+ case hwmon_temp_crit_alarm:
+- *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1;
+- return 0;
++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);
++ if (ret)
++ break;
++
++ *val = (regval >> JC42_ALARM_CRIT_BIT) & 1;
++ break;
+ default:
+- return -EOPNOTSUPP;
++ ret = -EOPNOTSUPP;
++ break;
+ }
++
++ mutex_unlock(&data->update_lock);
++
++ return ret;
+ }
+
+ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+ {
+ struct jc42_data *data = dev_get_drvdata(dev);
+- struct i2c_client *client = data->client;
++ unsigned int regval;
+ int diff, hyst;
+ int ret;
+
+@@ -334,21 +335,23 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+
+ switch (attr) {
+ case hwmon_temp_min:
+- data->temp[t_min] = jc42_temp_to_reg(val, data->extended);
+- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min],
+- data->temp[t_min]);
++ ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER,
++ jc42_temp_to_reg(val, data->extended));
+ break;
+ case hwmon_temp_max:
+- data->temp[t_max] = jc42_temp_to_reg(val, data->extended);
+- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max],
+- data->temp[t_max]);
++ ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER,
++ jc42_temp_to_reg(val, data->extended));
+ break;
+ case hwmon_temp_crit:
+- data->temp[t_crit] = jc42_temp_to_reg(val, data->extended);
+- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit],
+- data->temp[t_crit]);
++ ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL,
++ jc42_temp_to_reg(val, data->extended));
+ break;
+ case hwmon_temp_crit_hyst:
++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++ ®val);
++ if (ret)
++ break;
++
+ /*
+ * JC42.4 compliant chips only support four hysteresis values.
+ * Pick best choice and go from there.
+@@ -356,7 +359,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED
+ : JC42_TEMP_MIN) - 6000,
+ JC42_TEMP_MAX);
+- diff = jc42_temp_from_reg(data->temp[t_crit]) - val;
++ diff = jc42_temp_from_reg(regval) - val;
+ hyst = 0;
+ if (diff > 0) {
+ if (diff < 2250)
+@@ -368,9 +371,8 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ }
+ data->config = (data->config & ~JC42_CFG_HYST_MASK) |
+ (hyst << JC42_CFG_HYST_SHIFT);
+- ret = i2c_smbus_write_word_swapped(data->client,
+- JC42_REG_CONFIG,
+- data->config);
++ ret = regmap_write(data->regmap, JC42_REG_CONFIG,
++ data->config);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+@@ -470,51 +472,80 @@ static const struct hwmon_chip_info jc42_chip_info = {
+ .info = jc42_info,
+ };
+
++static bool jc42_readable_reg(struct device *dev, unsigned int reg)
++{
++ return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) ||
++ reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_writable_reg(struct device *dev, unsigned int reg)
++{
++ return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) ||
++ reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_volatile_reg(struct device *dev, unsigned int reg)
++{
++ return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP;
++}
++
++static const struct regmap_config jc42_regmap_config = {
++ .reg_bits = 8,
++ .val_bits = 16,
++ .val_format_endian = REGMAP_ENDIAN_BIG,
++ .max_register = JC42_REG_SMBUS,
++ .writeable_reg = jc42_writable_reg,
++ .readable_reg = jc42_readable_reg,
++ .volatile_reg = jc42_volatile_reg,
++ .cache_type = REGCACHE_RBTREE,
++};
++
+ static int jc42_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
++ unsigned int config, cap;
+ struct jc42_data *data;
+- int config, cap;
++ int ret;
+
+ data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+- data->client = client;
++ data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config);
++ if (IS_ERR(data->regmap))
++ return PTR_ERR(data->regmap);
++
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+- cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);
+- if (cap < 0)
+- return cap;
++ ret = regmap_read(data->regmap, JC42_REG_CAP, &cap);
++ if (ret)
++ return ret;
+
+ data->extended = !!(cap & JC42_CAP_RANGE);
+
+ if (device_property_read_bool(dev, "smbus-timeout-disable")) {
+- int smbus;
+-
+ /*
+ * Not all chips support this register, but from a
+ * quick read of various datasheets no chip appears
+ * incompatible with the below attempt to disable
+ * the timeout. And the whole thing is opt-in...
+ */
+- smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
+- if (smbus < 0)
+- return smbus;
+- i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
+- smbus | SMBUS_STMOUT);
++ ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS,
++ SMBUS_STMOUT);
++ if (ret)
++ return ret;
+ }
+
+- config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
+- if (config < 0)
+- return config;
++ ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config);
++ if (ret)
++ return ret;
+
+ data->orig_config = config;
+ if (config & JC42_CFG_SHUTDOWN) {
+ config &= ~JC42_CFG_SHUTDOWN;
+- i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++ regmap_write(data->regmap, JC42_REG_CONFIG, config);
+ }
+ data->config = config;
+
+@@ -535,7 +566,7 @@ static int jc42_remove(struct i2c_client *client)
+
+ config = (data->orig_config & ~JC42_CFG_HYST_MASK)
+ | (data->config & JC42_CFG_HYST_MASK);
+- i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++ regmap_write(data->regmap, JC42_REG_CONFIG, config);
+ }
+ return 0;
+ }
+@@ -547,8 +578,11 @@ static int jc42_suspend(struct device *dev)
+ struct jc42_data *data = dev_get_drvdata(dev);
+
+ data->config |= JC42_CFG_SHUTDOWN;
+- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+- data->config);
++ regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
++
++ regcache_cache_only(data->regmap, true);
++ regcache_mark_dirty(data->regmap);
++
+ return 0;
+ }
+
+@@ -556,10 +590,13 @@ static int jc42_resume(struct device *dev)
+ {
+ struct jc42_data *data = dev_get_drvdata(dev);
+
++ regcache_cache_only(data->regmap, false);
++
+ data->config &= ~JC42_CFG_SHUTDOWN;
+- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+- data->config);
+- return 0;
++ regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
++
++ /* Restore cached register values to hardware */
++ return regcache_sync(data->regmap);
+ }
+
+ static const struct dev_pm_ops jc42_dev_pm_ops = {
+diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c
+index 41c97cfacfb8c..50fe9533cf439 100644
+--- a/drivers/hwmon/nct6775-platform.c
++++ b/drivers/hwmon/nct6775-platform.c
+@@ -1043,7 +1043,9 @@ static struct platform_device *pdev[2];
+
+ static const char * const asus_wmi_boards[] = {
+ "PRO H410T",
++ "ProArt B550-CREATOR",
+ "ProArt X570-CREATOR WIFI",
++ "ProArt Z490-CREATOR 10G",
+ "Pro B550M-C",
+ "Pro WS X570-ACE",
+ "PRIME B360-PLUS",
+@@ -1055,8 +1057,10 @@ static const char * const asus_wmi_boards[] = {
+ "PRIME X570-P",
+ "PRIME X570-PRO",
+ "ROG CROSSHAIR VIII DARK HERO",
++ "ROG CROSSHAIR VIII EXTREME",
+ "ROG CROSSHAIR VIII FORMULA",
+ "ROG CROSSHAIR VIII HERO",
++ "ROG CROSSHAIR VIII HERO (WI-FI)",
+ "ROG CROSSHAIR VIII IMPACT",
+ "ROG STRIX B550-A GAMING",
+ "ROG STRIX B550-E GAMING",
+@@ -1080,8 +1084,11 @@ static const char * const asus_wmi_boards[] = {
+ "ROG STRIX Z490-G GAMING (WI-FI)",
+ "ROG STRIX Z490-H GAMING",
+ "ROG STRIX Z490-I GAMING",
++ "TUF GAMING B550M-E",
++ "TUF GAMING B550M-E (WI-FI)",
+ "TUF GAMING B550M-PLUS",
+ "TUF GAMING B550M-PLUS (WI-FI)",
++ "TUF GAMING B550M-PLUS WIFI II",
+ "TUF GAMING B550-PLUS",
+ "TUF GAMING B550-PLUS WIFI II",
+ "TUF GAMING B550-PRO",
+diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
+index 2b386bb848f8d..1fc4fd79a1c69 100644
+--- a/drivers/hwtracing/coresight/coresight-trbe.c
++++ b/drivers/hwtracing/coresight/coresight-trbe.c
+@@ -1434,6 +1434,7 @@ static int arm_trbe_probe_cpuhp(struct trbe_drvdata *drvdata)
+
+ static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata)
+ {
++ cpuhp_state_remove_instance(drvdata->trbe_online, &drvdata->hotplug_node);
+ cpuhp_remove_multi_state(drvdata->trbe_online);
+ }
+
+diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
+index 6078fa0c0d488..63120c41354c0 100644
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -509,6 +509,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
+ if (read_write == I2C_SMBUS_WRITE) {
+ /* Block Write */
+ dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: WRITE\n");
++ if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
++ return -EINVAL;
++
+ dma_size = data->block[0] + 1;
+ dma_direction = DMA_TO_DEVICE;
+ desc->wr_len_cmd = dma_size;
+diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
+index f614cade432bb..30e38bc8b6db8 100644
+--- a/drivers/i2c/busses/i2c-pxa-pci.c
++++ b/drivers/i2c/busses/i2c-pxa-pci.c
+@@ -105,7 +105,7 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ int i;
+ struct ce4100_devices *sds;
+
+- ret = pci_enable_device_mem(dev);
++ ret = pcim_enable_device(dev);
+ if (ret)
+ return ret;
+
+@@ -114,10 +114,8 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ return -EINVAL;
+ }
+ sds = kzalloc(sizeof(*sds), GFP_KERNEL);
+- if (!sds) {
+- ret = -ENOMEM;
+- goto err_mem;
+- }
++ if (!sds)
++ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
+ sds->pdev[i] = add_i2c_device(dev, i);
+@@ -133,8 +131,6 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+
+ err_dev_add:
+ kfree(sds);
+-err_mem:
+- pci_disable_device(dev);
+ return ret;
+ }
+
+diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
+index 0e0679f65cf77..30a6de1694e07 100644
+--- a/drivers/i2c/muxes/i2c-mux-reg.c
++++ b/drivers/i2c/muxes/i2c-mux-reg.c
+@@ -183,13 +183,12 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
+ if (!mux->data.reg) {
+ dev_info(&pdev->dev,
+ "Register not set, using platform resource\n");
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- mux->data.reg_size = resource_size(res);
+- mux->data.reg = devm_ioremap_resource(&pdev->dev, res);
++ mux->data.reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(mux->data.reg)) {
+ ret = PTR_ERR(mux->data.reg);
+ goto err_put_parent;
+ }
++ mux->data.reg_size = resource_size(res);
+ }
+
+ if (mux->data.reg_size != 4 && mux->data.reg_size != 2 &&
+diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
+index 261a9a6b45e15..d8570f620785a 100644
+--- a/drivers/iio/adc/ad_sigma_delta.c
++++ b/drivers/iio/adc/ad_sigma_delta.c
+@@ -281,10 +281,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
+ unsigned int data_reg;
+ int ret = 0;
+
+- if (iio_buffer_enabled(indio_dev))
+- return -EBUSY;
++ ret = iio_device_claim_direct_mode(indio_dev);
++ if (ret)
++ return ret;
+
+- mutex_lock(&indio_dev->mlock);
+ ad_sigma_delta_set_channel(sigma_delta, chan->address);
+
+ spi_bus_lock(sigma_delta->spi->master);
+@@ -323,7 +323,7 @@ out:
+ ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+ sigma_delta->bus_locked = false;
+ spi_bus_unlock(sigma_delta->spi->master);
+- mutex_unlock(&indio_dev->mlock);
++ iio_device_release_direct_mode(indio_dev);
+
+ if (ret)
+ return ret;
+diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c
+index 622fd384983c7..b3d5b9b7255bc 100644
+--- a/drivers/iio/adc/ti-adc128s052.c
++++ b/drivers/iio/adc/ti-adc128s052.c
+@@ -181,13 +181,13 @@ static int adc128_probe(struct spi_device *spi)
+ }
+
+ static const struct of_device_id adc128_of_match[] = {
+- { .compatible = "ti,adc128s052", },
+- { .compatible = "ti,adc122s021", },
+- { .compatible = "ti,adc122s051", },
+- { .compatible = "ti,adc122s101", },
+- { .compatible = "ti,adc124s021", },
+- { .compatible = "ti,adc124s051", },
+- { .compatible = "ti,adc124s101", },
++ { .compatible = "ti,adc128s052", .data = (void*)0L, },
++ { .compatible = "ti,adc122s021", .data = (void*)1L, },
++ { .compatible = "ti,adc122s051", .data = (void*)1L, },
++ { .compatible = "ti,adc122s101", .data = (void*)1L, },
++ { .compatible = "ti,adc124s021", .data = (void*)2L, },
++ { .compatible = "ti,adc124s051", .data = (void*)2L, },
++ { .compatible = "ti,adc124s101", .data = (void*)2L, },
+ { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, adc128_of_match);
+diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c
+index 899bcd83f40bc..e0e130ba9d3ec 100644
+--- a/drivers/iio/addac/ad74413r.c
++++ b/drivers/iio/addac/ad74413r.c
+@@ -691,7 +691,7 @@ static int ad74413_get_input_current_offset(struct ad74413r_state *st,
+ if (ret)
+ return ret;
+
+- *val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range;
++ *val = voltage_offset * (int)AD74413R_ADC_RESULT_MAX / voltage_range;
+
+ return IIO_VAL_INT;
+ }
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index f7fcfd04f659d..bc40240b29e26 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -270,23 +270,19 @@ EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB);
+ #endif
+
+ /**
+- * adis_enable_irq() - Enable or disable data ready IRQ
++ * __adis_enable_irq() - Enable or disable data ready IRQ (unlocked)
+ * @adis: The adis device
+ * @enable: Whether to enable the IRQ
+ *
+ * Returns 0 on success, negative error code otherwise
+ */
+-int adis_enable_irq(struct adis *adis, bool enable)
++int __adis_enable_irq(struct adis *adis, bool enable)
+ {
+- int ret = 0;
++ int ret;
+ u16 msc;
+
+- mutex_lock(&adis->state_lock);
+-
+- if (adis->data->enable_irq) {
+- ret = adis->data->enable_irq(adis, enable);
+- goto out_unlock;
+- }
++ if (adis->data->enable_irq)
++ return adis->data->enable_irq(adis, enable);
+
+ if (adis->data->unmasked_drdy) {
+ if (enable)
+@@ -294,12 +290,12 @@ int adis_enable_irq(struct adis *adis, bool enable)
+ else
+ disable_irq(adis->spi->irq);
+
+- goto out_unlock;
++ return 0;
+ }
+
+ ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+ if (ret)
+- goto out_unlock;
++ return ret;
+
+ msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
+ msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
+@@ -308,13 +304,9 @@ int adis_enable_irq(struct adis *adis, bool enable)
+ else
+ msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
+
+- ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+-
+-out_unlock:
+- mutex_unlock(&adis->state_lock);
+- return ret;
++ return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+ }
+-EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB);
++EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB);
+
+ /**
+ * __adis_check_status() - Check the device for error conditions (unlocked)
+@@ -445,7 +437,7 @@ int __adis_initial_startup(struct adis *adis)
+ * with 'IRQF_NO_AUTOEN' anyways.
+ */
+ if (!adis->data->unmasked_drdy)
+- adis_enable_irq(adis, false);
++ __adis_enable_irq(adis, false);
+
+ if (!adis->data->prod_id_reg)
+ return 0;
+diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
+index b5e059e15b0ae..ef161fa08146d 100644
+--- a/drivers/iio/industrialio-event.c
++++ b/drivers/iio/industrialio-event.c
+@@ -550,7 +550,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
+
+ ret = iio_device_register_sysfs_group(indio_dev, &ev_int->group);
+ if (ret)
+- goto error_free_setup_event_lines;
++ goto error_free_group_attrs;
+
+ ev_int->ioctl_handler.ioctl = iio_event_ioctl;
+ iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev,
+@@ -558,6 +558,8 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
+
+ return 0;
+
++error_free_group_attrs:
++ kfree(ev_int->group.attrs);
+ error_free_setup_event_lines:
+ iio_free_chan_devattr_list(&ev_int->dev_attr_list);
+ kfree(ev_int);
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index a60ccf1836872..1117991ca2ab6 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -209,6 +209,7 @@ struct ltc2983_data {
+ * Holds the converted temperature
+ */
+ __be32 temp __aligned(IIO_DMA_MINALIGN);
++ __be32 chan_val;
+ };
+
+ struct ltc2983_sensor {
+@@ -313,19 +314,18 @@ static int __ltc2983_fault_handler(const struct ltc2983_data *st,
+ return 0;
+ }
+
+-static int __ltc2983_chan_assign_common(const struct ltc2983_data *st,
++static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
+ const struct ltc2983_sensor *sensor,
+ u32 chan_val)
+ {
+ u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan);
+- __be32 __chan_val;
+
+ chan_val |= LTC2983_CHAN_TYPE(sensor->type);
+ dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
+ chan_val);
+- __chan_val = cpu_to_be32(chan_val);
+- return regmap_bulk_write(st->regmap, reg, &__chan_val,
+- sizeof(__chan_val));
++ st->chan_val = cpu_to_be32(chan_val);
++ return regmap_bulk_write(st->regmap, reg, &st->chan_val,
++ sizeof(st->chan_val));
+ }
+
+ static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st,
+diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
+index aa36ac618e729..17a2274152771 100644
+--- a/drivers/infiniband/Kconfig
++++ b/drivers/infiniband/Kconfig
+@@ -78,6 +78,7 @@ config INFINIBAND_VIRT_DMA
+ def_bool !HIGHMEM
+
+ if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS
++if !UML
+ source "drivers/infiniband/hw/bnxt_re/Kconfig"
+ source "drivers/infiniband/hw/cxgb4/Kconfig"
+ source "drivers/infiniband/hw/efa/Kconfig"
+@@ -94,6 +95,7 @@ source "drivers/infiniband/hw/qib/Kconfig"
+ source "drivers/infiniband/hw/usnic/Kconfig"
+ source "drivers/infiniband/hw/vmw_pvrdma/Kconfig"
+ source "drivers/infiniband/sw/rdmavt/Kconfig"
++endif # !UML
+ source "drivers/infiniband/sw/rxe/Kconfig"
+ source "drivers/infiniband/sw/siw/Kconfig"
+ endif
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 4053a09b8d33e..267d6e7fb18e0 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -2851,8 +2851,8 @@ err:
+ static void __exit ib_core_cleanup(void)
+ {
+ roce_gid_mgmt_cleanup();
+- nldev_exit();
+ rdma_nl_unregister(RDMA_NL_LS);
++ nldev_exit();
+ unregister_pernet_device(&rdma_dev_net_ops);
+ unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+ ib_sa_cleanup();
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 1893aa613ad73..674344eb8e2f4 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -59,9 +59,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+ struct ib_mad_qp_info *qp_info,
+ struct trace_event_raw_ib_mad_send_template *entry)
+ {
+- u16 pkey;
+- struct ib_device *dev = qp_info->port_priv->device;
+- u32 pnum = qp_info->port_priv->port_num;
+ struct ib_ud_wr *wr = &mad_send_wr->send_wr;
+ struct rdma_ah_attr attr = {};
+
+@@ -69,8 +66,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+
+ /* These are common */
+ entry->sl = attr.sl;
+- ib_query_pkey(dev, pnum, wr->pkey_index, &pkey);
+- entry->pkey = pkey;
+ entry->rqpn = wr->remote_qpn;
+ entry->rqkey = wr->remote_qkey;
+ entry->dlid = rdma_ah_get_dlid(&attr);
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index 12dc97067ed2b..222733a83ddb7 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -513,7 +513,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin,
+
+ /* In create_qp() port is not set yet */
+ if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port))
+- return -EINVAL;
++ return -EMSGSIZE;
+
+ ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num);
+ if (ret)
+@@ -552,7 +552,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin,
+ struct rdma_cm_id *cm_id = &id_priv->id;
+
+ if (port && port != cm_id->port_num)
+- return 0;
++ return -EAGAIN;
+
+ if (cm_id->port_num &&
+ nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num))
+@@ -894,6 +894,8 @@ static int fill_stat_counter_qps(struct sk_buff *msg,
+ int ret = 0;
+
+ table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP);
++ if (!table_attr)
++ return -EMSGSIZE;
+
+ rt = &counter->device->res[RDMA_RESTRACK_QP];
+ xa_lock(&rt->xa);
+diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c
+index 1f935d9f61785..01a499a8b88db 100644
+--- a/drivers/infiniband/core/restrack.c
++++ b/drivers/infiniband/core/restrack.c
+@@ -343,8 +343,6 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
+ rt = &dev->res[res->type];
+
+ old = xa_erase(&rt->xa, res->id);
+- if (res->type == RDMA_RESTRACK_MR)
+- return;
+ WARN_ON(old != res);
+
+ out:
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+index 84c53bd2a52db..ee59d73915689 100644
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -1213,6 +1213,9 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
+ p->port_num = port_num;
+ kobject_init(&p->kobj, &port_type);
+
++ if (device->port_data && is_full_dev)
++ device->port_data[port_num].sysfs = p;
++
+ cur_group = p->groups_list;
+ ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list,
+ attr->gid_tbl_len, show_port_gid);
+@@ -1258,9 +1261,6 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
+ }
+
+ list_add_tail(&p->kobj.entry, &coredev->port_list);
+- if (device->port_data && is_full_dev)
+- device->port_data[port_num].sysfs = p;
+-
+ return p;
+
+ err_groups:
+@@ -1268,6 +1268,8 @@ err_groups:
+ err_del:
+ kobject_del(&p->kobj);
+ err_put:
++ if (device->port_data && is_full_dev)
++ device->port_data[port_num].sysfs = NULL;
+ kobject_put(&p->kobj);
+ return ERR_PTR(ret);
+ }
+@@ -1276,14 +1278,17 @@ static void destroy_port(struct ib_core_device *coredev, struct ib_port *port)
+ {
+ bool is_full_dev = &port->ibdev->coredev == coredev;
+
+- if (port->ibdev->port_data &&
+- port->ibdev->port_data[port->port_num].sysfs == port)
+- port->ibdev->port_data[port->port_num].sysfs = NULL;
+ list_del(&port->kobj.entry);
+ if (is_full_dev)
+ sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups);
++
+ sysfs_remove_groups(&port->kobj, port->groups_list);
+ kobject_del(&port->kobj);
++
++ if (port->ibdev->port_data &&
++ port->ibdev->port_data[port->port_num].sysfs == port)
++ port->ibdev->port_data[port->port_num].sysfs = NULL;
++
+ kobject_put(&port->kobj);
+ }
+
+diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
+index 877f8e84a672a..77ee77d4000fb 100644
+--- a/drivers/infiniband/hw/hfi1/affinity.c
++++ b/drivers/infiniband/hw/hfi1/affinity.c
+@@ -177,6 +177,8 @@ out:
+ for (node = 0; node < node_affinity.num_possible_nodes; node++)
+ hfi1_per_node_cntr[node] = 1;
+
++ pci_dev_put(dev);
++
+ return 0;
+ }
+
+diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c
+index aa15a5cc7cf3a..9705bd7ea0647 100644
+--- a/drivers/infiniband/hw/hfi1/firmware.c
++++ b/drivers/infiniband/hw/hfi1/firmware.c
+@@ -1743,6 +1743,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+
+ if (!dd->platform_config.data) {
+ dd_dev_err(dd, "%s: Missing config file\n", __func__);
++ ret = -EINVAL;
+ goto bail;
+ }
+ ptr = (u32 *)dd->platform_config.data;
+@@ -1751,6 +1752,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ ptr++;
+ if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) {
+ dd_dev_err(dd, "%s: Bad config file\n", __func__);
++ ret = -EINVAL;
+ goto bail;
+ }
+
+@@ -1774,6 +1776,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ if (file_length > dd->platform_config.size) {
+ dd_dev_info(dd, "%s:File claims to be larger than read size\n",
+ __func__);
++ ret = -EINVAL;
+ goto bail;
+ } else if (file_length < dd->platform_config.size) {
+ dd_dev_info(dd,
+@@ -1794,6 +1797,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ dd_dev_err(dd, "%s: Failed validation at offset %ld\n",
+ __func__, (ptr - (u32 *)
+ dd->platform_config.data));
++ ret = -EINVAL;
+ goto bail;
+ }
+
+@@ -1837,6 +1841,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ __func__, table_type,
+ (ptr - (u32 *)
+ dd->platform_config.data));
++ ret = -EINVAL;
+ goto bail; /* We don't trust this file now */
+ }
+ pcfgcache->config_tables[table_type].table = ptr;
+@@ -1856,6 +1861,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ __func__, table_type,
+ (ptr -
+ (u32 *)dd->platform_config.data));
++ ret = -EINVAL;
+ goto bail; /* We don't trust this file now */
+ }
+ pcfgcache->config_tables[table_type].table_metadata =
+diff --git a/drivers/infiniband/hw/hns/Makefile b/drivers/infiniband/hw/hns/Makefile
+index 9f04f25d96317..a7d259238305b 100644
+--- a/drivers/infiniband/hw/hns/Makefile
++++ b/drivers/infiniband/hw/hns/Makefile
+@@ -10,6 +10,6 @@ hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
+ hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o
+
+ ifdef CONFIG_INFINIBAND_HNS_HIP08
+-hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o $(hns-roce-objs)
++hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
+ obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v2.o
+ endif
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index d24996526c4d9..48db4a42b7d3f 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -202,6 +202,7 @@ struct hns_roce_ucontext {
+ struct list_head page_list;
+ struct mutex page_mutex;
+ struct hns_user_mmap_entry *db_mmap_entry;
++ u32 config;
+ };
+
+ struct hns_roce_pd {
+@@ -335,6 +336,7 @@ struct hns_roce_wq {
+ u32 head;
+ u32 tail;
+ void __iomem *db_reg;
++ u32 ext_sge_cnt;
+ };
+
+ struct hns_roce_sge {
+@@ -637,6 +639,7 @@ struct hns_roce_qp {
+ struct list_head rq_node; /* all recv qps are on a list */
+ struct list_head sq_node; /* all send qps are on a list */
+ struct hns_user_mmap_entry *dwqe_mmap_entry;
++ u32 config;
+ };
+
+ struct hns_roce_ib_iboe {
+@@ -848,11 +851,6 @@ struct hns_roce_caps {
+ enum cong_type cong_type;
+ };
+
+-struct hns_roce_dfx_hw {
+- int (*query_cqc_info)(struct hns_roce_dev *hr_dev, u32 cqn,
+- int *buffer);
+-};
+-
+ enum hns_roce_device_state {
+ HNS_ROCE_DEVICE_STATE_INITED,
+ HNS_ROCE_DEVICE_STATE_RST_DOWN,
+@@ -898,6 +896,7 @@ struct hns_roce_hw {
+ int (*init_eq)(struct hns_roce_dev *hr_dev);
+ void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
+ int (*write_srqc)(struct hns_roce_srq *srq, void *mb_buf);
++ int (*query_cqc)(struct hns_roce_dev *hr_dev, u32 cqn, void *buffer);
+ const struct ib_device_ops *hns_roce_dev_ops;
+ const struct ib_device_ops *hns_roce_dev_srq_ops;
+ };
+@@ -959,7 +958,6 @@ struct hns_roce_dev {
+ void *priv;
+ struct workqueue_struct *irq_workq;
+ struct work_struct ecc_work;
+- const struct hns_roce_dfx_hw *dfx;
+ u32 func_num;
+ u32 is_vf;
+ u32 cong_algo_tmpl_id;
+@@ -1227,8 +1225,7 @@ u8 hns_get_gid_index(struct hns_roce_dev *hr_dev, u32 port, int gid_index);
+ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev);
+ int hns_roce_init(struct hns_roce_dev *hr_dev);
+ void hns_roce_exit(struct hns_roce_dev *hr_dev);
+-int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
+- struct ib_cq *ib_cq);
++int hns_roce_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ib_cq);
+ struct hns_user_mmap_entry *
+ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address,
+ size_t length,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 105888c6ccb77..b55a96863d1ae 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -192,8 +192,6 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ unsigned int *sge_idx, u32 msg_len)
+ {
+ struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev;
+- unsigned int dseg_len = sizeof(struct hns_roce_v2_wqe_data_seg);
+- unsigned int ext_sge_sz = qp->sq.max_gs * dseg_len;
+ unsigned int left_len_in_pg;
+ unsigned int idx = *sge_idx;
+ unsigned int i = 0;
+@@ -201,7 +199,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ void *addr;
+ void *dseg;
+
+- if (msg_len > ext_sge_sz) {
++ if (msg_len > qp->sq.ext_sge_cnt * HNS_ROCE_SGE_SIZE) {
+ ibdev_err(ibdev,
+ "no enough extended sge space for inline data.\n");
+ return -EINVAL;
+@@ -221,7 +219,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ if (len <= left_len_in_pg) {
+ memcpy(dseg, addr, len);
+
+- idx += len / dseg_len;
++ idx += len / HNS_ROCE_SGE_SIZE;
+
+ i++;
+ if (i >= wr->num_sge)
+@@ -236,7 +234,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+
+ len -= left_len_in_pg;
+ addr += left_len_in_pg;
+- idx += left_len_in_pg / dseg_len;
++ idx += left_len_in_pg / HNS_ROCE_SGE_SIZE;
+ dseg = hns_roce_get_extend_sge(qp,
+ idx & (qp->sge.sge_cnt - 1));
+ left_len_in_pg = 1 << HNS_HW_PAGE_SHIFT;
+@@ -1275,6 +1273,30 @@ static void update_cmdq_status(struct hns_roce_dev *hr_dev)
+ hr_dev->cmd.state = HNS_ROCE_CMDQ_STATE_FATAL_ERR;
+ }
+
++static int hns_roce_cmd_err_convert_errno(u16 desc_ret)
++{
++ struct hns_roce_cmd_errcode errcode_table[] = {
++ {CMD_EXEC_SUCCESS, 0},
++ {CMD_NO_AUTH, -EPERM},
++ {CMD_NOT_EXIST, -EOPNOTSUPP},
++ {CMD_CRQ_FULL, -EXFULL},
++ {CMD_NEXT_ERR, -ENOSR},
++ {CMD_NOT_EXEC, -ENOTBLK},
++ {CMD_PARA_ERR, -EINVAL},
++ {CMD_RESULT_ERR, -ERANGE},
++ {CMD_TIMEOUT, -ETIME},
++ {CMD_HILINK_ERR, -ENOLINK},
++ {CMD_INFO_ILLEGAL, -ENXIO},
++ {CMD_INVALID, -EBADR},
++ };
++ u16 i;
++
++ for (i = 0; i < ARRAY_SIZE(errcode_table); i++)
++ if (desc_ret == errcode_table[i].return_status)
++ return errcode_table[i].errno;
++ return -EIO;
++}
++
+ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmq_desc *desc, int num)
+ {
+@@ -1320,7 +1342,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ dev_err_ratelimited(hr_dev->dev,
+ "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n",
+ desc->opcode, desc_ret);
+- ret = -EIO;
++ ret = hns_roce_cmd_err_convert_errno(desc_ret);
+ }
+ } else {
+ /* FW/HW reset or incorrect number of desc */
+@@ -2027,13 +2049,14 @@ static void set_default_caps(struct hns_roce_dev *hr_dev)
+
+ caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW |
+ HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR |
+- HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL | HNS_ROCE_CAP_FLAG_XRC;
++ HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL;
+
+ caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM;
+
+ if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) {
+ caps->flags |= HNS_ROCE_CAP_FLAG_STASH |
+- HNS_ROCE_CAP_FLAG_DIRECT_WQE;
++ HNS_ROCE_CAP_FLAG_DIRECT_WQE |
++ HNS_ROCE_CAP_FLAG_XRC;
+ caps->max_sq_inline = HNS_ROCE_V3_MAX_SQ_INLINE;
+ } else {
+ caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE;
+@@ -2346,6 +2369,9 @@ static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev)
+ caps->wqe_sge_hop_num = hr_reg_read(resp_d, PF_CAPS_D_EX_SGE_HOP_NUM);
+ caps->wqe_rq_hop_num = hr_reg_read(resp_d, PF_CAPS_D_RQWQE_HOP_NUM);
+
++ if (!(caps->page_size_cap & PAGE_SIZE))
++ caps->page_size_cap = HNS_ROCE_V2_PAGE_SIZE_SUPPORTED;
++
+ return 0;
+ }
+
+@@ -2635,31 +2661,124 @@ static void free_dip_list(struct hns_roce_dev *hr_dev)
+ spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags);
+ }
+
+-static void free_mr_exit(struct hns_roce_dev *hr_dev)
++static struct ib_pd *free_mr_init_pd(struct hns_roce_dev *hr_dev)
++{
++ struct hns_roce_v2_priv *priv = hr_dev->priv;
++ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++ struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct hns_roce_pd *hr_pd;
++ struct ib_pd *pd;
++
++ hr_pd = kzalloc(sizeof(*hr_pd), GFP_KERNEL);
++ if (ZERO_OR_NULL_PTR(hr_pd))
++ return NULL;
++ pd = &hr_pd->ibpd;
++ pd->device = ibdev;
++
++ if (hns_roce_alloc_pd(pd, NULL)) {
++ ibdev_err(ibdev, "failed to create pd for free mr.\n");
++ kfree(hr_pd);
++ return NULL;
++ }
++ free_mr->rsv_pd = to_hr_pd(pd);
++ free_mr->rsv_pd->ibpd.device = &hr_dev->ib_dev;
++ free_mr->rsv_pd->ibpd.uobject = NULL;
++ free_mr->rsv_pd->ibpd.__internal_mr = NULL;
++ atomic_set(&free_mr->rsv_pd->ibpd.usecnt, 0);
++
++ return pd;
++}
++
++static struct ib_cq *free_mr_init_cq(struct hns_roce_dev *hr_dev)
++{
++ struct hns_roce_v2_priv *priv = hr_dev->priv;
++ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++ struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct ib_cq_init_attr cq_init_attr = {};
++ struct hns_roce_cq *hr_cq;
++ struct ib_cq *cq;
++
++ cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM;
++
++ hr_cq = kzalloc(sizeof(*hr_cq), GFP_KERNEL);
++ if (ZERO_OR_NULL_PTR(hr_cq))
++ return NULL;
++
++ cq = &hr_cq->ib_cq;
++ cq->device = ibdev;
++
++ if (hns_roce_create_cq(cq, &cq_init_attr, NULL)) {
++ ibdev_err(ibdev, "failed to create cq for free mr.\n");
++ kfree(hr_cq);
++ return NULL;
++ }
++ free_mr->rsv_cq = to_hr_cq(cq);
++ free_mr->rsv_cq->ib_cq.device = &hr_dev->ib_dev;
++ free_mr->rsv_cq->ib_cq.uobject = NULL;
++ free_mr->rsv_cq->ib_cq.comp_handler = NULL;
++ free_mr->rsv_cq->ib_cq.event_handler = NULL;
++ free_mr->rsv_cq->ib_cq.cq_context = NULL;
++ atomic_set(&free_mr->rsv_cq->ib_cq.usecnt, 0);
++
++ return cq;
++}
++
++static int free_mr_init_qp(struct hns_roce_dev *hr_dev, struct ib_cq *cq,
++ struct ib_qp_init_attr *init_attr, int i)
+ {
+ struct hns_roce_v2_priv *priv = hr_dev->priv;
+ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++ struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct hns_roce_qp *hr_qp;
++ struct ib_qp *qp;
+ int ret;
++
++ hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL);
++ if (ZERO_OR_NULL_PTR(hr_qp))
++ return -ENOMEM;
++
++ qp = &hr_qp->ibqp;
++ qp->device = ibdev;
++
++ ret = hns_roce_create_qp(qp, init_attr, NULL);
++ if (ret) {
++ ibdev_err(ibdev, "failed to create qp for free mr.\n");
++ kfree(hr_qp);
++ return ret;
++ }
++
++ free_mr->rsv_qp[i] = hr_qp;
++ free_mr->rsv_qp[i]->ibqp.recv_cq = cq;
++ free_mr->rsv_qp[i]->ibqp.send_cq = cq;
++
++ return 0;
++}
++
++static void free_mr_exit(struct hns_roce_dev *hr_dev)
++{
++ struct hns_roce_v2_priv *priv = hr_dev->priv;
++ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++ struct ib_qp *qp;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+ if (free_mr->rsv_qp[i]) {
+- ret = ib_destroy_qp(free_mr->rsv_qp[i]);
+- if (ret)
+- ibdev_err(&hr_dev->ib_dev,
+- "failed to destroy qp in free mr.\n");
+-
++ qp = &free_mr->rsv_qp[i]->ibqp;
++ hns_roce_v2_destroy_qp(qp, NULL);
++ kfree(free_mr->rsv_qp[i]);
+ free_mr->rsv_qp[i] = NULL;
+ }
+ }
+
+ if (free_mr->rsv_cq) {
+- ib_destroy_cq(free_mr->rsv_cq);
++ hns_roce_destroy_cq(&free_mr->rsv_cq->ib_cq, NULL);
++ kfree(free_mr->rsv_cq);
+ free_mr->rsv_cq = NULL;
+ }
+
+ if (free_mr->rsv_pd) {
+- ib_dealloc_pd(free_mr->rsv_pd);
++ hns_roce_dealloc_pd(&free_mr->rsv_pd->ibpd, NULL);
++ kfree(free_mr->rsv_pd);
+ free_mr->rsv_pd = NULL;
+ }
+ }
+@@ -2668,55 +2787,46 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev)
+ {
+ struct hns_roce_v2_priv *priv = hr_dev->priv;
+ struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
+- struct ib_device *ibdev = &hr_dev->ib_dev;
+- struct ib_cq_init_attr cq_init_attr = {};
+ struct ib_qp_init_attr qp_init_attr = {};
+ struct ib_pd *pd;
+ struct ib_cq *cq;
+- struct ib_qp *qp;
+ int ret;
+ int i;
+
+- pd = ib_alloc_pd(ibdev, 0);
+- if (IS_ERR(pd)) {
+- ibdev_err(ibdev, "failed to create pd for free mr.\n");
+- return PTR_ERR(pd);
+- }
+- free_mr->rsv_pd = pd;
++ pd = free_mr_init_pd(hr_dev);
++ if (!pd)
++ return -ENOMEM;
+
+- cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM;
+- cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_init_attr);
+- if (IS_ERR(cq)) {
+- ibdev_err(ibdev, "failed to create cq for free mr.\n");
+- ret = PTR_ERR(cq);
+- goto create_failed;
++ cq = free_mr_init_cq(hr_dev);
++ if (!cq) {
++ ret = -ENOMEM;
++ goto create_failed_cq;
+ }
+- free_mr->rsv_cq = cq;
+
+ qp_init_attr.qp_type = IB_QPT_RC;
+ qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
+- qp_init_attr.send_cq = free_mr->rsv_cq;
+- qp_init_attr.recv_cq = free_mr->rsv_cq;
++ qp_init_attr.send_cq = cq;
++ qp_init_attr.recv_cq = cq;
+ for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+ qp_init_attr.cap.max_send_wr = HNS_ROCE_FREE_MR_USED_SQWQE_NUM;
+ qp_init_attr.cap.max_send_sge = HNS_ROCE_FREE_MR_USED_SQSGE_NUM;
+ qp_init_attr.cap.max_recv_wr = HNS_ROCE_FREE_MR_USED_RQWQE_NUM;
+ qp_init_attr.cap.max_recv_sge = HNS_ROCE_FREE_MR_USED_RQSGE_NUM;
+
+- qp = ib_create_qp(free_mr->rsv_pd, &qp_init_attr);
+- if (IS_ERR(qp)) {
+- ibdev_err(ibdev, "failed to create qp for free mr.\n");
+- ret = PTR_ERR(qp);
+- goto create_failed;
+- }
+-
+- free_mr->rsv_qp[i] = qp;
++ ret = free_mr_init_qp(hr_dev, cq, &qp_init_attr, i);
++ if (ret)
++ goto create_failed_qp;
+ }
+
+ return 0;
+
+-create_failed:
+- free_mr_exit(hr_dev);
++create_failed_qp:
++ hns_roce_destroy_cq(cq, NULL);
++ kfree(cq);
++
++create_failed_cq:
++ hns_roce_dealloc_pd(pd, NULL);
++ kfree(pd);
+
+ return ret;
+ }
+@@ -2732,14 +2842,17 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ int mask;
+ int ret;
+
+- hr_qp = to_hr_qp(free_mr->rsv_qp[sl_num]);
++ hr_qp = to_hr_qp(&free_mr->rsv_qp[sl_num]->ibqp);
+ hr_qp->free_mr_en = 1;
++ hr_qp->ibqp.device = ibdev;
++ hr_qp->ibqp.qp_type = IB_QPT_RC;
+
+ mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS;
+ attr->qp_state = IB_QPS_INIT;
+ attr->port_num = 1;
+ attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE;
+- ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
++ IB_QPS_INIT);
+ if (ret) {
+ ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n",
+ ret);
+@@ -2760,7 +2873,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+
+ rdma_ah_set_sl(&attr->ah_attr, (u8)sl_num);
+
+- ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
++ IB_QPS_RTR);
+ hr_dev->loop_idc = loopback;
+ if (ret) {
+ ibdev_err(ibdev, "failed to modify qp to rtr, ret = %d.\n",
+@@ -2774,7 +2888,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ attr->sq_psn = HNS_ROCE_FREE_MR_USED_PSN;
+ attr->retry_cnt = HNS_ROCE_FREE_MR_USED_QP_RETRY_CNT;
+ attr->timeout = HNS_ROCE_FREE_MR_USED_QP_TIMEOUT;
+- ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_RTR,
++ IB_QPS_RTS);
+ if (ret)
+ ibdev_err(ibdev, "failed to modify qp to rts, ret = %d.\n",
+ ret);
+@@ -3190,7 +3305,8 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,
+ int i, count;
+
+ count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
+- ARRAY_SIZE(pages), &pbl_ba);
++ min_t(int, ARRAY_SIZE(pages), mr->npages),
++ &pbl_ba);
+ if (count < 1) {
+ ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
+ count);
+@@ -3418,7 +3534,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+ mutex_lock(&free_mr->mutex);
+
+ for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+- hr_qp = to_hr_qp(free_mr->rsv_qp[i]);
++ hr_qp = free_mr->rsv_qp[i];
+
+ ret = free_mr_post_send_lp_wqe(hr_qp);
+ if (ret) {
+@@ -3433,7 +3549,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+
+ end = msecs_to_jiffies(HNS_ROCE_V2_FREE_MR_TIMEOUT) + jiffies;
+ while (cqe_cnt) {
+- npolled = hns_roce_v2_poll_cq(free_mr->rsv_cq, cqe_cnt, wc);
++ 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",
+@@ -5383,6 +5499,8 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+
+ rdma_ah_set_sl(&qp_attr->ah_attr,
+ hr_reg_read(&context, QPC_SL));
++ rdma_ah_set_port_num(&qp_attr->ah_attr, hr_qp->port + 1);
++ rdma_ah_set_ah_flags(&qp_attr->ah_attr, IB_AH_GRH);
+ grh->flow_label = hr_reg_read(&context, QPC_FL);
+ grh->sgid_index = hr_reg_read(&context, QPC_GMV_IDX);
+ grh->hop_limit = hr_reg_read(&context, QPC_HOPLIMIT);
+@@ -5476,7 +5594,7 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
+ return ret;
+ }
+
+-static int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
++int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
+ {
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+@@ -5766,6 +5884,35 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+ return ret;
+ }
+
++static int hns_roce_v2_query_cqc(struct hns_roce_dev *hr_dev, u32 cqn,
++ void *buffer)
++{
++ struct hns_roce_v2_cq_context *context;
++ struct hns_roce_cmd_mailbox *mailbox;
++ int ret;
++
++ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
++ if (IS_ERR(mailbox))
++ return PTR_ERR(mailbox);
++
++ context = mailbox->buf;
++ 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);
++ goto err_mailbox;
++ }
++
++ memcpy(buffer, context, sizeof(*context));
++
++err_mailbox:
++ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
++
++ return ret;
++}
++
+ static void hns_roce_irq_work_handle(struct work_struct *work)
+ {
+ struct hns_roce_work *irq_work =
+@@ -6567,10 +6714,6 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
+ kfree(eq_table->eq);
+ }
+
+-static const struct hns_roce_dfx_hw hns_roce_dfx_hw_v2 = {
+- .query_cqc_info = hns_roce_v2_query_cqc_info,
+-};
+-
+ static const struct ib_device_ops hns_roce_v2_dev_ops = {
+ .destroy_qp = hns_roce_v2_destroy_qp,
+ .modify_cq = hns_roce_v2_modify_cq,
+@@ -6611,6 +6754,7 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
+ .init_eq = hns_roce_v2_init_eq_table,
+ .cleanup_eq = hns_roce_v2_cleanup_eq_table,
+ .write_srqc = hns_roce_v2_write_srqc,
++ .query_cqc = hns_roce_v2_query_cqc,
+ .hns_roce_dev_ops = &hns_roce_v2_dev_ops,
+ .hns_roce_dev_srq_ops = &hns_roce_v2_dev_srq_ops,
+ };
+@@ -6642,7 +6786,6 @@ static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
+ hr_dev->is_vf = id->driver_data;
+ hr_dev->dev = &handle->pdev->dev;
+ hr_dev->hw = &hns_roce_hw_v2;
+- hr_dev->dfx = &hns_roce_dfx_hw_v2;
+ hr_dev->sdb_offset = ROCEE_DB_SQ_L_0_REG;
+ hr_dev->odb_offset = hr_dev->sdb_offset;
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 4544a8775ce5a..4bf89c1280dc4 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -275,6 +275,11 @@ enum hns_roce_cmd_return_status {
+ CMD_OTHER_ERR = 0xff
+ };
+
++struct hns_roce_cmd_errcode {
++ enum hns_roce_cmd_return_status return_status;
++ int errno;
++};
++
+ enum hns_roce_sgid_type {
+ GID_TYPE_FLAG_ROCE_V1 = 0,
+ GID_TYPE_FLAG_ROCE_V2_IPV4,
+@@ -1328,9 +1333,9 @@ struct hns_roce_link_table {
+ #define HNS_ROCE_EXT_LLM_MIN_PAGES(que_num) ((que_num) * 4 + 2)
+
+ struct hns_roce_v2_free_mr {
+- struct ib_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM];
+- struct ib_cq *rsv_cq;
+- struct ib_pd *rsv_pd;
++ struct hns_roce_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM];
++ struct hns_roce_cq *rsv_cq;
++ struct hns_roce_pd *rsv_pd;
+ struct mutex mutex;
+ };
+
+@@ -1460,8 +1465,7 @@ struct hns_roce_sccc_clr_done {
+ __le32 rsv[5];
+ };
+
+-int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, u32 cqn,
+- int *buffer);
++int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
+
+ static inline void hns_roce_write64(struct hns_roce_dev *hr_dev, __le32 val[2],
+ void __iomem *dest)
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c
+deleted file mode 100644
+index f7a75a7cda749..0000000000000
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c
++++ /dev/null
+@@ -1,34 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+-// Copyright (c) 2019 Hisilicon Limited.
+-
+-#include "hnae3.h"
+-#include "hns_roce_device.h"
+-#include "hns_roce_cmd.h"
+-#include "hns_roce_hw_v2.h"
+-
+-int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, u32 cqn,
+- int *buffer)
+-{
+- struct hns_roce_v2_cq_context *cq_context;
+- struct hns_roce_cmd_mailbox *mailbox;
+- int ret;
+-
+- mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+- if (IS_ERR(mailbox))
+- return PTR_ERR(mailbox);
+-
+- cq_context = mailbox->buf;
+- ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_CQC,
+- cqn);
+- if (ret) {
+- dev_err(hr_dev->dev, "QUERY cqc cmd process error\n");
+- goto err_mailbox;
+- }
+-
+- memcpy(buffer, cq_context, sizeof(*cq_context));
+-
+-err_mailbox:
+- hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+-
+- return ret;
+-}
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 4ccb217b2841d..bf5c7729d7e84 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -354,10 +354,11 @@ static int hns_roce_alloc_uar_entry(struct ib_ucontext *uctx)
+ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
+ struct ib_udata *udata)
+ {
+- int ret;
+ struct hns_roce_ucontext *context = to_hr_ucontext(uctx);
+- struct hns_roce_ib_alloc_ucontext_resp resp = {};
+ struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device);
++ struct hns_roce_ib_alloc_ucontext_resp resp = {};
++ struct hns_roce_ib_alloc_ucontext ucmd = {};
++ int ret;
+
+ if (!hr_dev->active)
+ return -EAGAIN;
+@@ -365,6 +366,19 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
+ resp.qp_tab_size = hr_dev->caps.num_qps;
+ resp.srq_tab_size = hr_dev->caps.num_srqs;
+
++ ret = ib_copy_from_udata(&ucmd, udata,
++ min(udata->inlen, sizeof(ucmd)));
++ if (ret)
++ return ret;
++
++ if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
++ context->config = ucmd.config & HNS_ROCE_EXSGE_FLAGS;
++
++ if (context->config & HNS_ROCE_EXSGE_FLAGS) {
++ resp.config |= HNS_ROCE_RSP_EXSGE_FLAGS;
++ resp.max_inline_data = hr_dev->caps.max_sq_inline;
++ }
++
+ ret = hns_roce_uar_alloc(hr_dev, &context->uar);
+ if (ret)
+ goto error_fail_uar_alloc;
+@@ -515,7 +529,6 @@ static const struct ib_device_ops hns_roce_dev_ops = {
+ .destroy_ah = hns_roce_destroy_ah,
+ .destroy_cq = hns_roce_destroy_cq,
+ .disassociate_ucontext = hns_roce_disassociate_ucontext,
+- .fill_res_cq_entry = hns_roce_fill_res_cq_entry,
+ .get_dma_mr = hns_roce_get_dma_mr,
+ .get_link_layer = hns_roce_get_link_layer,
+ .get_port_immutable = hns_roce_port_immutable,
+@@ -566,6 +579,10 @@ static const struct ib_device_ops hns_roce_dev_xrcd_ops = {
+ INIT_RDMA_OBJ_SIZE(ib_xrcd, hns_roce_xrcd, ibxrcd),
+ };
+
++static const struct ib_device_ops hns_roce_dev_restrack_ops = {
++ .fill_res_cq_entry = hns_roce_fill_res_cq_entry,
++};
++
+ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+ {
+ int ret;
+@@ -605,6 +622,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+
+ ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_ops);
+ ib_set_device_ops(ib_dev, &hns_roce_dev_ops);
++ ib_set_device_ops(ib_dev, &hns_roce_dev_restrack_ops);
+ for (i = 0; i < hr_dev->caps.num_ports; i++) {
+ if (!hr_dev->iboe.netdevs[i])
+ continue;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index dedfa56f57731..fb165069c8d9d 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -392,10 +392,10 @@ struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+
+ return &mr->ibmr;
+
+-err_key:
+- free_mr_key(hr_dev, mr);
+ err_pbl:
+ free_mr_pbl(hr_dev, mr);
++err_key:
++ free_mr_key(hr_dev, mr);
+ err_free:
+ kfree(mr);
+ return ERR_PTR(ret);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index 7bee7f6c5e702..a0040096ddb1b 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -479,38 +479,109 @@ static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap,
+ return 0;
+ }
+
+-static u32 get_wqe_ext_sge_cnt(struct hns_roce_qp *qp)
++static u32 get_max_inline_data(struct hns_roce_dev *hr_dev,
++ struct ib_qp_cap *cap)
+ {
+- /* GSI/UD QP only has extended sge */
+- if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_UD)
+- return qp->sq.max_gs;
+-
+- if (qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE)
+- return qp->sq.max_gs - HNS_ROCE_SGE_IN_WQE;
++ if (cap->max_inline_data) {
++ cap->max_inline_data = roundup_pow_of_two(cap->max_inline_data);
++ return min(cap->max_inline_data,
++ hr_dev->caps.max_sq_inline);
++ }
+
+ return 0;
+ }
+
++static void update_inline_data(struct hns_roce_qp *hr_qp,
++ struct ib_qp_cap *cap)
++{
++ u32 sge_num = hr_qp->sq.ext_sge_cnt;
++
++ if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) {
++ if (!(hr_qp->ibqp.qp_type == IB_QPT_GSI ||
++ hr_qp->ibqp.qp_type == IB_QPT_UD))
++ sge_num = max((u32)HNS_ROCE_SGE_IN_WQE, sge_num);
++
++ cap->max_inline_data = max(cap->max_inline_data,
++ sge_num * HNS_ROCE_SGE_SIZE);
++ }
++
++ hr_qp->max_inline_data = cap->max_inline_data;
++}
++
++static u32 get_sge_num_from_max_send_sge(bool is_ud_or_gsi,
++ u32 max_send_sge)
++{
++ unsigned int std_sge_num;
++ unsigned int min_sge;
++
++ std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE;
++ min_sge = is_ud_or_gsi ? 1 : 0;
++ return max_send_sge > std_sge_num ? (max_send_sge - std_sge_num) :
++ min_sge;
++}
++
++static unsigned int get_sge_num_from_max_inl_data(bool is_ud_or_gsi,
++ u32 max_inline_data)
++{
++ unsigned int inline_sge;
++
++ inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
++
++ /*
++ * if max_inline_data less than
++ * HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE,
++ * In addition to ud's mode, no need to extend sge.
++ */
++ if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE)
++ inline_sge = 0;
++
++ return inline_sge;
++}
++
+ static void set_ext_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt,
+ struct hns_roce_qp *hr_qp, struct ib_qp_cap *cap)
+ {
++ bool is_ud_or_gsi = (hr_qp->ibqp.qp_type == IB_QPT_GSI ||
++ hr_qp->ibqp.qp_type == IB_QPT_UD);
++ unsigned int std_sge_num;
++ u32 inline_ext_sge = 0;
++ u32 ext_wqe_sge_cnt;
+ u32 total_sge_cnt;
+- u32 wqe_sge_cnt;
++
++ cap->max_inline_data = get_max_inline_data(hr_dev, cap);
+
+ hr_qp->sge.sge_shift = HNS_ROCE_SGE_SHIFT;
++ std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE;
++ ext_wqe_sge_cnt = get_sge_num_from_max_send_sge(is_ud_or_gsi,
++ cap->max_send_sge);
+
+- hr_qp->sq.max_gs = max(1U, cap->max_send_sge);
++ if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) {
++ inline_ext_sge = max(ext_wqe_sge_cnt,
++ get_sge_num_from_max_inl_data(is_ud_or_gsi,
++ cap->max_inline_data));
++ hr_qp->sq.ext_sge_cnt = inline_ext_sge ?
++ roundup_pow_of_two(inline_ext_sge) : 0;
+
+- wqe_sge_cnt = get_wqe_ext_sge_cnt(hr_qp);
++ hr_qp->sq.max_gs = max(1U, (hr_qp->sq.ext_sge_cnt + std_sge_num));
++ hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg);
++
++ ext_wqe_sge_cnt = hr_qp->sq.ext_sge_cnt;
++ } else {
++ hr_qp->sq.max_gs = max(1U, cap->max_send_sge);
++ hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg);
++ hr_qp->sq.ext_sge_cnt = hr_qp->sq.max_gs;
++ }
+
+ /* If the number of extended sge is not zero, they MUST use the
+ * space of HNS_HW_PAGE_SIZE at least.
+ */
+- if (wqe_sge_cnt) {
+- total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * wqe_sge_cnt);
++ if (ext_wqe_sge_cnt) {
++ total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * ext_wqe_sge_cnt);
+ hr_qp->sge.sge_cnt = max(total_sge_cnt,
+ (u32)HNS_HW_PAGE_SIZE / HNS_ROCE_SGE_SIZE);
+ }
++
++ update_inline_data(hr_qp, cap);
+ }
+
+ static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev,
+@@ -559,6 +630,7 @@ static int set_user_sq_size(struct hns_roce_dev *hr_dev,
+
+ hr_qp->sq.wqe_shift = ucmd->log_sq_stride;
+ hr_qp->sq.wqe_cnt = cnt;
++ cap->max_send_sge = hr_qp->sq.max_gs;
+
+ return 0;
+ }
+@@ -989,13 +1061,9 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
+ struct hns_roce_ib_create_qp *ucmd)
+ {
+ struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct hns_roce_ucontext *uctx;
+ int ret;
+
+- if (init_attr->cap.max_inline_data > hr_dev->caps.max_sq_inline)
+- init_attr->cap.max_inline_data = hr_dev->caps.max_sq_inline;
+-
+- hr_qp->max_inline_data = init_attr->cap.max_inline_data;
+-
+ if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
+ hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
+ else
+@@ -1018,12 +1086,17 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
+ return ret;
+ }
+
++ uctx = rdma_udata_to_drv_context(udata, struct hns_roce_ucontext,
++ ibucontext);
++ hr_qp->config = uctx->config;
+ ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd);
+ if (ret)
+ ibdev_err(ibdev,
+ "failed to set user SQ size, ret = %d.\n",
+ ret);
+ } else {
++ if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
++ hr_qp->config = HNS_ROCE_EXSGE_FLAGS;
+ ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp);
+ if (ret)
+ ibdev_err(ibdev,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_restrack.c b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+index 24a154d646304..83417be15d3fa 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_restrack.c
++++ b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+@@ -55,45 +55,34 @@ err:
+ return -EMSGSIZE;
+ }
+
+-int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
+- struct ib_cq *ib_cq)
++int hns_roce_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ib_cq)
+ {
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
+ struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
+- struct hns_roce_v2_cq_context *context;
++ struct hns_roce_v2_cq_context context;
+ struct nlattr *table_attr;
+ int ret;
+
+- if (!hr_dev->dfx->query_cqc_info)
++ if (!hr_dev->hw->query_cqc)
+ return -EINVAL;
+
+- context = kzalloc(sizeof(struct hns_roce_v2_cq_context), GFP_KERNEL);
+- if (!context)
+- return -ENOMEM;
+-
+- ret = hr_dev->dfx->query_cqc_info(hr_dev, hr_cq->cqn, (int *)context);
++ ret = hr_dev->hw->query_cqc(hr_dev, hr_cq->cqn, &context);
+ if (ret)
+- goto err;
++ return -EINVAL;
+
+ table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER);
+- if (!table_attr) {
+- ret = -EMSGSIZE;
+- goto err;
+- }
++ if (!table_attr)
++ return -EMSGSIZE;
+
+- if (hns_roce_fill_cq(msg, context)) {
+- ret = -EMSGSIZE;
+- goto err_cancel_table;
+- }
++ if (hns_roce_fill_cq(msg, &context))
++ goto err;
+
+ nla_nest_end(msg, table_attr);
+- kfree(context);
+
+ return 0;
+
+-err_cancel_table:
+- nla_nest_cancel(msg, table_attr);
+ err:
+- kfree(context);
+- return ret;
++ nla_nest_cancel(msg, table_attr);
++
++ return -EMSGSIZE;
+ }
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index a6e5d350a94ce..16183e894da77 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -566,21 +566,37 @@ static void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe,
+
+ /**
+ * irdma_copy_inline_data_gen_1 - Copy inline data to wqe
+- * @dest: pointer to wqe
+- * @src: pointer to inline data
+- * @len: length of inline data to copy
++ * @wqe: pointer to wqe
++ * @sge_list: table of pointers to inline data
++ * @num_sges: Total inline data length
+ * @polarity: compatibility parameter
+ */
+-static void irdma_copy_inline_data_gen_1(u8 *dest, u8 *src, u32 len,
+- u8 polarity)
++static void irdma_copy_inline_data_gen_1(u8 *wqe, struct ib_sge *sge_list,
++ u32 num_sges, u8 polarity)
+ {
+- if (len <= 16) {
+- memcpy(dest, src, len);
+- } else {
+- memcpy(dest, src, 16);
+- src += 16;
+- dest = dest + 32;
+- memcpy(dest, src, len - 16);
++ u32 quanta_bytes_remaining = 16;
++ int i;
++
++ for (i = 0; i < num_sges; i++) {
++ u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
++ u32 sge_len = sge_list[i].length;
++
++ while (sge_len) {
++ u32 bytes_copied;
++
++ bytes_copied = min(sge_len, quanta_bytes_remaining);
++ memcpy(wqe, cur_sge, bytes_copied);
++ wqe += bytes_copied;
++ cur_sge += bytes_copied;
++ quanta_bytes_remaining -= bytes_copied;
++ sge_len -= bytes_copied;
++
++ if (!quanta_bytes_remaining) {
++ /* Remaining inline bytes reside after hdr */
++ wqe += 16;
++ quanta_bytes_remaining = 32;
++ }
++ }
+ }
+ }
+
+@@ -612,35 +628,51 @@ static void irdma_set_mw_bind_wqe(__le64 *wqe,
+
+ /**
+ * irdma_copy_inline_data - Copy inline data to wqe
+- * @dest: pointer to wqe
+- * @src: pointer to inline data
+- * @len: length of inline data to copy
++ * @wqe: pointer to wqe
++ * @sge_list: table of pointers to inline data
++ * @num_sges: number of SGE's
+ * @polarity: polarity of wqe valid bit
+ */
+-static void irdma_copy_inline_data(u8 *dest, u8 *src, u32 len, u8 polarity)
++static void irdma_copy_inline_data(u8 *wqe, struct ib_sge *sge_list,
++ u32 num_sges, u8 polarity)
+ {
+ u8 inline_valid = polarity << IRDMA_INLINE_VALID_S;
+- u32 copy_size;
+-
+- dest += 8;
+- if (len <= 8) {
+- memcpy(dest, src, len);
+- return;
+- }
+-
+- *((u64 *)dest) = *((u64 *)src);
+- len -= 8;
+- src += 8;
+- dest += 24; /* point to additional 32 byte quanta */
+-
+- while (len) {
+- copy_size = len < 31 ? len : 31;
+- memcpy(dest, src, copy_size);
+- *(dest + 31) = inline_valid;
+- len -= copy_size;
+- dest += 32;
+- src += copy_size;
++ u32 quanta_bytes_remaining = 8;
++ bool first_quanta = true;
++ int i;
++
++ wqe += 8;
++
++ for (i = 0; i < num_sges; i++) {
++ u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
++ u32 sge_len = sge_list[i].length;
++
++ while (sge_len) {
++ u32 bytes_copied;
++
++ bytes_copied = min(sge_len, quanta_bytes_remaining);
++ memcpy(wqe, cur_sge, bytes_copied);
++ wqe += bytes_copied;
++ cur_sge += bytes_copied;
++ quanta_bytes_remaining -= bytes_copied;
++ sge_len -= bytes_copied;
++
++ if (!quanta_bytes_remaining) {
++ quanta_bytes_remaining = 31;
++
++ /* Remaining inline bytes reside after hdr */
++ if (first_quanta) {
++ first_quanta = false;
++ wqe += 16;
++ } else {
++ *wqe = inline_valid;
++ wqe++;
++ }
++ }
++ }
+ }
++ if (!first_quanta && quanta_bytes_remaining < 31)
++ *(wqe + quanta_bytes_remaining) = inline_valid;
+ }
+
+ /**
+@@ -679,20 +711,27 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+ struct irdma_post_sq_info *info, bool post_sq)
+ {
+ __le64 *wqe;
+- struct irdma_inline_rdma_write *op_info;
++ struct irdma_rdma_write *op_info;
+ u64 hdr = 0;
+ u32 wqe_idx;
+ bool read_fence = false;
++ u32 i, total_size = 0;
+ u16 quanta;
+
+ info->push_wqe = qp->push_db ? true : false;
+- op_info = &info->op.inline_rdma_write;
++ op_info = &info->op.rdma_write;
++
++ if (unlikely(qp->max_sq_frag_cnt < op_info->num_lo_sges))
++ return -EINVAL;
++
++ for (i = 0; i < op_info->num_lo_sges; i++)
++ total_size += op_info->lo_sg_list[i].length;
+
+- if (op_info->len > qp->max_inline_data)
++ if (unlikely(total_size > qp->max_inline_data))
+ return -EINVAL;
+
+- quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
+- wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
++ quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
++ wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
+ info);
+ if (!wqe)
+ return -ENOMEM;
+@@ -705,7 +744,7 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+
+ hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
+ FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
+- FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
++ FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
+ FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) |
+ FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
+ FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) |
+@@ -719,7 +758,8 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+ set_64bit_val(wqe, 0,
+ FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
+
+- qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
++ qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->lo_sg_list,
++ op_info->num_lo_sges,
+ qp->swqe_polarity);
+ dma_wmb(); /* make sure WQE is populated before valid bit is set */
+
+@@ -745,20 +785,27 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ struct irdma_post_sq_info *info, bool post_sq)
+ {
+ __le64 *wqe;
+- struct irdma_post_inline_send *op_info;
++ struct irdma_post_send *op_info;
+ u64 hdr;
+ u32 wqe_idx;
+ bool read_fence = false;
++ u32 i, total_size = 0;
+ u16 quanta;
+
+ info->push_wqe = qp->push_db ? true : false;
+- op_info = &info->op.inline_send;
++ op_info = &info->op.send;
++
++ if (unlikely(qp->max_sq_frag_cnt < op_info->num_sges))
++ return -EINVAL;
+
+- if (op_info->len > qp->max_inline_data)
++ for (i = 0; i < op_info->num_sges; i++)
++ total_size += op_info->sg_list[i].length;
++
++ if (unlikely(total_size > qp->max_inline_data))
+ return -EINVAL;
+
+- quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
+- wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
++ quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
++ wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
+ info);
+ if (!wqe)
+ return -ENOMEM;
+@@ -773,7 +820,7 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
+ FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
+ FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
+- FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
++ FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
+ FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
+ (info->imm_data_valid ? 1 : 0)) |
+ FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
+@@ -789,8 +836,8 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ if (info->imm_data_valid)
+ set_64bit_val(wqe, 0,
+ FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
+- qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
+- qp->swqe_polarity);
++ qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->sg_list,
++ op_info->num_sges, qp->swqe_polarity);
+
+ dma_wmb(); /* make sure WQE is populated before valid bit is set */
+
+@@ -1002,11 +1049,10 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ __le64 *cqe;
+ struct irdma_qp_uk *qp;
+ struct irdma_ring *pring = NULL;
+- u32 wqe_idx, q_type;
++ u32 wqe_idx;
+ int ret_code;
+ bool move_cq_head = true;
+ u8 polarity;
+- u8 op_type;
+ bool ext_valid;
+ __le64 *ext_cqe;
+
+@@ -1074,7 +1120,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ info->ud_vlan_valid = false;
+ }
+
+- q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
++ info->q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
+ info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3);
+ info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3);
+ info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3);
+@@ -1113,8 +1159,9 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ }
+ wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
+ info->qp_handle = (irdma_qp_handle)(unsigned long)qp;
++ info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
+
+- if (q_type == IRDMA_CQE_QTYPE_RQ) {
++ if (info->q_type == IRDMA_CQE_QTYPE_RQ) {
+ u32 array_idx;
+
+ array_idx = wqe_idx / qp->rq_wqe_size_multiplier;
+@@ -1134,10 +1181,6 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+
+ info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0);
+
+- if (info->imm_valid)
+- info->op_type = IRDMA_OP_TYPE_REC_IMM;
+- else
+- info->op_type = IRDMA_OP_TYPE_REC;
+ if (qword3 & IRDMACQ_STAG) {
+ info->stag_invalid_set = true;
+ info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2);
+@@ -1195,17 +1238,18 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ sw_wqe = qp->sq_base[tail].elem;
+ get_64bit_val(sw_wqe, 24,
+ &wqe_qword);
+- op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
+- info->op_type = op_type;
++ info->op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE,
++ wqe_qword);
+ IRDMA_RING_SET_TAIL(qp->sq_ring,
+ tail + qp->sq_wrtrk_array[tail].quanta);
+- if (op_type != IRDMAQP_OP_NOP) {
++ if (info->op_type != IRDMAQP_OP_NOP) {
+ info->wr_id = qp->sq_wrtrk_array[tail].wrid;
+ info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len;
+ break;
+ }
+ } while (1);
+- if (op_type == IRDMA_OP_TYPE_BIND_MW && info->minor_err == FLUSH_PROT_ERR)
++ if (info->op_type == IRDMA_OP_TYPE_BIND_MW &&
++ info->minor_err == FLUSH_PROT_ERR)
+ info->minor_err = FLUSH_MW_BIND_ERR;
+ qp->sq_flush_seen = true;
+ if (!IRDMA_RING_MORE_WORK(qp->sq_ring))
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index 2ef61923c9268..d0cdf609f5e06 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -173,14 +173,6 @@ struct irdma_post_send {
+ u32 ah_id;
+ };
+
+-struct irdma_post_inline_send {
+- void *data;
+- u32 len;
+- u32 qkey;
+- u32 dest_qp;
+- u32 ah_id;
+-};
+-
+ struct irdma_post_rq_info {
+ u64 wr_id;
+ struct ib_sge *sg_list;
+@@ -193,12 +185,6 @@ struct irdma_rdma_write {
+ struct ib_sge rem_addr;
+ };
+
+-struct irdma_inline_rdma_write {
+- void *data;
+- u32 len;
+- struct ib_sge rem_addr;
+-};
+-
+ struct irdma_rdma_read {
+ struct ib_sge *lo_sg_list;
+ u32 num_lo_sges;
+@@ -241,8 +227,6 @@ struct irdma_post_sq_info {
+ struct irdma_rdma_read rdma_read;
+ struct irdma_bind_window bind_window;
+ struct irdma_inv_local_stag inv_local_stag;
+- struct irdma_inline_rdma_write inline_rdma_write;
+- struct irdma_post_inline_send inline_send;
+ } op;
+ };
+
+@@ -261,6 +245,7 @@ struct irdma_cq_poll_info {
+ u16 ud_vlan;
+ u8 ud_smac[6];
+ u8 op_type;
++ u8 q_type;
+ bool stag_invalid_set:1; /* or L_R_Key set */
+ bool push_dropped:1;
+ bool error:1;
+@@ -291,7 +276,8 @@ int irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp,
+ bool post_sq);
+
+ struct irdma_wqe_uk_ops {
+- void (*iw_copy_inline_data)(u8 *dest, u8 *src, u32 len, u8 polarity);
++ void (*iw_copy_inline_data)(u8 *dest, struct ib_sge *sge_list,
++ u32 num_sges, u8 polarity);
+ u16 (*iw_inline_data_size_to_quanta)(u32 data_size);
+ void (*iw_set_fragment)(__le64 *wqe, u32 offset, struct ib_sge *sge,
+ u8 valid);
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 8dfc9e154d733..445e69e864097 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -2591,6 +2591,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
+ sw_wqe = qp->sq_base[wqe_idx].elem;
+ get_64bit_val(sw_wqe, 24, &wqe_qword);
+ cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, IRDMAQPSQ_OPCODE);
++ cmpl->cpi.q_type = IRDMA_CQE_QTYPE_SQ;
+ /* remove the SQ WR by moving SQ tail*/
+ IRDMA_RING_SET_TAIL(*sq_ring,
+ sq_ring->tail + qp->sq_wrtrk_array[sq_ring->tail].quanta);
+@@ -2629,6 +2630,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
+
+ cmpl->cpi.wr_id = qp->rq_wrid_array[wqe_idx];
+ cmpl->cpi.op_type = IRDMA_OP_TYPE_REC;
++ cmpl->cpi.q_type = IRDMA_CQE_QTYPE_RQ;
+ /* remove the RQ WR by moving RQ tail */
+ IRDMA_RING_SET_TAIL(*rq_ring, rq_ring->tail + 1);
+ ibdev_dbg(iwqp->iwrcq->ibcq.device,
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index a22afbb25bc58..f6973ea55eda7 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -63,36 +63,6 @@ static int irdma_query_device(struct ib_device *ibdev,
+ return 0;
+ }
+
+-/**
+- * irdma_get_eth_speed_and_width - Get IB port speed and width from netdev speed
+- * @link_speed: netdev phy link speed
+- * @active_speed: IB port speed
+- * @active_width: IB port width
+- */
+-static void irdma_get_eth_speed_and_width(u32 link_speed, u16 *active_speed,
+- u8 *active_width)
+-{
+- if (link_speed <= SPEED_1000) {
+- *active_width = IB_WIDTH_1X;
+- *active_speed = IB_SPEED_SDR;
+- } else if (link_speed <= SPEED_10000) {
+- *active_width = IB_WIDTH_1X;
+- *active_speed = IB_SPEED_FDR10;
+- } else if (link_speed <= SPEED_20000) {
+- *active_width = IB_WIDTH_4X;
+- *active_speed = IB_SPEED_DDR;
+- } else if (link_speed <= SPEED_25000) {
+- *active_width = IB_WIDTH_1X;
+- *active_speed = IB_SPEED_EDR;
+- } else if (link_speed <= SPEED_40000) {
+- *active_width = IB_WIDTH_4X;
+- *active_speed = IB_SPEED_FDR10;
+- } else {
+- *active_width = IB_WIDTH_4X;
+- *active_speed = IB_SPEED_EDR;
+- }
+-}
+-
+ /**
+ * irdma_query_port - get port attributes
+ * @ibdev: device pointer from stack
+@@ -120,8 +90,9 @@ static int irdma_query_port(struct ib_device *ibdev, u32 port,
+ props->state = IB_PORT_DOWN;
+ props->phys_state = IB_PORT_PHYS_STATE_DISABLED;
+ }
+- irdma_get_eth_speed_and_width(SPEED_100000, &props->active_speed,
+- &props->active_width);
++
++ ib_get_eth_speed(ibdev, port, &props->active_speed,
++ &props->active_width);
+
+ if (rdma_protocol_roce(ibdev, 1)) {
+ props->gid_tbl_len = 32;
+@@ -1242,6 +1213,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ av->attrs = attr->ah_attr;
+ rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid);
+ rdma_gid2ip((struct sockaddr *)&av->dgid_addr, &attr->ah_attr.grh.dgid);
++ av->net_type = rdma_gid_attr_network_type(sgid_attr);
+ if (av->net_type == RDMA_NETWORK_IPV6) {
+ __be32 *daddr =
+ av->dgid_addr.saddr_in6.sin6_addr.in6_u.u6_addr32;
+@@ -2358,9 +2330,10 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+ * @rf: RDMA PCI function
+ * @iwmr: mr pointer for this memory registration
+ * @use_pbles: flag if to use pble's
++ * @lvl_1_only: request only level 1 pble if true
+ */
+ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+- bool use_pbles)
++ bool use_pbles, bool lvl_1_only)
+ {
+ struct irdma_pbl *iwpbl = &iwmr->iwpbl;
+ struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc;
+@@ -2371,7 +2344,7 @@ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+
+ if (use_pbles) {
+ status = irdma_get_pble(rf->pble_rsrc, palloc, iwmr->page_cnt,
+- false);
++ lvl_1_only);
+ if (status)
+ return status;
+
+@@ -2414,16 +2387,10 @@ static int irdma_handle_q_mem(struct irdma_device *iwdev,
+ bool ret = true;
+
+ pg_size = iwmr->page_size;
+- err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++ err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, true);
+ if (err)
+ return err;
+
+- if (use_pbles && palloc->level != PBLE_LEVEL_1) {
+- irdma_free_pble(iwdev->rf->pble_rsrc, palloc);
+- iwpbl->pbl_allocated = false;
+- return -ENOMEM;
+- }
+-
+ if (use_pbles)
+ arr = palloc->level1.addr;
+
+@@ -2899,7 +2866,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ case IRDMA_MEMREG_TYPE_MEM:
+ use_pbles = (iwmr->page_cnt != 1);
+
+- err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++ err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, false);
+ if (err)
+ goto error;
+
+@@ -3165,30 +3132,20 @@ static int irdma_post_send(struct ib_qp *ibqp,
+ info.stag_to_inv = ib_wr->ex.invalidate_rkey;
+ }
+
+- if (ib_wr->send_flags & IB_SEND_INLINE) {
+- info.op.inline_send.data = (void *)(unsigned long)
+- ib_wr->sg_list[0].addr;
+- info.op.inline_send.len = ib_wr->sg_list[0].length;
+- if (iwqp->ibqp.qp_type == IB_QPT_UD ||
+- iwqp->ibqp.qp_type == IB_QPT_GSI) {
+- ah = to_iwah(ud_wr(ib_wr)->ah);
+- info.op.inline_send.ah_id = ah->sc_ah.ah_info.ah_idx;
+- info.op.inline_send.qkey = ud_wr(ib_wr)->remote_qkey;
+- info.op.inline_send.dest_qp = ud_wr(ib_wr)->remote_qpn;
+- }
++ info.op.send.num_sges = ib_wr->num_sge;
++ info.op.send.sg_list = ib_wr->sg_list;
++ if (iwqp->ibqp.qp_type == IB_QPT_UD ||
++ iwqp->ibqp.qp_type == IB_QPT_GSI) {
++ ah = to_iwah(ud_wr(ib_wr)->ah);
++ info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx;
++ info.op.send.qkey = ud_wr(ib_wr)->remote_qkey;
++ info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn;
++ }
++
++ if (ib_wr->send_flags & IB_SEND_INLINE)
+ err = irdma_uk_inline_send(ukqp, &info, false);
+- } else {
+- info.op.send.num_sges = ib_wr->num_sge;
+- info.op.send.sg_list = ib_wr->sg_list;
+- if (iwqp->ibqp.qp_type == IB_QPT_UD ||
+- iwqp->ibqp.qp_type == IB_QPT_GSI) {
+- ah = to_iwah(ud_wr(ib_wr)->ah);
+- info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx;
+- info.op.send.qkey = ud_wr(ib_wr)->remote_qkey;
+- info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn;
+- }
++ else
+ err = irdma_uk_send(ukqp, &info, false);
+- }
+ break;
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ if (ukqp->qp_caps & IRDMA_WRITE_WITH_IMM) {
+@@ -3205,22 +3162,15 @@ static int irdma_post_send(struct ib_qp *ibqp,
+ else
+ info.op_type = IRDMA_OP_TYPE_RDMA_WRITE;
+
+- if (ib_wr->send_flags & IB_SEND_INLINE) {
+- info.op.inline_rdma_write.data = (void *)(uintptr_t)ib_wr->sg_list[0].addr;
+- info.op.inline_rdma_write.len =
+- ib_wr->sg_list[0].length;
+- info.op.inline_rdma_write.rem_addr.addr =
+- rdma_wr(ib_wr)->remote_addr;
+- info.op.inline_rdma_write.rem_addr.lkey =
+- rdma_wr(ib_wr)->rkey;
++ info.op.rdma_write.num_lo_sges = ib_wr->num_sge;
++ info.op.rdma_write.lo_sg_list = ib_wr->sg_list;
++ info.op.rdma_write.rem_addr.addr =
++ rdma_wr(ib_wr)->remote_addr;
++ info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey;
++ if (ib_wr->send_flags & IB_SEND_INLINE)
+ err = irdma_uk_inline_rdma_write(ukqp, &info, false);
+- } else {
+- info.op.rdma_write.lo_sg_list = (void *)ib_wr->sg_list;
+- info.op.rdma_write.num_lo_sges = ib_wr->num_sge;
+- info.op.rdma_write.rem_addr.addr = rdma_wr(ib_wr)->remote_addr;
+- info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey;
++ else
+ err = irdma_uk_rdma_write(ukqp, &info, false);
+- }
+ break;
+ case IB_WR_RDMA_READ_WITH_INV:
+ inv_stag = true;
+@@ -3380,7 +3330,6 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode
+ static void irdma_process_cqe(struct ib_wc *entry,
+ struct irdma_cq_poll_info *cq_poll_info)
+ {
+- struct irdma_qp *iwqp;
+ struct irdma_sc_qp *qp;
+
+ entry->wc_flags = 0;
+@@ -3388,7 +3337,6 @@ static void irdma_process_cqe(struct ib_wc *entry,
+ entry->wr_id = cq_poll_info->wr_id;
+
+ qp = cq_poll_info->qp_handle;
+- iwqp = qp->qp_uk.back_qp;
+ entry->qp = qp->qp_uk.back_qp;
+
+ if (cq_poll_info->error) {
+@@ -3421,42 +3369,17 @@ static void irdma_process_cqe(struct ib_wc *entry,
+ }
+ }
+
+- switch (cq_poll_info->op_type) {
+- case IRDMA_OP_TYPE_RDMA_WRITE:
+- case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
+- entry->opcode = IB_WC_RDMA_WRITE;
+- break;
+- case IRDMA_OP_TYPE_RDMA_READ_INV_STAG:
+- case IRDMA_OP_TYPE_RDMA_READ:
+- entry->opcode = IB_WC_RDMA_READ;
+- break;
+- case IRDMA_OP_TYPE_SEND_INV:
+- case IRDMA_OP_TYPE_SEND_SOL:
+- case IRDMA_OP_TYPE_SEND_SOL_INV:
+- case IRDMA_OP_TYPE_SEND:
+- entry->opcode = IB_WC_SEND;
+- break;
+- case IRDMA_OP_TYPE_FAST_REG_NSMR:
+- entry->opcode = IB_WC_REG_MR;
+- break;
+- case IRDMA_OP_TYPE_INV_STAG:
+- entry->opcode = IB_WC_LOCAL_INV;
+- break;
+- case IRDMA_OP_TYPE_REC_IMM:
+- case IRDMA_OP_TYPE_REC:
+- entry->opcode = cq_poll_info->op_type == IRDMA_OP_TYPE_REC_IMM ?
+- IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV;
++ if (cq_poll_info->q_type == IRDMA_CQE_QTYPE_SQ) {
++ set_ib_wc_op_sq(cq_poll_info, entry);
++ } else {
++ set_ib_wc_op_rq(cq_poll_info, entry,
++ qp->qp_uk.qp_caps & IRDMA_SEND_WITH_IMM ?
++ true : false);
+ if (qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_UD &&
+ cq_poll_info->stag_invalid_set) {
+ entry->ex.invalidate_rkey = cq_poll_info->inv_stag;
+ entry->wc_flags |= IB_WC_WITH_INVALIDATE;
+ }
+- break;
+- default:
+- ibdev_err(&iwqp->iwdev->ibdev,
+- "Invalid opcode = %d in CQE\n", cq_poll_info->op_type);
+- entry->status = IB_WC_GENERAL_ERR;
+- return;
+ }
+
+ if (qp->qp_uk.qp_type == IRDMA_QP_TYPE_ROCE_UD) {
+diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h
+index 4309b7159f42c..a536e9fa85ebf 100644
+--- a/drivers/infiniband/hw/irdma/verbs.h
++++ b/drivers/infiniband/hw/irdma/verbs.h
+@@ -232,6 +232,59 @@ static inline u16 irdma_fw_minor_ver(struct irdma_sc_dev *dev)
+ return (u16)FIELD_GET(IRDMA_FW_VER_MINOR, dev->feature_info[IRDMA_FEATURE_FW_INFO]);
+ }
+
++static inline void set_ib_wc_op_sq(struct irdma_cq_poll_info *cq_poll_info,
++ struct ib_wc *entry)
++{
++ switch (cq_poll_info->op_type) {
++ case IRDMA_OP_TYPE_RDMA_WRITE:
++ case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
++ entry->opcode = IB_WC_RDMA_WRITE;
++ break;
++ case IRDMA_OP_TYPE_RDMA_READ_INV_STAG:
++ case IRDMA_OP_TYPE_RDMA_READ:
++ entry->opcode = IB_WC_RDMA_READ;
++ break;
++ case IRDMA_OP_TYPE_SEND_SOL:
++ case IRDMA_OP_TYPE_SEND_SOL_INV:
++ case IRDMA_OP_TYPE_SEND_INV:
++ case IRDMA_OP_TYPE_SEND:
++ entry->opcode = IB_WC_SEND;
++ break;
++ case IRDMA_OP_TYPE_FAST_REG_NSMR:
++ entry->opcode = IB_WC_REG_MR;
++ break;
++ case IRDMA_OP_TYPE_INV_STAG:
++ entry->opcode = IB_WC_LOCAL_INV;
++ break;
++ default:
++ entry->status = IB_WC_GENERAL_ERR;
++ }
++}
++
++static inline void set_ib_wc_op_rq(struct irdma_cq_poll_info *cq_poll_info,
++ struct ib_wc *entry, bool send_imm_support)
++{
++ /**
++ * iWARP does not support sendImm, so the presence of Imm data
++ * must be WriteImm.
++ */
++ if (!send_imm_support) {
++ entry->opcode = cq_poll_info->imm_valid ?
++ IB_WC_RECV_RDMA_WITH_IMM :
++ IB_WC_RECV;
++ return;
++ }
++
++ switch (cq_poll_info->op_type) {
++ case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE:
++ case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE:
++ entry->opcode = IB_WC_RECV_RDMA_WITH_IMM;
++ break;
++ default:
++ entry->opcode = IB_WC_RECV;
++ }
++}
++
+ void irdma_mcast_mac(u32 *ip_addr, u8 *mac, bool ipv4);
+ int irdma_ib_register_device(struct irdma_device *iwdev);
+ void irdma_ib_unregister_device(struct irdma_device *iwdev);
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index af34f198e6456..8cd6f1b165d55 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -99,6 +99,7 @@ err2:
+ kfree(mr->map[i]);
+
+ kfree(mr->map);
++ mr->map = NULL;
+ err1:
+ return -ENOMEM;
+ }
+@@ -122,7 +123,6 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ int num_buf;
+ void *vaddr;
+ int err;
+- int i;
+
+ umem = ib_umem_get(&rxe->ib_dev, start, length, access);
+ if (IS_ERR(umem)) {
+@@ -163,9 +163,8 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ pr_warn("%s: Unable to get virtual address\n",
+ __func__);
+ err = -ENOMEM;
+- goto err_cleanup_map;
++ goto err_release_umem;
+ }
+-
+ buf->addr = (uintptr_t)vaddr;
+ buf->size = PAGE_SIZE;
+ num_buf++;
+@@ -185,10 +184,6 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+
+ return 0;
+
+-err_cleanup_map:
+- for (i = 0; i < mr->num_map; i++)
+- kfree(mr->map[i]);
+- kfree(mr->map);
+ err_release_umem:
+ ib_umem_release(umem);
+ err_out:
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index d776dfda43b16..e9c573fe71553 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -830,12 +830,12 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+ if (qp->resp.mr)
+ rxe_put(qp->resp.mr);
+
+- if (qp_type(qp) == IB_QPT_RC)
+- sk_dst_reset(qp->sk->sk);
+-
+ free_rd_atomic_resources(qp);
+
+ if (qp->sk) {
++ if (qp_type(qp) == IB_QPT_RC)
++ sk_dst_reset(qp->sk->sk);
++
+ kernel_sock_shutdown(qp->sk, SHUT_RDWR);
+ sock_release(qp->sk);
+ }
+diff --git a/drivers/infiniband/sw/siw/siw_cq.c b/drivers/infiniband/sw/siw/siw_cq.c
+index d68e37859e73b..403029de6b92d 100644
+--- a/drivers/infiniband/sw/siw/siw_cq.c
++++ b/drivers/infiniband/sw/siw/siw_cq.c
+@@ -56,8 +56,6 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+ if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) {
+ memset(wc, 0, sizeof(*wc));
+ wc->wr_id = cqe->id;
+- wc->status = map_cqe_status[cqe->status].ib;
+- wc->opcode = map_wc_opcode[cqe->opcode];
+ wc->byte_len = cqe->bytes;
+
+ /*
+@@ -71,10 +69,32 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+ wc->wc_flags = IB_WC_WITH_INVALIDATE;
+ }
+ wc->qp = cqe->base_qp;
++ wc->opcode = map_wc_opcode[cqe->opcode];
++ wc->status = map_cqe_status[cqe->status].ib;
+ siw_dbg_cq(cq,
+ "idx %u, type %d, flags %2x, id 0x%pK\n",
+ cq->cq_get % cq->num_cqe, cqe->opcode,
+ cqe->flags, (void *)(uintptr_t)cqe->id);
++ } else {
++ /*
++ * A malicious user may set invalid opcode or
++ * status in the user mmapped CQE array.
++ * Sanity check and correct values in that case
++ * to avoid out-of-bounds access to global arrays
++ * for opcode and status mapping.
++ */
++ u8 opcode = cqe->opcode;
++ u16 status = cqe->status;
++
++ if (opcode >= SIW_NUM_OPCODES) {
++ opcode = 0;
++ status = SIW_WC_GENERAL_ERR;
++ } else if (status >= SIW_NUM_WC_STATUS) {
++ status = SIW_WC_GENERAL_ERR;
++ }
++ wc->opcode = map_wc_opcode[opcode];
++ wc->status = map_cqe_status[status].ib;
++
+ }
+ WRITE_ONCE(cqe->flags, 0);
+ cq->cq_get++;
+diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
+index 7d47b521070b1..05052b49107f2 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
+@@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx)
+ dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
+
+ if (paddr)
+- return virt_to_page((void *)paddr);
++ return virt_to_page((void *)(uintptr_t)paddr);
+
+ return NULL;
+ }
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 3e814cfb298cf..906fde1a2a0de 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -676,13 +676,45 @@ static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr,
+ static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+ {
+- struct siw_sqe sqe = {};
+ int rv = 0;
+
+ while (wr) {
+- sqe.id = wr->wr_id;
+- sqe.opcode = wr->opcode;
+- rv = siw_sqe_complete(qp, &sqe, 0, SIW_WC_WR_FLUSH_ERR);
++ struct siw_sqe sqe = {};
++
++ switch (wr->opcode) {
++ case IB_WR_RDMA_WRITE:
++ sqe.opcode = SIW_OP_WRITE;
++ break;
++ case IB_WR_RDMA_READ:
++ sqe.opcode = SIW_OP_READ;
++ break;
++ case IB_WR_RDMA_READ_WITH_INV:
++ sqe.opcode = SIW_OP_READ_LOCAL_INV;
++ break;
++ case IB_WR_SEND:
++ sqe.opcode = SIW_OP_SEND;
++ break;
++ case IB_WR_SEND_WITH_IMM:
++ sqe.opcode = SIW_OP_SEND_WITH_IMM;
++ break;
++ case IB_WR_SEND_WITH_INV:
++ sqe.opcode = SIW_OP_SEND_REMOTE_INV;
++ break;
++ case IB_WR_LOCAL_INV:
++ sqe.opcode = SIW_OP_INVAL_STAG;
++ break;
++ case IB_WR_REG_MR:
++ sqe.opcode = SIW_OP_REG_MR;
++ break;
++ default:
++ rv = -EINVAL;
++ break;
++ }
++ if (!rv) {
++ sqe.id = wr->wr_id;
++ rv = siw_sqe_complete(qp, &sqe, 0,
++ SIW_WC_WR_FLUSH_ERR);
++ }
+ if (rv) {
+ if (bad_wr)
+ *bad_wr = wr;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+index ea16ba5d8da6c..9ad8d98562752 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+@@ -41,6 +41,11 @@ static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
+ [IFLA_IPOIB_UMCAST] = { .type = NLA_U16 },
+ };
+
++static unsigned int ipoib_get_max_num_queues(void)
++{
++ return min_t(unsigned int, num_possible_cpus(), 128);
++}
++
+ static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ {
+ struct ipoib_dev_priv *priv = ipoib_priv(dev);
+@@ -172,6 +177,8 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
+ .changelink = ipoib_changelink,
+ .get_size = ipoib_get_size,
+ .fill_info = ipoib_fill_info,
++ .get_num_rx_queues = ipoib_get_max_num_queues,
++ .get_num_tx_queues = ipoib_get_max_num_queues,
+ };
+
+ struct rtnl_link_ops *ipoib_get_link_ops(void)
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 9c9872868aeea..4f5e49393c854 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -3405,7 +3405,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_PKEY:
+- if (match_hex(args, &token)) {
++ ret = match_hex(args, &token);
++ if (ret) {
+ pr_warn("bad P_Key parameter '%s'\n", p);
+ goto out;
+ }
+@@ -3465,7 +3466,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_MAX_SECT:
+- if (match_int(args, &token)) {
++ ret = match_int(args, &token);
++ if (ret) {
+ pr_warn("bad max sect parameter '%s'\n", p);
+ goto out;
+ }
+@@ -3473,8 +3475,15 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_QUEUE_SIZE:
+- if (match_int(args, &token) || token < 1) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for queue_size parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1) {
+ pr_warn("bad queue_size parameter '%s'\n", p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->scsi_host->can_queue = token;
+@@ -3485,25 +3494,40 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_MAX_CMD_PER_LUN:
+- if (match_int(args, &token) || token < 1) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for max cmd_per_lun parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1) {
+ pr_warn("bad max cmd_per_lun parameter '%s'\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->scsi_host->cmd_per_lun = token;
+ break;
+
+ case SRP_OPT_TARGET_CAN_QUEUE:
+- if (match_int(args, &token) || token < 1) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for max target_can_queue parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1) {
+ pr_warn("bad max target_can_queue parameter '%s'\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->target_can_queue = token;
+ break;
+
+ case SRP_OPT_IO_CLASS:
+- if (match_hex(args, &token)) {
++ ret = match_hex(args, &token);
++ if (ret) {
+ pr_warn("bad IO class parameter '%s'\n", p);
+ goto out;
+ }
+@@ -3512,6 +3536,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+ pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n",
+ token, SRP_REV10_IB_IO_CLASS,
+ SRP_REV16A_IB_IO_CLASS);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->io_class = token;
+@@ -3534,16 +3559,24 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_CMD_SG_ENTRIES:
+- if (match_int(args, &token) || token < 1 || token > 255) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for max cmd_sg_entries parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1 || token > 255) {
+ pr_warn("bad max cmd_sg_entries parameter '%s'\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->cmd_sg_cnt = token;
+ break;
+
+ case SRP_OPT_ALLOW_EXT_SG:
+- if (match_int(args, &token)) {
++ ret = match_int(args, &token);
++ if (ret) {
+ pr_warn("bad allow_ext_sg parameter '%s'\n", p);
+ goto out;
+ }
+@@ -3551,43 +3584,77 @@ static int srp_parse_options(struct net *net, const char *buf,
+ break;
+
+ case SRP_OPT_SG_TABLESIZE:
+- if (match_int(args, &token) || token < 1 ||
+- token > SG_MAX_SEGMENTS) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for max sg_tablesize parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1 || token > SG_MAX_SEGMENTS) {
+ pr_warn("bad max sg_tablesize parameter '%s'\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->sg_tablesize = token;
+ break;
+
+ case SRP_OPT_COMP_VECTOR:
+- if (match_int(args, &token) || token < 0) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for comp_vector parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 0) {
+ pr_warn("bad comp_vector parameter '%s'\n", p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->comp_vector = token;
+ break;
+
+ case SRP_OPT_TL_RETRY_COUNT:
+- if (match_int(args, &token) || token < 2 || token > 7) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for tl_retry_count parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 2 || token > 7) {
+ pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->tl_retry_count = token;
+ break;
+
+ case SRP_OPT_MAX_IT_IU_SIZE:
+- if (match_int(args, &token) || token < 0) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for max it_iu_size parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 0) {
+ pr_warn("bad maximum initiator to target IU size '%s'\n", p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->max_it_iu_size = token;
+ break;
+
+ case SRP_OPT_CH_COUNT:
+- if (match_int(args, &token) || token < 1) {
++ ret = match_int(args, &token);
++ if (ret) {
++ pr_warn("match_int() failed for channel count parameter '%s', Error %d\n",
++ p, ret);
++ goto out;
++ }
++ if (token < 1) {
+ pr_warn("bad channel count %s\n", p);
++ ret = -EINVAL;
+ goto out;
+ }
+ target->ch_count = token;
+@@ -3596,6 +3663,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+ default:
+ pr_warn("unknown parameter or missing value '%s' in target creation request\n",
+ p);
++ ret = -EINVAL;
+ goto out;
+ }
+ }
+diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
+index 9dcf3f51f2dd9..04ca3d1c28162 100644
+--- a/drivers/input/joystick/Kconfig
++++ b/drivers/input/joystick/Kconfig
+@@ -46,6 +46,7 @@ config JOYSTICK_A3D
+ config JOYSTICK_ADC
+ tristate "Simple joystick connected over ADC"
+ depends on IIO
++ select IIO_BUFFER
+ select IIO_BUFFER_CB
+ help
+ Say Y here if you have a simple joystick connected over ADC.
+diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
+index a18ab7358d8f3..54c116e56e9d0 100644
+--- a/drivers/input/misc/Kconfig
++++ b/drivers/input/misc/Kconfig
+@@ -330,7 +330,7 @@ config INPUT_CPCAP_PWRBUTTON
+
+ config INPUT_WISTRON_BTNS
+ tristate "x86 Wistron laptop button interface"
+- depends on X86_32
++ depends on X86_32 && !UML
+ select INPUT_SPARSEKMAP
+ select NEW_LEDS
+ select LEDS_CLASS
+diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c
+index b2e8097a2e6d9..e47ab6c1177f5 100644
+--- a/drivers/input/misc/iqs7222.c
++++ b/drivers/input/misc/iqs7222.c
+@@ -86,7 +86,9 @@ enum iqs7222_reg_key_id {
+ IQS7222_REG_KEY_TOUCH,
+ IQS7222_REG_KEY_DEBOUNCE,
+ IQS7222_REG_KEY_TAP,
++ IQS7222_REG_KEY_TAP_LEGACY,
+ IQS7222_REG_KEY_AXIAL,
++ IQS7222_REG_KEY_AXIAL_LEGACY,
+ IQS7222_REG_KEY_WHEEL,
+ IQS7222_REG_KEY_NO_WHEEL,
+ IQS7222_REG_KEY_RESERVED
+@@ -105,14 +107,14 @@ enum iqs7222_reg_grp_id {
+ IQS7222_NUM_REG_GRPS
+ };
+
+-static const char * const iqs7222_reg_grp_names[] = {
++static const char * const iqs7222_reg_grp_names[IQS7222_NUM_REG_GRPS] = {
+ [IQS7222_REG_GRP_CYCLE] = "cycle",
+ [IQS7222_REG_GRP_CHAN] = "channel",
+ [IQS7222_REG_GRP_SLDR] = "slider",
+ [IQS7222_REG_GRP_GPIO] = "gpio",
+ };
+
+-static const unsigned int iqs7222_max_cols[] = {
++static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = {
+ [IQS7222_REG_GRP_STAT] = IQS7222_MAX_COLS_STAT,
+ [IQS7222_REG_GRP_CYCLE] = IQS7222_MAX_COLS_CYCLE,
+ [IQS7222_REG_GRP_GLBL] = IQS7222_MAX_COLS_GLBL,
+@@ -202,10 +204,68 @@ struct iqs7222_dev_desc {
+ int allow_offset;
+ int event_offset;
+ int comms_offset;
++ bool legacy_gesture;
+ struct iqs7222_reg_grp_desc reg_grps[IQS7222_NUM_REG_GRPS];
+ };
+
+ static const struct iqs7222_dev_desc iqs7222_devs[] = {
++ {
++ .prod_num = IQS7222_PROD_NUM_A,
++ .fw_major = 1,
++ .fw_minor = 13,
++ .sldr_res = U8_MAX * 16,
++ .touch_link = 1768,
++ .allow_offset = 9,
++ .event_offset = 10,
++ .comms_offset = 12,
++ .reg_grps = {
++ [IQS7222_REG_GRP_STAT] = {
++ .base = IQS7222_SYS_STATUS,
++ .num_row = 1,
++ .num_col = 8,
++ },
++ [IQS7222_REG_GRP_CYCLE] = {
++ .base = 0x8000,
++ .num_row = 7,
++ .num_col = 3,
++ },
++ [IQS7222_REG_GRP_GLBL] = {
++ .base = 0x8700,
++ .num_row = 1,
++ .num_col = 3,
++ },
++ [IQS7222_REG_GRP_BTN] = {
++ .base = 0x9000,
++ .num_row = 12,
++ .num_col = 3,
++ },
++ [IQS7222_REG_GRP_CHAN] = {
++ .base = 0xA000,
++ .num_row = 12,
++ .num_col = 6,
++ },
++ [IQS7222_REG_GRP_FILT] = {
++ .base = 0xAC00,
++ .num_row = 1,
++ .num_col = 2,
++ },
++ [IQS7222_REG_GRP_SLDR] = {
++ .base = 0xB000,
++ .num_row = 2,
++ .num_col = 11,
++ },
++ [IQS7222_REG_GRP_GPIO] = {
++ .base = 0xC000,
++ .num_row = 1,
++ .num_col = 3,
++ },
++ [IQS7222_REG_GRP_SYS] = {
++ .base = IQS7222_SYS_SETUP,
++ .num_row = 1,
++ .num_col = 13,
++ },
++ },
++ },
+ {
+ .prod_num = IQS7222_PROD_NUM_A,
+ .fw_major = 1,
+@@ -215,6 +275,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
+ .allow_offset = 9,
+ .event_offset = 10,
+ .comms_offset = 12,
++ .legacy_gesture = true,
+ .reg_grps = {
+ [IQS7222_REG_GRP_STAT] = {
+ .base = IQS7222_SYS_STATUS,
+@@ -874,6 +935,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ .reg_offset = 9,
+ .reg_shift = 8,
+ .reg_width = 8,
++ .val_pitch = 16,
++ .label = "maximum gesture time",
++ },
++ {
++ .name = "azoteq,gesture-max-ms",
++ .reg_grp = IQS7222_REG_GRP_SLDR,
++ .reg_key = IQS7222_REG_KEY_TAP_LEGACY,
++ .reg_offset = 9,
++ .reg_shift = 8,
++ .reg_width = 8,
+ .val_pitch = 4,
+ .label = "maximum gesture time",
+ },
+@@ -884,6 +955,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ .reg_offset = 9,
+ .reg_shift = 3,
+ .reg_width = 5,
++ .val_pitch = 16,
++ .label = "minimum gesture time",
++ },
++ {
++ .name = "azoteq,gesture-min-ms",
++ .reg_grp = IQS7222_REG_GRP_SLDR,
++ .reg_key = IQS7222_REG_KEY_TAP_LEGACY,
++ .reg_offset = 9,
++ .reg_shift = 3,
++ .reg_width = 5,
+ .val_pitch = 4,
+ .label = "minimum gesture time",
+ },
+@@ -897,6 +978,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ .val_pitch = 16,
+ .label = "gesture distance",
+ },
++ {
++ .name = "azoteq,gesture-dist",
++ .reg_grp = IQS7222_REG_GRP_SLDR,
++ .reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
++ .reg_offset = 10,
++ .reg_shift = 8,
++ .reg_width = 8,
++ .val_pitch = 16,
++ .label = "gesture distance",
++ },
+ {
+ .name = "azoteq,gesture-max-ms",
+ .reg_grp = IQS7222_REG_GRP_SLDR,
+@@ -904,6 +995,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ .reg_offset = 10,
+ .reg_shift = 0,
+ .reg_width = 8,
++ .val_pitch = 16,
++ .label = "maximum gesture time",
++ },
++ {
++ .name = "azoteq,gesture-max-ms",
++ .reg_grp = IQS7222_REG_GRP_SLDR,
++ .reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
++ .reg_offset = 10,
++ .reg_shift = 0,
++ .reg_width = 8,
+ .val_pitch = 4,
+ .label = "maximum gesture time",
+ },
+@@ -1077,7 +1178,7 @@ static int iqs7222_hard_reset(struct iqs7222_private *iqs7222)
+
+ static int iqs7222_force_comms(struct iqs7222_private *iqs7222)
+ {
+- u8 msg_buf[] = { 0xFF, 0x00, };
++ u8 msg_buf[] = { 0xFF, };
+ int ret;
+
+ /*
+@@ -1567,56 +1668,17 @@ static int iqs7222_gpio_select(struct iqs7222_private *iqs7222,
+ }
+
+ static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
+- struct fwnode_handle **child_node,
+- int child_index,
++ struct fwnode_handle *reg_grp_node,
++ int reg_grp_index,
+ enum iqs7222_reg_grp_id reg_grp,
+ enum iqs7222_reg_key_id reg_key)
+ {
+- u16 *setup = iqs7222_setup(iqs7222, reg_grp, child_index);
++ u16 *setup = iqs7222_setup(iqs7222, reg_grp, reg_grp_index);
+ struct i2c_client *client = iqs7222->client;
+- struct fwnode_handle *reg_grp_node;
+- char reg_grp_name[16];
+ int i;
+
+- switch (reg_grp) {
+- case IQS7222_REG_GRP_CYCLE:
+- case IQS7222_REG_GRP_CHAN:
+- case IQS7222_REG_GRP_SLDR:
+- case IQS7222_REG_GRP_GPIO:
+- case IQS7222_REG_GRP_BTN:
+- /*
+- * These groups derive a child node and return it to the caller
+- * for additional group-specific processing. In some cases, the
+- * child node may have already been derived.
+- */
+- reg_grp_node = *child_node;
+- if (reg_grp_node)
+- break;
+-
+- snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
+- iqs7222_reg_grp_names[reg_grp], child_index);
+-
+- reg_grp_node = device_get_named_child_node(&client->dev,
+- reg_grp_name);
+- if (!reg_grp_node)
+- return 0;
+-
+- *child_node = reg_grp_node;
+- break;
+-
+- case IQS7222_REG_GRP_GLBL:
+- case IQS7222_REG_GRP_FILT:
+- case IQS7222_REG_GRP_SYS:
+- /*
+- * These groups are not organized beneath a child node, nor are
+- * they subject to any additional processing by the caller.
+- */
+- reg_grp_node = dev_fwnode(&client->dev);
+- break;
+-
+- default:
+- return -EINVAL;
+- }
++ if (!setup)
++ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(iqs7222_props); i++) {
+ const char *name = iqs7222_props[i].name;
+@@ -1686,11 +1748,66 @@ static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
+ return 0;
+ }
+
+-static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
++static int iqs7222_parse_event(struct iqs7222_private *iqs7222,
++ struct fwnode_handle *event_node,
++ int reg_grp_index,
++ enum iqs7222_reg_grp_id reg_grp,
++ enum iqs7222_reg_key_id reg_key,
++ u16 event_enable, u16 event_link,
++ unsigned int *event_type,
++ unsigned int *event_code)
++{
++ struct i2c_client *client = iqs7222->client;
++ int error;
++
++ error = iqs7222_parse_props(iqs7222, event_node, reg_grp_index,
++ reg_grp, reg_key);
++ if (error)
++ return error;
++
++ error = iqs7222_gpio_select(iqs7222, event_node, event_enable,
++ event_link);
++ if (error)
++ return error;
++
++ error = fwnode_property_read_u32(event_node, "linux,code", event_code);
++ if (error == -EINVAL) {
++ return 0;
++ } else if (error) {
++ dev_err(&client->dev, "Failed to read %s code: %d\n",
++ fwnode_get_name(event_node), error);
++ return error;
++ }
++
++ if (!event_type) {
++ input_set_capability(iqs7222->keypad, EV_KEY, *event_code);
++ return 0;
++ }
++
++ error = fwnode_property_read_u32(event_node, "linux,input-type",
++ event_type);
++ if (error == -EINVAL) {
++ *event_type = EV_KEY;
++ } else if (error) {
++ dev_err(&client->dev, "Failed to read %s input type: %d\n",
++ fwnode_get_name(event_node), error);
++ return error;
++ } else if (*event_type != EV_KEY && *event_type != EV_SW) {
++ dev_err(&client->dev, "Invalid %s input type: %d\n",
++ fwnode_get_name(event_node), *event_type);
++ return -EINVAL;
++ }
++
++ input_set_capability(iqs7222->keypad, *event_type, *event_code);
++
++ return 0;
++}
++
++static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222,
++ struct fwnode_handle *cycle_node, int cycle_index)
+ {
+ u16 *cycle_setup = iqs7222->cycle_setup[cycle_index];
+ struct i2c_client *client = iqs7222->client;
+- struct fwnode_handle *cycle_node = NULL;
+ unsigned int pins[9];
+ int error, count, i;
+
+@@ -1698,17 +1815,7 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
+ * Each channel shares a cycle with one other channel; the mapping of
+ * channels to cycles is fixed. Properties defined for a cycle impact
+ * both channels tied to the cycle.
+- */
+- error = iqs7222_parse_props(iqs7222, &cycle_node, cycle_index,
+- IQS7222_REG_GRP_CYCLE,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+- if (!cycle_node)
+- return 0;
+-
+- /*
++ *
+ * Unlike channels which are restricted to a select range of CRx pins
+ * based on channel number, any cycle can claim any of the device's 9
+ * CTx pins (CTx0-8).
+@@ -1750,11 +1857,11 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
+ return 0;
+ }
+
+-static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
++static int iqs7222_parse_chan(struct iqs7222_private *iqs7222,
++ struct fwnode_handle *chan_node, int chan_index)
+ {
+ const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ struct i2c_client *client = iqs7222->client;
+- struct fwnode_handle *chan_node = NULL;
+ int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
+ int ext_chan = rounddown(num_chan, 10);
+ int error, i;
+@@ -1762,20 +1869,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ u16 *sys_setup = iqs7222->sys_setup;
+ unsigned int val;
+
+- error = iqs7222_parse_props(iqs7222, &chan_node, chan_index,
+- IQS7222_REG_GRP_CHAN,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+- if (!chan_node)
+- return 0;
+-
+- if (dev_desc->allow_offset) {
+- sys_setup[dev_desc->allow_offset] |= BIT(chan_index);
+- if (fwnode_property_present(chan_node, "azoteq,ulp-allow"))
+- sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index);
+- }
++ if (dev_desc->allow_offset &&
++ fwnode_property_present(chan_node, "azoteq,ulp-allow"))
++ sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index);
+
+ chan_setup[0] |= IQS7222_CHAN_SETUP_0_CHAN_EN;
+
+@@ -1812,8 +1908,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ chan_setup[0] |= IQS7222_CHAN_SETUP_0_REF_MODE_FOLLOW;
+ chan_setup[4] = val * 42 + 1048;
+
+- if (!fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
+- &val)) {
++ error = fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
++ &val);
++ if (!error) {
+ if (val > U16_MAX) {
+ dev_err(&client->dev,
+ "Invalid %s reference weight: %u\n",
+@@ -1822,6 +1919,11 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ }
+
+ chan_setup[5] = val;
++ } else if (error != -EINVAL) {
++ dev_err(&client->dev,
++ "Failed to read %s reference weight: %d\n",
++ fwnode_get_name(chan_node), error);
++ return error;
+ }
+
+ /*
+@@ -1894,21 +1996,10 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ if (!event_node)
+ continue;
+
+- error = iqs7222_parse_props(iqs7222, &event_node, chan_index,
+- IQS7222_REG_GRP_BTN,
+- iqs7222_kp_events[i].reg_key);
+- if (error)
+- return error;
+-
+- error = iqs7222_gpio_select(iqs7222, event_node,
+- BIT(chan_index),
+- dev_desc->touch_link - (i ? 0 : 2));
+- if (error)
+- return error;
+-
+- if (!fwnode_property_read_u32(event_node,
+- "azoteq,timeout-press-ms",
+- &val)) {
++ error = fwnode_property_read_u32(event_node,
++ "azoteq,timeout-press-ms",
++ &val);
++ if (!error) {
+ /*
+ * The IQS7222B employs a global pair of press timeout
+ * registers as opposed to channel-specific registers.
+@@ -1921,57 +2012,31 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ if (val > U8_MAX * 500) {
+ dev_err(&client->dev,
+ "Invalid %s press timeout: %u\n",
+- fwnode_get_name(chan_node), val);
++ fwnode_get_name(event_node), val);
++ fwnode_handle_put(event_node);
+ return -EINVAL;
+ }
+
+ *setup &= ~(U8_MAX << i * 8);
+ *setup |= (val / 500 << i * 8);
+- }
+-
+- error = fwnode_property_read_u32(event_node, "linux,code",
+- &val);
+- if (error) {
+- dev_err(&client->dev, "Failed to read %s code: %d\n",
+- fwnode_get_name(chan_node), error);
++ } else if (error != -EINVAL) {
++ dev_err(&client->dev,
++ "Failed to read %s press timeout: %d\n",
++ fwnode_get_name(event_node), error);
++ fwnode_handle_put(event_node);
+ return error;
+ }
+
+- iqs7222->kp_code[chan_index][i] = val;
+- iqs7222->kp_type[chan_index][i] = EV_KEY;
+-
+- if (fwnode_property_present(event_node, "linux,input-type")) {
+- error = fwnode_property_read_u32(event_node,
+- "linux,input-type",
+- &val);
+- if (error) {
+- dev_err(&client->dev,
+- "Failed to read %s input type: %d\n",
+- fwnode_get_name(chan_node), error);
+- return error;
+- }
+-
+- if (val != EV_KEY && val != EV_SW) {
+- dev_err(&client->dev,
+- "Invalid %s input type: %u\n",
+- fwnode_get_name(chan_node), val);
+- return -EINVAL;
+- }
+-
+- iqs7222->kp_type[chan_index][i] = val;
+- }
+-
+- /*
+- * Reference channels can opt out of event reporting by using
+- * KEY_RESERVED in place of a true key or switch code.
+- */
+- if (iqs7222->kp_type[chan_index][i] == EV_KEY &&
+- iqs7222->kp_code[chan_index][i] == KEY_RESERVED)
+- continue;
+-
+- input_set_capability(iqs7222->keypad,
+- iqs7222->kp_type[chan_index][i],
+- iqs7222->kp_code[chan_index][i]);
++ error = iqs7222_parse_event(iqs7222, event_node, chan_index,
++ IQS7222_REG_GRP_BTN,
++ iqs7222_kp_events[i].reg_key,
++ BIT(chan_index),
++ dev_desc->touch_link - (i ? 0 : 2),
++ &iqs7222->kp_type[chan_index][i],
++ &iqs7222->kp_code[chan_index][i]);
++ fwnode_handle_put(event_node);
++ if (error)
++ return error;
+
+ if (!dev_desc->event_offset)
+ continue;
+@@ -1983,16 +2048,16 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ * The following call handles a special pair of properties that apply
+ * to a channel node, but reside within the button (event) group.
+ */
+- return iqs7222_parse_props(iqs7222, &chan_node, chan_index,
++ return iqs7222_parse_props(iqs7222, chan_node, chan_index,
+ IQS7222_REG_GRP_BTN,
+ IQS7222_REG_KEY_DEBOUNCE);
+ }
+
+-static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
++static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222,
++ struct fwnode_handle *sldr_node, int sldr_index)
+ {
+ const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ struct i2c_client *client = iqs7222->client;
+- struct fwnode_handle *sldr_node = NULL;
+ int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
+ int ext_chan = rounddown(num_chan, 10);
+ int count, error, reg_offset, i;
+@@ -2000,15 +2065,6 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ u16 *sldr_setup = iqs7222->sldr_setup[sldr_index];
+ unsigned int chan_sel[4], val;
+
+- error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
+- IQS7222_REG_GRP_SLDR,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+- if (!sldr_node)
+- return 0;
+-
+ /*
+ * Each slider can be spread across 3 to 4 channels. It is possible to
+ * select only 2 channels, but doing so prevents the slider from using
+@@ -2067,8 +2123,9 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ if (fwnode_property_present(sldr_node, "azoteq,use-prox"))
+ sldr_setup[4 + reg_offset] -= 2;
+
+- if (!fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val)) {
+- if (!val || val > dev_desc->sldr_res) {
++ error = fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val);
++ if (!error) {
++ if (val > dev_desc->sldr_res) {
+ dev_err(&client->dev, "Invalid %s size: %u\n",
+ fwnode_get_name(sldr_node), val);
+ return -EINVAL;
+@@ -2081,9 +2138,21 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ sldr_setup[2] |= (val / 16 <<
+ IQS7222_SLDR_SETUP_2_RES_SHIFT);
+ }
++ } else if (error != -EINVAL) {
++ dev_err(&client->dev, "Failed to read %s size: %d\n",
++ fwnode_get_name(sldr_node), error);
++ return error;
++ }
++
++ if (!(reg_offset ? sldr_setup[3]
++ : sldr_setup[2] & IQS7222_SLDR_SETUP_2_RES_MASK)) {
++ dev_err(&client->dev, "Undefined %s size\n",
++ fwnode_get_name(sldr_node));
++ return -EINVAL;
+ }
+
+- if (!fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val)) {
++ error = fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val);
++ if (!error) {
+ if (val > (reg_offset ? U16_MAX : U8_MAX * 4)) {
+ dev_err(&client->dev, "Invalid %s top speed: %u\n",
+ fwnode_get_name(sldr_node), val);
+@@ -2096,9 +2165,14 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ sldr_setup[2] &= ~IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK;
+ sldr_setup[2] |= (val / 4);
+ }
++ } else if (error != -EINVAL) {
++ dev_err(&client->dev, "Failed to read %s top speed: %d\n",
++ fwnode_get_name(sldr_node), error);
++ return error;
+ }
+
+- if (!fwnode_property_read_u32(sldr_node, "linux,axis", &val)) {
++ error = fwnode_property_read_u32(sldr_node, "linux,axis", &val);
++ if (!error) {
+ u16 sldr_max = sldr_setup[3] - 1;
+
+ if (!reg_offset) {
+@@ -2112,6 +2186,10 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+
+ input_set_abs_params(iqs7222->keypad, val, 0, sldr_max, 0, 0);
+ iqs7222->sl_axis[sldr_index] = val;
++ } else if (error != -EINVAL) {
++ dev_err(&client->dev, "Failed to read %s axis: %d\n",
++ fwnode_get_name(sldr_node), error);
++ return error;
+ }
+
+ if (dev_desc->wheel_enable) {
+@@ -2132,46 +2210,47 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++) {
+ const char *event_name = iqs7222_sl_events[i].name;
+ struct fwnode_handle *event_node;
++ enum iqs7222_reg_key_id reg_key;
+
+ event_node = fwnode_get_named_child_node(sldr_node, event_name);
+ if (!event_node)
+ continue;
+
+- error = iqs7222_parse_props(iqs7222, &event_node, sldr_index,
+- IQS7222_REG_GRP_SLDR,
+- reg_offset ?
+- IQS7222_REG_KEY_RESERVED :
+- iqs7222_sl_events[i].reg_key);
+- if (error)
+- return error;
++ /*
++ * Depending on the device, gestures are either offered using
++ * one of two timing resolutions, or are not supported at all.
++ */
++ if (reg_offset)
++ reg_key = IQS7222_REG_KEY_RESERVED;
++ else if (dev_desc->legacy_gesture &&
++ iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_TAP)
++ reg_key = IQS7222_REG_KEY_TAP_LEGACY;
++ else if (dev_desc->legacy_gesture &&
++ iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_AXIAL)
++ reg_key = IQS7222_REG_KEY_AXIAL_LEGACY;
++ else
++ reg_key = iqs7222_sl_events[i].reg_key;
+
+ /*
+ * The press/release event does not expose a direct GPIO link,
+ * but one can be emulated by tying each of the participating
+ * channels to the same GPIO.
+ */
+- error = iqs7222_gpio_select(iqs7222, event_node,
++ error = iqs7222_parse_event(iqs7222, event_node, sldr_index,
++ IQS7222_REG_GRP_SLDR, reg_key,
+ i ? iqs7222_sl_events[i].enable
+ : sldr_setup[3 + reg_offset],
+ i ? 1568 + sldr_index * 30
+- : sldr_setup[4 + reg_offset]);
++ : sldr_setup[4 + reg_offset],
++ NULL,
++ &iqs7222->sl_code[sldr_index][i]);
++ fwnode_handle_put(event_node);
+ if (error)
+ return error;
+
+ if (!reg_offset)
+ sldr_setup[9] |= iqs7222_sl_events[i].enable;
+
+- error = fwnode_property_read_u32(event_node, "linux,code",
+- &val);
+- if (error) {
+- dev_err(&client->dev, "Failed to read %s code: %d\n",
+- fwnode_get_name(sldr_node), error);
+- return error;
+- }
+-
+- iqs7222->sl_code[sldr_index][i] = val;
+- input_set_capability(iqs7222->keypad, EV_KEY, val);
+-
+ if (!dev_desc->event_offset)
+ continue;
+
+@@ -2192,49 +2271,77 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ * The following call handles a special pair of properties that shift
+ * to make room for a wheel enable control in the case of IQS7222C.
+ */
+- return iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
++ return iqs7222_parse_props(iqs7222, sldr_node, sldr_index,
+ IQS7222_REG_GRP_SLDR,
+ dev_desc->wheel_enable ?
+ IQS7222_REG_KEY_WHEEL :
+ IQS7222_REG_KEY_NO_WHEEL);
+ }
+
++static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS])
++ (struct iqs7222_private *iqs7222,
++ struct fwnode_handle *reg_grp_node,
++ int reg_grp_index) = {
++ [IQS7222_REG_GRP_CYCLE] = iqs7222_parse_cycle,
++ [IQS7222_REG_GRP_CHAN] = iqs7222_parse_chan,
++ [IQS7222_REG_GRP_SLDR] = iqs7222_parse_sldr,
++};
++
++static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222,
++ enum iqs7222_reg_grp_id reg_grp,
++ int reg_grp_index)
++{
++ struct i2c_client *client = iqs7222->client;
++ struct fwnode_handle *reg_grp_node;
++ int error;
++
++ if (iqs7222_reg_grp_names[reg_grp]) {
++ char reg_grp_name[16];
++
++ snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
++ iqs7222_reg_grp_names[reg_grp], reg_grp_index);
++
++ reg_grp_node = device_get_named_child_node(&client->dev,
++ reg_grp_name);
++ } else {
++ reg_grp_node = fwnode_handle_get(dev_fwnode(&client->dev));
++ }
++
++ if (!reg_grp_node)
++ return 0;
++
++ error = iqs7222_parse_props(iqs7222, reg_grp_node, reg_grp_index,
++ reg_grp, IQS7222_REG_KEY_NONE);
++
++ if (!error && iqs7222_parse_extra[reg_grp])
++ error = iqs7222_parse_extra[reg_grp](iqs7222, reg_grp_node,
++ reg_grp_index);
++
++ fwnode_handle_put(reg_grp_node);
++
++ return error;
++}
++
+ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
+ {
+ const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ const struct iqs7222_reg_grp_desc *reg_grps = dev_desc->reg_grps;
+ u16 *sys_setup = iqs7222->sys_setup;
+- int error, i;
++ int error, i, j;
++
++ if (dev_desc->allow_offset)
++ sys_setup[dev_desc->allow_offset] = U16_MAX;
+
+ if (dev_desc->event_offset)
+ sys_setup[dev_desc->event_offset] = IQS7222_EVENT_MASK_ATI;
+
+- for (i = 0; i < reg_grps[IQS7222_REG_GRP_CYCLE].num_row; i++) {
+- error = iqs7222_parse_cycle(iqs7222, i);
+- if (error)
+- return error;
+- }
+-
+- error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_GLBL,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+ for (i = 0; i < reg_grps[IQS7222_REG_GRP_GPIO].num_row; i++) {
+- struct fwnode_handle *gpio_node = NULL;
+ u16 *gpio_setup = iqs7222->gpio_setup[i];
+- int j;
+
+ gpio_setup[0] &= ~IQS7222_GPIO_SETUP_0_GPIO_EN;
+ gpio_setup[1] = 0;
+ gpio_setup[2] = 0;
+
+- error = iqs7222_parse_props(iqs7222, &gpio_node, i,
+- IQS7222_REG_GRP_GPIO,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+ if (reg_grps[IQS7222_REG_GRP_GPIO].num_row == 1)
+ continue;
+
+@@ -2257,29 +2364,21 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
+ chan_setup[5] = 0;
+ }
+
+- for (i = 0; i < reg_grps[IQS7222_REG_GRP_CHAN].num_row; i++) {
+- error = iqs7222_parse_chan(iqs7222, i);
+- if (error)
+- return error;
+- }
+-
+- error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_FILT,
+- IQS7222_REG_KEY_NONE);
+- if (error)
+- return error;
+-
+ for (i = 0; i < reg_grps[IQS7222_REG_GRP_SLDR].num_row; i++) {
+ u16 *sldr_setup = iqs7222->sldr_setup[i];
+
+ sldr_setup[0] &= ~IQS7222_SLDR_SETUP_0_CHAN_CNT_MASK;
++ }
+
+- error = iqs7222_parse_sldr(iqs7222, i);
+- if (error)
+- return error;
++ for (i = 0; i < IQS7222_NUM_REG_GRPS; i++) {
++ for (j = 0; j < reg_grps[i].num_row; j++) {
++ error = iqs7222_parse_reg_grp(iqs7222, i, j);
++ if (error)
++ return error;
++ }
+ }
+
+- return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
+- IQS7222_REG_KEY_NONE);
++ return 0;
+ }
+
+ static int iqs7222_report(struct iqs7222_private *iqs7222)
+@@ -2326,6 +2425,9 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
+ int k = 2 + j * (num_chan > 16 ? 2 : 1);
+ u16 state = le16_to_cpu(status[k + i / 16]);
+
++ if (!iqs7222->kp_type[i][j])
++ continue;
++
+ input_event(iqs7222->keypad,
+ iqs7222->kp_type[i][j],
+ iqs7222->kp_code[i][j],
+diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
+index 879a4d984c907..e1308e179dd6f 100644
+--- a/drivers/input/touchscreen/elants_i2c.c
++++ b/drivers/input/touchscreen/elants_i2c.c
+@@ -1329,14 +1329,12 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ if (IS_ERR_OR_NULL(ts->reset_gpio))
+ return 0;
+
+- gpiod_set_value_cansleep(ts->reset_gpio, 1);
+-
+ error = regulator_enable(ts->vcc33);
+ if (error) {
+ dev_err(&ts->client->dev,
+ "failed to enable vcc33 regulator: %d\n",
+ error);
+- goto release_reset_gpio;
++ return error;
+ }
+
+ error = regulator_enable(ts->vccio);
+@@ -1345,7 +1343,7 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ "failed to enable vccio regulator: %d\n",
+ error);
+ regulator_disable(ts->vcc33);
+- goto release_reset_gpio;
++ return error;
+ }
+
+ /*
+@@ -1354,7 +1352,6 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ */
+ udelay(ELAN_POWERON_DELAY_USEC);
+
+-release_reset_gpio:
+ gpiod_set_value_cansleep(ts->reset_gpio, 0);
+ if (error)
+ return error;
+@@ -1462,7 +1459,7 @@ static int elants_i2c_probe(struct i2c_client *client)
+ return error;
+ }
+
+- ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
++ ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ts->reset_gpio)) {
+ error = PTR_ERR(ts->reset_gpio);
+
+diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c
+index 35cd448efdfbe..82d5e8a8c19ea 100644
+--- a/drivers/interconnect/qcom/sc7180.c
++++ b/drivers/interconnect/qcom/sc7180.c
+@@ -369,7 +369,7 @@ static const struct qcom_icc_desc sc7180_gem_noc = {
+ .num_bcms = ARRAY_SIZE(gem_noc_bcms),
+ };
+
+-static struct qcom_icc_bcm *mc_virt_bcms[] = {
++static struct qcom_icc_bcm * const mc_virt_bcms[] = {
+ &bcm_acv,
+ &bcm_mc0,
+ };
+diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
+index 6a1f02c62dffc..9f7fab49a5a90 100644
+--- a/drivers/iommu/amd/iommu_v2.c
++++ b/drivers/iommu/amd/iommu_v2.c
+@@ -587,6 +587,7 @@ out_drop_state:
+ put_device_state(dev_state);
+
+ out:
++ pci_dev_put(pdev);
+ return ret;
+ }
+
+diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
+index 0d03f837a5d4e..7a1a413f75ab2 100644
+--- a/drivers/iommu/fsl_pamu.c
++++ b/drivers/iommu/fsl_pamu.c
+@@ -868,7 +868,7 @@ static int fsl_pamu_probe(struct platform_device *pdev)
+ ret = create_csd(ppaact_phys, mem_size, csd_port_id);
+ if (ret) {
+ dev_err(dev, "could not create coherence subdomain\n");
+- return ret;
++ goto error;
+ }
+ }
+
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index 7e363b1f24dfe..ec73720e239b2 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1041,20 +1041,24 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ struct mtk_iommu_data *data)
+ {
+ struct device_node *larbnode, *smicomm_node, *smi_subcomm_node;
+- struct platform_device *plarbdev;
++ struct platform_device *plarbdev, *pcommdev;
+ struct device_link *link;
+ int i, larb_nr, ret;
+
+ larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL);
+ if (larb_nr < 0)
+ return larb_nr;
++ if (larb_nr == 0 || larb_nr > MTK_LARB_NR_MAX)
++ return -EINVAL;
+
+ for (i = 0; i < larb_nr; i++) {
+ u32 id;
+
+ larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+- if (!larbnode)
+- return -EINVAL;
++ if (!larbnode) {
++ ret = -EINVAL;
++ goto err_larbdev_put;
++ }
+
+ if (!of_device_is_available(larbnode)) {
+ of_node_put(larbnode);
+@@ -1064,20 +1068,32 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
+ if (ret)/* The id is consecutive if there is no this property */
+ id = i;
++ if (id >= MTK_LARB_NR_MAX) {
++ of_node_put(larbnode);
++ ret = -EINVAL;
++ goto err_larbdev_put;
++ }
+
+ plarbdev = of_find_device_by_node(larbnode);
++ of_node_put(larbnode);
+ if (!plarbdev) {
+- of_node_put(larbnode);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err_larbdev_put;
+ }
+- if (!plarbdev->dev.driver) {
+- of_node_put(larbnode);
+- return -EPROBE_DEFER;
++ if (data->larb_imu[id].dev) {
++ platform_device_put(plarbdev);
++ ret = -EEXIST;
++ goto err_larbdev_put;
+ }
+ data->larb_imu[id].dev = &plarbdev->dev;
+
+- component_match_add_release(dev, match, component_release_of,
+- component_compare_of, larbnode);
++ if (!plarbdev->dev.driver) {
++ ret = -EPROBE_DEFER;
++ goto err_larbdev_put;
++ }
++
++ component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
++ platform_device_put(plarbdev);
+ }
+
+ /* Get smi-(sub)-common dev from the last larb. */
+@@ -1095,17 +1111,28 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ else
+ smicomm_node = smi_subcomm_node;
+
+- plarbdev = of_find_device_by_node(smicomm_node);
++ pcommdev = of_find_device_by_node(smicomm_node);
+ of_node_put(smicomm_node);
+- data->smicomm_dev = &plarbdev->dev;
++ if (!pcommdev)
++ return -ENODEV;
++ data->smicomm_dev = &pcommdev->dev;
+
+ link = device_link_add(data->smicomm_dev, dev,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
++ platform_device_put(pcommdev);
+ if (!link) {
+ dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
+ return -EINVAL;
+ }
+ return 0;
++
++err_larbdev_put:
++ for (i = MTK_LARB_NR_MAX - 1; i >= 0; i--) {
++ if (!data->larb_imu[i].dev)
++ continue;
++ put_device(data->larb_imu[i].dev);
++ }
++ return ret;
+ }
+
+ static int mtk_iommu_probe(struct platform_device *pdev)
+@@ -1170,6 +1197,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
+
+ banks_num = data->plat_data->banks_num;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res)
++ return -EINVAL;
+ if (resource_size(res) < banks_num * MTK_IOMMU_BANK_SZ) {
+ dev_err(dev, "banknr %d. res %pR is not enough.\n", banks_num, res);
+ return -EINVAL;
+diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
+index ab57c4b8fade2..a0652e9a7db34 100644
+--- a/drivers/iommu/rockchip-iommu.c
++++ b/drivers/iommu/rockchip-iommu.c
+@@ -280,19 +280,17 @@ static u32 rk_mk_pte(phys_addr_t page, int prot)
+ * 11:9 - Page address bit 34:32
+ * 8:4 - Page address bit 39:35
+ * 3 - Security
+- * 2 - Readable
+- * 1 - Writable
++ * 2 - Writable
++ * 1 - Readable
+ * 0 - 1 if Page @ Page address is valid
+ */
+-#define RK_PTE_PAGE_READABLE_V2 BIT(2)
+-#define RK_PTE_PAGE_WRITABLE_V2 BIT(1)
+
+ static u32 rk_mk_pte_v2(phys_addr_t page, int prot)
+ {
+ u32 flags = 0;
+
+- flags |= (prot & IOMMU_READ) ? RK_PTE_PAGE_READABLE_V2 : 0;
+- flags |= (prot & IOMMU_WRITE) ? RK_PTE_PAGE_WRITABLE_V2 : 0;
++ flags |= (prot & IOMMU_READ) ? RK_PTE_PAGE_READABLE : 0;
++ flags |= (prot & IOMMU_WRITE) ? RK_PTE_PAGE_WRITABLE : 0;
+
+ return rk_mk_dte_v2(page) | flags;
+ }
+diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
+index c898bcbbce118..96173cfee3249 100644
+--- a/drivers/iommu/s390-iommu.c
++++ b/drivers/iommu/s390-iommu.c
+@@ -79,10 +79,36 @@ static void s390_domain_free(struct iommu_domain *domain)
+ {
+ struct s390_domain *s390_domain = to_s390_domain(domain);
+
++ WARN_ON(!list_empty(&s390_domain->devices));
+ dma_cleanup_tables(s390_domain->dma_table);
+ kfree(s390_domain);
+ }
+
++static void __s390_iommu_detach_device(struct zpci_dev *zdev)
++{
++ struct s390_domain *s390_domain = zdev->s390_domain;
++ struct s390_domain_device *domain_device, *tmp;
++ unsigned long flags;
++
++ if (!s390_domain)
++ return;
++
++ spin_lock_irqsave(&s390_domain->list_lock, flags);
++ list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices,
++ list) {
++ if (domain_device->zdev == zdev) {
++ list_del(&domain_device->list);
++ kfree(domain_device);
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&s390_domain->list_lock, flags);
++
++ zpci_unregister_ioat(zdev, 0);
++ zdev->s390_domain = NULL;
++ zdev->dma_table = NULL;
++}
++
+ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+ {
+@@ -90,7 +116,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ struct zpci_dev *zdev = to_zpci_dev(dev);
+ struct s390_domain_device *domain_device;
+ unsigned long flags;
+- int cc, rc;
++ int cc, rc = 0;
+
+ if (!zdev)
+ return -ENODEV;
+@@ -99,24 +125,18 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ if (!domain_device)
+ return -ENOMEM;
+
+- if (zdev->dma_table && !zdev->s390_domain) {
+- cc = zpci_dma_exit_device(zdev);
+- if (cc) {
+- rc = -EIO;
+- goto out_free;
+- }
+- }
+-
+ if (zdev->s390_domain)
+- zpci_unregister_ioat(zdev, 0);
++ __s390_iommu_detach_device(zdev);
++ else if (zdev->dma_table)
++ zpci_dma_exit_device(zdev);
+
+- zdev->dma_table = s390_domain->dma_table;
+ cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+- virt_to_phys(zdev->dma_table));
++ virt_to_phys(s390_domain->dma_table));
+ if (cc) {
+ rc = -EIO;
+- goto out_restore;
++ goto out_free;
+ }
++ zdev->dma_table = s390_domain->dma_table;
+
+ spin_lock_irqsave(&s390_domain->list_lock, flags);
+ /* First device defines the DMA range limits */
+@@ -127,9 +147,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ /* Allow only devices with identical DMA range limits */
+ } else if (domain->geometry.aperture_start != zdev->start_dma ||
+ domain->geometry.aperture_end != zdev->end_dma) {
+- rc = -EINVAL;
+ spin_unlock_irqrestore(&s390_domain->list_lock, flags);
+- goto out_restore;
++ rc = -EINVAL;
++ goto out_unregister;
+ }
+ domain_device->zdev = zdev;
+ zdev->s390_domain = s390_domain;
+@@ -138,14 +158,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+
+ return 0;
+
+-out_restore:
+- if (!zdev->s390_domain) {
+- zpci_dma_init_device(zdev);
+- } else {
+- zdev->dma_table = zdev->s390_domain->dma_table;
+- zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+- virt_to_phys(zdev->dma_table));
+- }
++out_unregister:
++ zpci_unregister_ioat(zdev, 0);
++ zdev->dma_table = NULL;
+ out_free:
+ kfree(domain_device);
+
+@@ -155,32 +170,12 @@ out_free:
+ static void s390_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+ {
+- struct s390_domain *s390_domain = to_s390_domain(domain);
+ struct zpci_dev *zdev = to_zpci_dev(dev);
+- struct s390_domain_device *domain_device, *tmp;
+- unsigned long flags;
+- int found = 0;
+
+- if (!zdev)
+- return;
++ WARN_ON(zdev->s390_domain != to_s390_domain(domain));
+
+- spin_lock_irqsave(&s390_domain->list_lock, flags);
+- list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices,
+- list) {
+- if (domain_device->zdev == zdev) {
+- list_del(&domain_device->list);
+- kfree(domain_device);
+- found = 1;
+- break;
+- }
+- }
+- spin_unlock_irqrestore(&s390_domain->list_lock, flags);
+-
+- if (found && (zdev->s390_domain == s390_domain)) {
+- zdev->s390_domain = NULL;
+- zpci_unregister_ioat(zdev, 0);
+- zpci_dma_init_device(zdev);
+- }
++ __s390_iommu_detach_device(zdev);
++ zpci_dma_init_device(zdev);
+ }
+
+ static struct iommu_device *s390_iommu_probe_device(struct device *dev)
+@@ -193,24 +188,13 @@ static struct iommu_device *s390_iommu_probe_device(struct device *dev)
+ static void s390_iommu_release_device(struct device *dev)
+ {
+ struct zpci_dev *zdev = to_zpci_dev(dev);
+- struct iommu_domain *domain;
+
+ /*
+- * This is a workaround for a scenario where the IOMMU API common code
+- * "forgets" to call the detach_dev callback: After binding a device
+- * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers
+- * the attach_dev), removing the device via
+- * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,
+- * only release_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
+- * notifier.
+- *
+- * So let's call detach_dev from here if it hasn't been called before.
++ * release_device is expected to detach any domain currently attached
++ * to the device, but keep it attached to other devices in the group.
+ */
+- if (zdev && zdev->s390_domain) {
+- domain = iommu_get_domain_for_dev(dev);
+- if (domain)
+- s390_iommu_detach_device(domain, dev);
+- }
++ if (zdev)
++ __s390_iommu_detach_device(zdev);
+ }
+
+ static int s390_iommu_update_trans(struct s390_domain *s390_domain,
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index a84c63518773a..1d81a6aa939bf 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -27,6 +27,7 @@
+ #include <linux/types.h>
+
+ #define IOMMU_RESET_REG 0x010
++#define IOMMU_RESET_RELEASE_ALL 0xffffffff
+ #define IOMMU_ENABLE_REG 0x020
+ #define IOMMU_ENABLE_ENABLE BIT(0)
+
+@@ -92,6 +93,8 @@
+ #define NUM_PT_ENTRIES 256
+ #define PT_SIZE (NUM_PT_ENTRIES * PT_ENTRY_SIZE)
+
++#define SPAGE_SIZE 4096
++
+ struct sun50i_iommu {
+ struct iommu_device iommu;
+
+@@ -270,7 +273,7 @@ static u32 sun50i_mk_pte(phys_addr_t page, int prot)
+ enum sun50i_iommu_aci aci;
+ u32 flags = 0;
+
+- if (prot & (IOMMU_READ | IOMMU_WRITE))
++ if ((prot & (IOMMU_READ | IOMMU_WRITE)) == (IOMMU_READ | IOMMU_WRITE))
+ aci = SUN50I_IOMMU_ACI_RD_WR;
+ else if (prot & IOMMU_READ)
+ aci = SUN50I_IOMMU_ACI_RD;
+@@ -294,6 +297,62 @@ static void sun50i_table_flush(struct sun50i_iommu_domain *sun50i_domain,
+ dma_sync_single_for_device(iommu->dev, dma, size, DMA_TO_DEVICE);
+ }
+
++static void sun50i_iommu_zap_iova(struct sun50i_iommu *iommu,
++ unsigned long iova)
++{
++ u32 reg;
++ int ret;
++
++ iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_REG, iova);
++ iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_MASK_REG, GENMASK(31, 12));
++ iommu_write(iommu, IOMMU_TLB_IVLD_ENABLE_REG,
++ IOMMU_TLB_IVLD_ENABLE_ENABLE);
++
++ ret = readl_poll_timeout_atomic(iommu->base + IOMMU_TLB_IVLD_ENABLE_REG,
++ reg, !reg, 1, 2000);
++ if (ret)
++ dev_warn(iommu->dev, "TLB invalidation timed out!\n");
++}
++
++static void sun50i_iommu_zap_ptw_cache(struct sun50i_iommu *iommu,
++ unsigned long iova)
++{
++ u32 reg;
++ int ret;
++
++ iommu_write(iommu, IOMMU_PC_IVLD_ADDR_REG, iova);
++ iommu_write(iommu, IOMMU_PC_IVLD_ENABLE_REG,
++ IOMMU_PC_IVLD_ENABLE_ENABLE);
++
++ ret = readl_poll_timeout_atomic(iommu->base + IOMMU_PC_IVLD_ENABLE_REG,
++ reg, !reg, 1, 2000);
++ if (ret)
++ dev_warn(iommu->dev, "PTW cache invalidation timed out!\n");
++}
++
++static void sun50i_iommu_zap_range(struct sun50i_iommu *iommu,
++ unsigned long iova, size_t size)
++{
++ assert_spin_locked(&iommu->iommu_lock);
++
++ iommu_write(iommu, IOMMU_AUTO_GATING_REG, 0);
++
++ sun50i_iommu_zap_iova(iommu, iova);
++ sun50i_iommu_zap_iova(iommu, iova + SPAGE_SIZE);
++ if (size > SPAGE_SIZE) {
++ sun50i_iommu_zap_iova(iommu, iova + size);
++ sun50i_iommu_zap_iova(iommu, iova + size + SPAGE_SIZE);
++ }
++ sun50i_iommu_zap_ptw_cache(iommu, iova);
++ sun50i_iommu_zap_ptw_cache(iommu, iova + SZ_1M);
++ if (size > SZ_1M) {
++ sun50i_iommu_zap_ptw_cache(iommu, iova + size);
++ sun50i_iommu_zap_ptw_cache(iommu, iova + size + SZ_1M);
++ }
++
++ iommu_write(iommu, IOMMU_AUTO_GATING_REG, IOMMU_AUTO_GATING_ENABLE);
++}
++
+ static int sun50i_iommu_flush_all_tlb(struct sun50i_iommu *iommu)
+ {
+ u32 reg;
+@@ -343,6 +402,18 @@ static void sun50i_iommu_flush_iotlb_all(struct iommu_domain *domain)
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+ }
+
++static void sun50i_iommu_iotlb_sync_map(struct iommu_domain *domain,
++ unsigned long iova, size_t size)
++{
++ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
++ struct sun50i_iommu *iommu = sun50i_domain->iommu;
++ unsigned long flags;
++
++ spin_lock_irqsave(&iommu->iommu_lock, flags);
++ sun50i_iommu_zap_range(iommu, iova, size);
++ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
++}
++
+ static void sun50i_iommu_iotlb_sync(struct iommu_domain *domain,
+ struct iommu_iotlb_gather *gather)
+ {
+@@ -511,7 +582,7 @@ static u32 *sun50i_dte_get_page_table(struct sun50i_iommu_domain *sun50i_domain,
+ sun50i_iommu_free_page_table(iommu, drop_pt);
+ }
+
+- sun50i_table_flush(sun50i_domain, page_table, PT_SIZE);
++ sun50i_table_flush(sun50i_domain, page_table, NUM_PT_ENTRIES);
+ sun50i_table_flush(sun50i_domain, dte_addr, 1);
+
+ return page_table;
+@@ -601,7 +672,6 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
+ struct sun50i_iommu_domain *sun50i_domain;
+
+ if (type != IOMMU_DOMAIN_DMA &&
+- type != IOMMU_DOMAIN_IDENTITY &&
+ type != IOMMU_DOMAIN_UNMANAGED)
+ return NULL;
+
+@@ -766,6 +836,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
+ .attach_dev = sun50i_iommu_attach_device,
+ .detach_dev = sun50i_iommu_detach_device,
+ .flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
++ .iotlb_sync_map = sun50i_iommu_iotlb_sync_map,
+ .iotlb_sync = sun50i_iommu_iotlb_sync,
+ .iova_to_phys = sun50i_iommu_iova_to_phys,
+ .map = sun50i_iommu_map,
+@@ -785,6 +856,8 @@ static void sun50i_iommu_report_fault(struct sun50i_iommu *iommu,
+ report_iommu_fault(iommu->domain, iommu->dev, iova, prot);
+ else
+ dev_err(iommu->dev, "Page fault while iommu not attached to any domain?\n");
++
++ sun50i_iommu_zap_range(iommu, iova, SPAGE_SIZE);
+ }
+
+ static phys_addr_t sun50i_iommu_handle_pt_irq(struct sun50i_iommu *iommu,
+@@ -868,8 +941,8 @@ static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu)
+
+ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ {
++ u32 status, l1_status, l2_status, resets;
+ struct sun50i_iommu *iommu = dev_id;
+- u32 status;
+
+ spin_lock(&iommu->iommu_lock);
+
+@@ -879,6 +952,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ return IRQ_NONE;
+ }
+
++ l1_status = iommu_read(iommu, IOMMU_L1PG_INT_REG);
++ l2_status = iommu_read(iommu, IOMMU_L2PG_INT_REG);
++
+ if (status & IOMMU_INT_INVALID_L2PG)
+ sun50i_iommu_handle_pt_irq(iommu,
+ IOMMU_INT_ERR_ADDR_L2_REG,
+@@ -892,8 +968,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+
+ iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+
+- iommu_write(iommu, IOMMU_RESET_REG, ~status);
+- iommu_write(iommu, IOMMU_RESET_REG, status);
++ resets = (status | l1_status | l2_status) & IOMMU_INT_MASTER_MASK;
++ iommu_write(iommu, IOMMU_RESET_REG, ~resets);
++ iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL);
+
+ spin_unlock(&iommu->iommu_lock);
+
+diff --git a/drivers/irqchip/irq-gic-pm.c b/drivers/irqchip/irq-gic-pm.c
+index b60e1853593f4..3989d16f997b3 100644
+--- a/drivers/irqchip/irq-gic-pm.c
++++ b/drivers/irqchip/irq-gic-pm.c
+@@ -102,7 +102,7 @@ static int gic_probe(struct platform_device *pdev)
+
+ pm_runtime_enable(dev);
+
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ goto rpm_disable;
+
+diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
+index 0da8716f8f24b..c4584e2f0ad3d 100644
+--- a/drivers/irqchip/irq-loongson-liointc.c
++++ b/drivers/irqchip/irq-loongson-liointc.c
+@@ -207,10 +207,13 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision,
+ "reg-names", core_reg_names[i]);
+
+ if (index < 0)
+- goto out_iounmap;
++ continue;
+
+ priv->core_isr[i] = of_iomap(node, index);
+ }
++
++ if (!priv->core_isr[0])
++ goto out_iounmap;
+ }
+
+ /* Setup IRQ domain */
+diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c
+index c01b9c2570053..03493cda65a37 100644
+--- a/drivers/irqchip/irq-loongson-pch-pic.c
++++ b/drivers/irqchip/irq-loongson-pch-pic.c
+@@ -159,6 +159,9 @@ static int pch_pic_domain_translate(struct irq_domain *d,
+ return -EINVAL;
+
+ if (of_node) {
++ if (fwspec->param_count < 2)
++ return -EINVAL;
++
+ *hwirq = fwspec->param[0] + priv->ht_vec_base;
+ *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+ } else {
+diff --git a/drivers/irqchip/irq-wpcm450-aic.c b/drivers/irqchip/irq-wpcm450-aic.c
+index 0dcbeb1a05a1f..91df62a64cd91 100644
+--- a/drivers/irqchip/irq-wpcm450-aic.c
++++ b/drivers/irqchip/irq-wpcm450-aic.c
+@@ -146,6 +146,7 @@ static int __init wpcm450_aic_of_init(struct device_node *node,
+ aic->regs = of_iomap(node, 0);
+ if (!aic->regs) {
+ pr_err("Failed to map WPCM450 AIC registers\n");
++ kfree(aic);
+ return -ENOMEM;
+ }
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
+index 4f7eaa17fb274..e840609c50eb7 100644
+--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
++++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
+@@ -3217,6 +3217,7 @@ static int
+ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ {
+ struct hfc_multi *hc = dch->hw;
++ struct sk_buff_head free_queue;
+ u_long flags;
+
+ switch (cmd) {
+@@ -3245,6 +3246,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ l1_event(dch->l1, HW_POWERUP_IND);
+ break;
+ case HW_DEACT_REQ:
++ __skb_queue_head_init(&free_queue);
+ /* start deactivation */
+ spin_lock_irqsave(&hc->lock, flags);
+ if (hc->ctype == HFC_TYPE_E1) {
+@@ -3264,20 +3266,21 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ plxsd_checksync(hc, 0);
+ }
+ }
+- skb_queue_purge(&dch->squeue);
++ skb_queue_splice_init(&dch->squeue, &free_queue);
+ if (dch->tx_skb) {
+- dev_kfree_skb(dch->tx_skb);
++ __skb_queue_tail(&free_queue, dch->tx_skb);
+ dch->tx_skb = NULL;
+ }
+ dch->tx_idx = 0;
+ if (dch->rx_skb) {
+- dev_kfree_skb(dch->rx_skb);
++ __skb_queue_tail(&free_queue, dch->rx_skb);
+ dch->rx_skb = NULL;
+ }
+ test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+ if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+ del_timer(&dch->timer);
+ spin_unlock_irqrestore(&hc->lock, flags);
++ __skb_queue_purge(&free_queue);
+ break;
+ case HW_POWERUP_REQ:
+ spin_lock_irqsave(&hc->lock, flags);
+@@ -3384,6 +3387,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ case PH_DEACTIVATE_REQ:
+ test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+ if (dch->dev.D.protocol != ISDN_P_TE_S0) {
++ struct sk_buff_head free_queue;
++
++ __skb_queue_head_init(&free_queue);
+ spin_lock_irqsave(&hc->lock, flags);
+ if (debug & DEBUG_HFCMULTI_MSG)
+ printk(KERN_DEBUG
+@@ -3405,14 +3411,14 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ /* deactivate */
+ dch->state = 1;
+ }
+- skb_queue_purge(&dch->squeue);
++ skb_queue_splice_init(&dch->squeue, &free_queue);
+ if (dch->tx_skb) {
+- dev_kfree_skb(dch->tx_skb);
++ __skb_queue_tail(&free_queue, dch->tx_skb);
+ dch->tx_skb = NULL;
+ }
+ dch->tx_idx = 0;
+ if (dch->rx_skb) {
+- dev_kfree_skb(dch->rx_skb);
++ __skb_queue_tail(&free_queue, dch->rx_skb);
+ dch->rx_skb = NULL;
+ }
+ test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -3424,6 +3430,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ #endif
+ ret = 0;
+ spin_unlock_irqrestore(&hc->lock, flags);
++ __skb_queue_purge(&free_queue);
+ } else
+ ret = l1_event(dch->l1, hh->prim);
+ break;
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index af17459c1a5c0..eba58b99cd29d 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -1617,16 +1617,19 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+ spin_lock_irqsave(&hc->lock, flags);
+ if (hc->hw.protocol == ISDN_P_NT_S0) {
++ struct sk_buff_head free_queue;
++
++ __skb_queue_head_init(&free_queue);
+ /* prepare deactivation */
+ Write_hfc(hc, HFCPCI_STATES, 0x40);
+- skb_queue_purge(&dch->squeue);
++ skb_queue_splice_init(&dch->squeue, &free_queue);
+ if (dch->tx_skb) {
+- dev_kfree_skb(dch->tx_skb);
++ __skb_queue_tail(&free_queue, dch->tx_skb);
+ dch->tx_skb = NULL;
+ }
+ dch->tx_idx = 0;
+ if (dch->rx_skb) {
+- dev_kfree_skb(dch->rx_skb);
++ __skb_queue_tail(&free_queue, dch->rx_skb);
+ dch->rx_skb = NULL;
+ }
+ test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -1639,10 +1642,12 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ hc->hw.mst_m &= ~HFCPCI_MASTER;
+ Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
+ ret = 0;
++ spin_unlock_irqrestore(&hc->lock, flags);
++ __skb_queue_purge(&free_queue);
+ } else {
+ ret = l1_event(dch->l1, hh->prim);
++ spin_unlock_irqrestore(&hc->lock, flags);
+ }
+- spin_unlock_irqrestore(&hc->lock, flags);
+ break;
+ }
+ if (!ret)
+diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
+index 651f2f8f685b7..1efd17979f240 100644
+--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
++++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
+@@ -326,20 +326,24 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+
+ if (hw->protocol == ISDN_P_NT_S0) {
++ struct sk_buff_head free_queue;
++
++ __skb_queue_head_init(&free_queue);
+ hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
+ spin_lock_irqsave(&hw->lock, flags);
+- skb_queue_purge(&dch->squeue);
++ skb_queue_splice_init(&dch->squeue, &free_queue);
+ if (dch->tx_skb) {
+- dev_kfree_skb(dch->tx_skb);
++ __skb_queue_tail(&free_queue, dch->tx_skb);
+ dch->tx_skb = NULL;
+ }
+ dch->tx_idx = 0;
+ if (dch->rx_skb) {
+- dev_kfree_skb(dch->rx_skb);
++ __skb_queue_tail(&free_queue, dch->rx_skb);
+ dch->rx_skb = NULL;
+ }
+ test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
++ __skb_queue_purge(&free_queue);
+ #ifdef FIXME
+ if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
+ dchannel_sched_event(&hc->dch, D_CLEARBUSY);
+@@ -1330,7 +1334,7 @@ tx_iso_complete(struct urb *urb)
+ printk("\n");
+ }
+
+- dev_kfree_skb(tx_skb);
++ dev_consume_skb_irq(tx_skb);
+ tx_skb = NULL;
+ if (fifo->dch && get_next_dframe(fifo->dch))
+ tx_skb = fifo->dch->tx_skb;
+diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
+index 52b59b62f437c..b2f4c4ec7c567 100644
+--- a/drivers/leds/leds-is31fl319x.c
++++ b/drivers/leds/leds-is31fl319x.c
+@@ -38,6 +38,7 @@
+ #define IS31FL3190_CURRENT_uA_MIN 5000
+ #define IS31FL3190_CURRENT_uA_DEFAULT 42000
+ #define IS31FL3190_CURRENT_uA_MAX 42000
++#define IS31FL3190_CURRENT_SHIFT 2
+ #define IS31FL3190_CURRENT_MASK GENMASK(4, 2)
+ #define IS31FL3190_CURRENT_5_mA 0x02
+ #define IS31FL3190_CURRENT_10_mA 0x01
+@@ -553,7 +554,7 @@ static int is31fl319x_probe(struct i2c_client *client)
+ is31fl3196_db_to_gain(is31->audio_gain_db));
+ else
+ regmap_update_bits(is31->regmap, IS31FL3190_CURRENT, IS31FL3190_CURRENT_MASK,
+- is31fl3190_microamp_to_cs(dev, aggregated_led_microamp));
++ is31fl3190_microamp_to_cs(dev, aggregated_led_microamp) << IS31FL3190_CURRENT_SHIFT);
+
+ for (i = 0; i < is31->cdef->num_leds; i++) {
+ struct is31fl319x_led *led = &is31->leds[i];
+diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
+index 02f51cc618376..c1a56259226fb 100644
+--- a/drivers/leds/rgb/leds-qcom-lpg.c
++++ b/drivers/leds/rgb/leds-qcom-lpg.c
+@@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
+ lpg_lut_sync(lpg, lut_mask);
+ }
+
+-static void lpg_brightness_single_set(struct led_classdev *cdev,
+- enum led_brightness value)
++static int lpg_brightness_single_set(struct led_classdev *cdev,
++ enum led_brightness value)
+ {
+ struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
+ struct mc_subled info;
+@@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
+ lpg_brightness_set(led, cdev, &info);
+
+ mutex_unlock(&led->lpg->lock);
++
++ return 0;
+ }
+
+-static void lpg_brightness_mc_set(struct led_classdev *cdev,
+- enum led_brightness value)
++static int lpg_brightness_mc_set(struct led_classdev *cdev,
++ enum led_brightness value)
+ {
+ struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
+ struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
+@@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
+ lpg_brightness_set(led, cdev, mc->subled_info);
+
+ mutex_unlock(&led->lpg->lock);
++
++ return 0;
+ }
+
+ static int lpg_blink_set(struct lpg_led *led,
+@@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ led->mcdev.num_colors = num_channels;
+
+ cdev = &led->mcdev.led_cdev;
+- cdev->brightness_set = lpg_brightness_mc_set;
++ cdev->brightness_set_blocking = lpg_brightness_mc_set;
+ cdev->blink_set = lpg_blink_mc_set;
+
+ /* Register pattern accessors only if we have a LUT block */
+@@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ return ret;
+
+ cdev = &led->cdev;
+- cdev->brightness_set = lpg_brightness_single_set;
++ cdev->brightness_set_blocking = lpg_brightness_single_set;
+ cdev->blink_set = lpg_blink_single_set;
+
+ /* Register pattern accessors only if we have a LUT block */
+@@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ else
+ cdev->brightness = LED_OFF;
+
+- cdev->brightness_set(cdev, cdev->brightness);
++ cdev->brightness_set_blocking(cdev, cdev->brightness);
+
+ init_data.fwnode = of_fwnode_handle(np);
+
+diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
+index 9b63bd2551c63..cd4e34d15c26b 100644
+--- a/drivers/macintosh/macio-adb.c
++++ b/drivers/macintosh/macio-adb.c
+@@ -108,6 +108,10 @@ int macio_init(void)
+ return -ENXIO;
+ }
+ adb = ioremap(r.start, sizeof(struct adb_regs));
++ if (!adb) {
++ of_node_put(adbs);
++ return -ENOMEM;
++ }
+
+ out_8(&adb->ctrl.r, 0);
+ out_8(&adb->intr.r, 0);
+diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
+index 1ec1e5984563f..3bc1f374e6577 100644
+--- a/drivers/macintosh/macio_asic.c
++++ b/drivers/macintosh/macio_asic.c
+@@ -424,7 +424,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
+ if (of_device_register(&dev->ofdev) != 0) {
+ printk(KERN_DEBUG"macio: device registration error for %s!\n",
+ dev_name(&dev->ofdev.dev));
+- kfree(dev);
++ put_device(&dev->ofdev.dev);
+ return NULL;
+ }
+
+diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
+index a47aef8df52fd..c6d4957c4da83 100644
+--- a/drivers/mailbox/arm_mhuv2.c
++++ b/drivers/mailbox/arm_mhuv2.c
+@@ -1062,8 +1062,8 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
+ int ret = -EINVAL;
+
+ reg = devm_of_iomap(dev, dev->of_node, 0, NULL);
+- if (!reg)
+- return -ENOMEM;
++ if (IS_ERR(reg))
++ return PTR_ERR(reg);
+
+ mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
+ if (!mhu)
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
+index cfacb3f320a64..853901acaeec2 100644
+--- a/drivers/mailbox/mailbox-mpfs.c
++++ b/drivers/mailbox/mailbox-mpfs.c
+@@ -2,7 +2,7 @@
+ /*
+ * Microchip PolarFire SoC (MPFS) system controller/mailbox controller driver
+ *
+- * Copyright (c) 2020 Microchip Corporation. All rights reserved.
++ * Copyright (c) 2020-2022 Microchip Corporation. All rights reserved.
+ *
+ * Author: Conor Dooley <conor.dooley@microchip.com>
+ *
+@@ -56,7 +56,7 @@
+ #define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY)
+
+ #define SCB_STATUS_POS (16)
+-#define SCB_STATUS_MASK GENMASK_ULL(SCB_STATUS_POS + SCB_MASK_WIDTH, SCB_STATUS_POS)
++#define SCB_STATUS_MASK GENMASK(SCB_STATUS_POS + SCB_MASK_WIDTH - 1, SCB_STATUS_POS)
+
+ struct mpfs_mbox {
+ struct mbox_controller controller;
+@@ -130,13 +130,38 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
+ struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
+ struct mpfs_mss_response *response = mbox->response;
+ u16 num_words = ALIGN((response->resp_size), (4)) / 4U;
+- u32 i;
++ u32 i, status;
+
+ if (!response->resp_msg) {
+ dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM);
+ return;
+ }
+
++ /*
++ * The status is stored in bits 31:16 of the SERVICES_SR register.
++ * It is only valid when BUSY == 0.
++ * We should *never* get an interrupt while the controller is
++ * still in the busy state. If we do, something has gone badly
++ * wrong & the content of the mailbox would not be valid.
++ */
++ if (mpfs_mbox_busy(mbox)) {
++ dev_err(mbox->dev, "got an interrupt but system controller is busy\n");
++ response->resp_status = 0xDEAD;
++ return;
++ }
++
++ status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
++
++ /*
++ * If the status of the individual servers is non-zero, the service has
++ * failed. The contents of the mailbox at this point are not be valid,
++ * so don't bother reading them. Set the status so that the driver
++ * implementing the service can handle the result.
++ */
++ response->resp_status = (status & SCB_STATUS_MASK) >> SCB_STATUS_POS;
++ if (response->resp_status)
++ return;
++
+ if (!mpfs_mbox_busy(mbox)) {
+ for (i = 0; i < num_words; i++) {
+ response->resp_msg[i] =
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index ebfa33a40fceb..5e232b3fb72a9 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -743,6 +743,7 @@ static int __init pcc_init(void)
+
+ if (IS_ERR(pcc_pdev)) {
+ pr_debug("Err creating PCC platform bundle\n");
++ pcc_chan_count = 0;
+ return PTR_ERR(pcc_pdev);
+ }
+
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index 31a0fa9142744..12e004ff1a147 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -493,6 +493,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
+ ret = device_register(&ipi_mbox->dev);
+ if (ret) {
+ dev_err(dev, "Failed to register ipi mbox dev.\n");
++ put_device(&ipi_mbox->dev);
+ return ret;
+ }
+ mdev = &ipi_mbox->dev;
+@@ -619,7 +620,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
+ ipi_mbox = &pdata->ipi_mboxes[i];
+ if (ipi_mbox->dev.parent) {
+ mbox_controller_unregister(&ipi_mbox->mbox);
+- device_unregister(&ipi_mbox->dev);
++ if (device_is_registered(&ipi_mbox->dev))
++ device_unregister(&ipi_mbox->dev);
+ }
+ }
+ }
+diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
+index 338fc889b357a..b8ad4f16b4acd 100644
+--- a/drivers/mcb/mcb-core.c
++++ b/drivers/mcb/mcb-core.c
+@@ -71,8 +71,10 @@ static int mcb_probe(struct device *dev)
+
+ get_device(dev);
+ ret = mdrv->probe(mdev, found_id);
+- if (ret)
++ if (ret) {
+ module_put(carrier_mod);
++ put_device(dev);
++ }
+
+ return ret;
+ }
+diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
+index 0266bfddfbe27..aa6938da0db85 100644
+--- a/drivers/mcb/mcb-parse.c
++++ b/drivers/mcb/mcb-parse.c
+@@ -108,7 +108,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
+ return 0;
+
+ err:
+- mcb_free_dev(mdev);
++ put_device(&mdev->dev);
+
+ return ret;
+ }
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index b4a2cb5333fcc..bbde744f7dbaa 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -732,28 +732,48 @@ static char *_dm_claim_ptr = "I belong to device-mapper";
+ /*
+ * Open a table device so we can use it as a map destination.
+ */
+-static int open_table_device(struct table_device *td, dev_t dev,
+- struct mapped_device *md)
++static struct table_device *open_table_device(struct mapped_device *md,
++ dev_t dev, fmode_t mode)
+ {
++ struct table_device *td;
+ struct block_device *bdev;
+ u64 part_off;
+ int r;
+
+- BUG_ON(td->dm_dev.bdev);
++ td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id);
++ if (!td)
++ return ERR_PTR(-ENOMEM);
++ refcount_set(&td->count, 1);
+
+- bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _dm_claim_ptr);
+- if (IS_ERR(bdev))
+- return PTR_ERR(bdev);
++ bdev = blkdev_get_by_dev(dev, mode | FMODE_EXCL, _dm_claim_ptr);
++ if (IS_ERR(bdev)) {
++ r = PTR_ERR(bdev);
++ goto out_free_td;
++ }
+
+- r = bd_link_disk_holder(bdev, dm_disk(md));
+- if (r) {
+- blkdev_put(bdev, td->dm_dev.mode | FMODE_EXCL);
+- return r;
++ /*
++ * We can be called before the dm disk is added. In that case we can't
++ * register the holder relation here. It will be done once add_disk was
++ * called.
++ */
++ if (md->disk->slave_dir) {
++ r = bd_link_disk_holder(bdev, md->disk);
++ if (r)
++ goto out_blkdev_put;
+ }
+
++ td->dm_dev.mode = mode;
+ td->dm_dev.bdev = bdev;
+ td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev, &part_off, NULL, NULL);
+- return 0;
++ format_dev_t(td->dm_dev.name, dev);
++ list_add(&td->list, &md->table_devices);
++ return td;
++
++out_blkdev_put:
++ blkdev_put(bdev, mode | FMODE_EXCL);
++out_free_td:
++ kfree(td);
++ return ERR_PTR(r);
+ }
+
+ /*
+@@ -761,14 +781,12 @@ static int open_table_device(struct table_device *td, dev_t dev,
+ */
+ static void close_table_device(struct table_device *td, struct mapped_device *md)
+ {
+- if (!td->dm_dev.bdev)
+- return;
+-
+- bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md));
++ if (md->disk->slave_dir)
++ bd_unlink_disk_holder(td->dm_dev.bdev, md->disk);
+ blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL);
+ put_dax(td->dm_dev.dax_dev);
+- td->dm_dev.bdev = NULL;
+- td->dm_dev.dax_dev = NULL;
++ list_del(&td->list);
++ kfree(td);
+ }
+
+ static struct table_device *find_table_device(struct list_head *l, dev_t dev,
+@@ -786,31 +804,16 @@ static struct table_device *find_table_device(struct list_head *l, dev_t dev,
+ int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode,
+ struct dm_dev **result)
+ {
+- int r;
+ struct table_device *td;
+
+ mutex_lock(&md->table_devices_lock);
+ td = find_table_device(&md->table_devices, dev, mode);
+ if (!td) {
+- td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id);
+- if (!td) {
++ td = open_table_device(md, dev, mode);
++ if (IS_ERR(td)) {
+ mutex_unlock(&md->table_devices_lock);
+- return -ENOMEM;
++ return PTR_ERR(td);
+ }
+-
+- td->dm_dev.mode = mode;
+- td->dm_dev.bdev = NULL;
+-
+- if ((r = open_table_device(td, dev, md))) {
+- mutex_unlock(&md->table_devices_lock);
+- kfree(td);
+- return r;
+- }
+-
+- format_dev_t(td->dm_dev.name, dev);
+-
+- refcount_set(&td->count, 1);
+- list_add(&td->list, &md->table_devices);
+ } else {
+ refcount_inc(&td->count);
+ }
+@@ -825,11 +828,8 @@ void dm_put_table_device(struct mapped_device *md, struct dm_dev *d)
+ struct table_device *td = container_of(d, struct table_device, dm_dev);
+
+ mutex_lock(&md->table_devices_lock);
+- if (refcount_dec_and_test(&td->count)) {
++ if (refcount_dec_and_test(&td->count))
+ close_table_device(td, md);
+- list_del(&td->list);
+- kfree(td);
+- }
+ mutex_unlock(&md->table_devices_lock);
+ }
+
+@@ -1972,8 +1972,21 @@ static void cleanup_mapped_device(struct mapped_device *md)
+ md->disk->private_data = NULL;
+ spin_unlock(&_minor_lock);
+ if (dm_get_md_type(md) != DM_TYPE_NONE) {
++ struct table_device *td;
++
+ dm_sysfs_exit(md);
++ list_for_each_entry(td, &md->table_devices, list) {
++ bd_unlink_disk_holder(td->dm_dev.bdev,
++ md->disk);
++ }
++
++ /*
++ * Hold lock to make sure del_gendisk() won't concurrent
++ * with open/close_table_device().
++ */
++ mutex_lock(&md->table_devices_lock);
+ del_gendisk(md->disk);
++ mutex_unlock(&md->table_devices_lock);
+ }
+ dm_queue_destroy_crypto_profile(md->queue);
+ put_disk(md->disk);
+@@ -2305,6 +2318,7 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
+ {
+ enum dm_queue_mode type = dm_table_get_type(t);
+ struct queue_limits limits;
++ struct table_device *td;
+ int r;
+
+ switch (type) {
+@@ -2333,17 +2347,40 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
+ if (r)
+ return r;
+
++ /*
++ * Hold lock to make sure add_disk() and del_gendisk() won't concurrent
++ * with open_table_device() and close_table_device().
++ */
++ mutex_lock(&md->table_devices_lock);
+ r = add_disk(md->disk);
++ mutex_unlock(&md->table_devices_lock);
+ if (r)
+ return r;
+
+- r = dm_sysfs_init(md);
+- if (r) {
+- del_gendisk(md->disk);
+- return r;
++ /*
++ * Register the holder relationship for devices added before the disk
++ * was live.
++ */
++ list_for_each_entry(td, &md->table_devices, list) {
++ r = bd_link_disk_holder(td->dm_dev.bdev, md->disk);
++ if (r)
++ goto out_undo_holders;
+ }
++
++ r = dm_sysfs_init(md);
++ if (r)
++ goto out_undo_holders;
++
+ md->type = type;
+ return 0;
++
++out_undo_holders:
++ list_for_each_entry_continue_reverse(td, &md->table_devices, list)
++ bd_unlink_disk_holder(td->dm_dev.bdev, md->disk);
++ mutex_lock(&md->table_devices_lock);
++ del_gendisk(md->disk);
++ mutex_unlock(&md->table_devices_lock);
++ return r;
+ }
+
+ struct mapped_device *dm_get_md(dev_t dev)
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index bf6dffadbe6f6..63ece30114e53 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2195,20 +2195,23 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+
+ if (set) {
+ bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
+- if (*bmc_new == 0) {
+- /* need to set on-disk bits too. */
+- sector_t end = block + new_blocks;
+- sector_t start = block >> chunkshift;
+- start <<= chunkshift;
+- while (start < end) {
+- md_bitmap_file_set_bit(bitmap, block);
+- start += 1 << chunkshift;
++ if (bmc_new) {
++ if (*bmc_new == 0) {
++ /* need to set on-disk bits too. */
++ sector_t end = block + new_blocks;
++ sector_t start = block >> chunkshift;
++
++ start <<= chunkshift;
++ while (start < end) {
++ md_bitmap_file_set_bit(bitmap, block);
++ start += 1 << chunkshift;
++ }
++ *bmc_new = 2;
++ md_bitmap_count_page(&bitmap->counts, block, 1);
++ md_bitmap_set_pending(&bitmap->counts, block);
+ }
+- *bmc_new = 2;
+- md_bitmap_count_page(&bitmap->counts, block, 1);
+- md_bitmap_set_pending(&bitmap->counts, block);
++ *bmc_new |= NEEDED_MASK;
+ }
+- *bmc_new |= NEEDED_MASK;
+ if (new_blocks < old_blocks)
+ old_blocks = new_blocks;
+ }
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 857c49399c28e..b536befd88988 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -398,7 +398,6 @@ static int raid0_run(struct mddev *mddev)
+
+ blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
+ blk_queue_max_write_zeroes_sectors(mddev->queue, mddev->chunk_sectors);
+- blk_queue_max_discard_sectors(mddev->queue, UINT_MAX);
+
+ blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
+ blk_queue_io_opt(mddev->queue,
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 05d8438cfec88..58f705f429480 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -3159,6 +3159,7 @@ static int raid1_run(struct mddev *mddev)
+ * RAID1 needs at least one disk in active
+ */
+ if (conf->raid_disks - mddev->degraded < 1) {
++ md_unregister_thread(&conf->thread);
+ ret = -EINVAL;
+ goto abort;
+ }
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 64d6e4cd8a3a0..b19c6ce89d5ea 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -4104,8 +4104,6 @@ static int raid10_run(struct mddev *mddev)
+ conf->thread = NULL;
+
+ if (mddev->queue) {
+- blk_queue_max_discard_sectors(mddev->queue,
+- UINT_MAX);
+ blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
+ blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
+ raid10_set_io_opt(conf);
+diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
+index 15a08d8c69ef8..c2d2792227f86 100644
+--- a/drivers/media/dvb-core/dvb_ca_en50221.c
++++ b/drivers/media/dvb-core/dvb_ca_en50221.c
+@@ -157,7 +157,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
+ {
+ unsigned int i;
+
+- dvb_free_device(ca->dvbdev);
++ dvb_device_put(ca->dvbdev);
+ for (i = 0; i < ca->slot_count; i++)
+ vfree(ca->slot_info[i].rx_buffer.data);
+
+diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
+index 48e735cdbe6bb..c41a7e5c2b928 100644
+--- a/drivers/media/dvb-core/dvb_frontend.c
++++ b/drivers/media/dvb-core/dvb_frontend.c
+@@ -136,7 +136,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
+ if (fepriv)
+- dvb_free_device(fepriv->dvbdev);
++ dvb_device_put(fepriv->dvbdev);
+
+ dvb_frontend_invoke_release(fe, fe->ops.release);
+
+@@ -2986,6 +2986,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+ .name = fe->ops.info.name,
+ #endif
+ };
++ int ret;
+
+ dev_dbg(dvb->device, "%s:\n", __func__);
+
+@@ -3019,8 +3020,13 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+ "DVB: registering adapter %i frontend %i (%s)...\n",
+ fe->dvb->num, fe->id, fe->ops.info.name);
+
+- dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
++ ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
+ fe, DVB_DEVICE_FRONTEND, 0);
++ if (ret) {
++ dvb_frontend_put(fe);
++ mutex_unlock(&frontend_mutex);
++ return ret;
++ }
+
+ /*
+ * Initialize the cache to the proper values according with the
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 675d877a67b25..9934728734af9 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -97,7 +97,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
+ new_fops = fops_get(dvbdev->fops);
+ if (!new_fops)
+ goto fail;
+- file->private_data = dvbdev;
++ file->private_data = dvb_device_get(dvbdev);
+ replace_fops(file, new_fops);
+ if (file->f_op->open)
+ err = file->f_op->open(inode, file);
+@@ -161,6 +161,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
+ }
+
+ dvbdev->users++;
++
++ dvb_device_put(dvbdev);
++
+ return 0;
+ }
+ EXPORT_SYMBOL(dvb_generic_release);
+@@ -478,6 +481,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ }
+
+ memcpy(dvbdev, template, sizeof(struct dvb_device));
++ kref_init(&dvbdev->ref);
+ dvbdev->type = type;
+ dvbdev->id = id;
+ dvbdev->adapter = adap;
+@@ -508,7 +512,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ #endif
+
+ dvbdev->minor = minor;
+- dvb_minors[minor] = dvbdev;
++ dvb_minors[minor] = dvb_device_get(dvbdev);
+ up_write(&minor_rwsem);
+
+ ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
+@@ -553,6 +557,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+
+ down_write(&minor_rwsem);
+ dvb_minors[dvbdev->minor] = NULL;
++ dvb_device_put(dvbdev);
+ up_write(&minor_rwsem);
+
+ dvb_media_device_free(dvbdev);
+@@ -564,21 +569,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+ EXPORT_SYMBOL(dvb_remove_device);
+
+
+-void dvb_free_device(struct dvb_device *dvbdev)
++static void dvb_free_device(struct kref *ref)
+ {
+- if (!dvbdev)
+- return;
++ struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
+
+ kfree (dvbdev->fops);
+ kfree (dvbdev);
+ }
+-EXPORT_SYMBOL(dvb_free_device);
++
++
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
++{
++ kref_get(&dvbdev->ref);
++ return dvbdev;
++}
++EXPORT_SYMBOL(dvb_device_get);
++
++
++void dvb_device_put(struct dvb_device *dvbdev)
++{
++ if (dvbdev)
++ kref_put(&dvbdev->ref, dvb_free_device);
++}
+
+
+ void dvb_unregister_device(struct dvb_device *dvbdev)
+ {
+ dvb_remove_device(dvbdev);
+- dvb_free_device(dvbdev);
++ dvb_device_put(dvbdev);
+ }
+ EXPORT_SYMBOL(dvb_unregister_device);
+
+diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
+index da0ff7b44da41..68b92b4419cff 100644
+--- a/drivers/media/dvb-frontends/bcm3510.c
++++ b/drivers/media/dvb-frontends/bcm3510.c
+@@ -649,6 +649,7 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
+ deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
+ if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+ err("firmware download failed: %d\n",ret);
++ release_firmware(fw);
+ return ret;
+ }
+ i += 4 + len;
+diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
+index 2958a46944614..07639ecc85aa8 100644
+--- a/drivers/media/i2c/ad5820.c
++++ b/drivers/media/i2c/ad5820.c
+@@ -327,18 +327,18 @@ static int ad5820_probe(struct i2c_client *client,
+
+ ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
+ if (ret < 0)
+- goto cleanup2;
++ goto clean_mutex;
+
+ ret = v4l2_async_register_subdev(&coil->subdev);
+ if (ret < 0)
+- goto cleanup;
++ goto clean_entity;
+
+ return ret;
+
+-cleanup2:
+- mutex_destroy(&coil->power_lock);
+-cleanup:
++clean_entity:
+ media_entity_cleanup(&coil->subdev.entity);
++clean_mutex:
++ mutex_destroy(&coil->power_lock);
+ return ret;
+ }
+
+diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
+index 02eabe10ab970..00095c7762c24 100644
+--- a/drivers/media/i2c/adv748x/adv748x-afe.c
++++ b/drivers/media/i2c/adv748x/adv748x-afe.c
+@@ -521,6 +521,10 @@ int adv748x_afe_init(struct adv748x_afe *afe)
+ }
+ }
+
++ adv748x_afe_s_input(afe, afe->input);
++
++ adv_dbg(state, "AFE Default input set to %d\n", afe->input);
++
+ /* Entity pads and sinks are 0-indexed to match the pads */
+ for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++)
+ afe->pads[i].flags = MEDIA_PAD_FL_SINK;
+diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
+index c086580efac78..60ae0adf51744 100644
+--- a/drivers/media/i2c/dw9768.c
++++ b/drivers/media/i2c/dw9768.c
+@@ -414,6 +414,7 @@ static int dw9768_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+ struct dw9768 *dw9768;
++ bool full_power;
+ unsigned int i;
+ int ret;
+
+@@ -469,13 +470,23 @@ static int dw9768_probe(struct i2c_client *client)
+
+ dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
+
++ /*
++ * Figure out whether we're going to power up the device here. Generally
++ * this is done if CONFIG_PM is disabled in a DT system or the device is
++ * to be powered on in an ACPI system. Similarly for power off in
++ * remove.
++ */
+ pm_runtime_enable(dev);
+- if (!pm_runtime_enabled(dev)) {
++ full_power = (is_acpi_node(dev_fwnode(dev)) &&
++ acpi_dev_state_d0(dev)) ||
++ (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
++ if (full_power) {
+ ret = dw9768_runtime_resume(dev);
+ if (ret < 0) {
+ dev_err(dev, "failed to power on: %d\n", ret);
+ goto err_clean_entity;
+ }
++ pm_runtime_set_active(dev);
+ }
+
+ ret = v4l2_async_register_subdev(&dw9768->sd);
+@@ -484,14 +495,17 @@ static int dw9768_probe(struct i2c_client *client)
+ goto err_power_off;
+ }
+
++ pm_runtime_idle(dev);
++
+ return 0;
+
+ err_power_off:
+- if (pm_runtime_enabled(dev))
+- pm_runtime_disable(dev);
+- else
++ 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);
+@@ -503,14 +517,17 @@ static int dw9768_remove(struct i2c_client *client)
+ {
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct dw9768 *dw9768 = sd_to_dw9768(sd);
++ struct device *dev = &client->dev;
+
+ v4l2_async_unregister_subdev(&dw9768->sd);
+ v4l2_ctrl_handler_free(&dw9768->ctrls);
+ media_entity_cleanup(&dw9768->sd.entity);
+- pm_runtime_disable(&client->dev);
+- if (!pm_runtime_status_suspended(&client->dev))
+- dw9768_runtime_suspend(&client->dev);
+- pm_runtime_set_suspended(&client->dev);
++ if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
++ (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
++ dw9768_runtime_suspend(dev);
++ pm_runtime_set_suspended(dev);
++ }
++ pm_runtime_disable(dev);
+
+ return 0;
+ }
+diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
+index ad35c3ff36115..254031503c728 100644
+--- a/drivers/media/i2c/hi846.c
++++ b/drivers/media/i2c/hi846.c
+@@ -2008,22 +2008,24 @@ static int hi846_parse_dt(struct hi846 *hi846, struct device *dev)
+ bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+ dev_err(dev, "number of CSI2 data lanes %d is not supported",
+ bus_cfg.bus.mipi_csi2.num_data_lanes);
+- v4l2_fwnode_endpoint_free(&bus_cfg);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto check_hwcfg_error;
+ }
+
+ hi846->nr_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+ if (!bus_cfg.nr_of_link_frequencies) {
+ dev_err(dev, "link-frequency property not found in DT\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto check_hwcfg_error;
+ }
+
+ /* Check that link frequences for all the modes are in device tree */
+ fq = hi846_check_link_freqs(hi846, &bus_cfg);
+ if (fq) {
+ dev_err(dev, "Link frequency of %lld is not supported\n", fq);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto check_hwcfg_error;
+ }
+
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+@@ -2044,6 +2046,10 @@ static int hi846_parse_dt(struct hi846 *hi846, struct device *dev)
+ }
+
+ return 0;
++
++check_hwcfg_error:
++ v4l2_fwnode_endpoint_free(&bus_cfg);
++ return ret;
+ }
+
+ static int hi846_probe(struct i2c_client *client)
+diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
+index 1fd4dc6e4726f..92f4e184353f8 100644
+--- a/drivers/media/i2c/mt9p031.c
++++ b/drivers/media/i2c/mt9p031.c
+@@ -702,7 +702,6 @@ static int mt9p031_init_cfg(struct v4l2_subdev *subdev,
+ V4L2_SUBDEV_FORMAT_TRY;
+
+ crop = __mt9p031_get_pad_crop(mt9p031, sd_state, 0, which);
+- v4l2_subdev_get_try_crop(subdev, sd_state, 0);
+ crop->left = MT9P031_COLUMN_START_DEF;
+ crop->top = MT9P031_ROW_START_DEF;
+ crop->width = MT9P031_WINDOW_WIDTH_DEF;
+diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
+index 502f0b62e9505..7e72e7c7b0ddc 100644
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -3816,7 +3816,8 @@ static int ov5640_probe(struct i2c_client *client)
+ sensor->current_mode =
+ &ov5640_mode_data[OV5640_MODE_VGA_640_480];
+ sensor->last_mode = sensor->current_mode;
+- sensor->current_link_freq = OV5640_DEFAULT_LINK_FREQ;
++ sensor->current_link_freq =
++ ov5640_csi2_link_freqs[OV5640_DEFAULT_LINK_FREQ];
+
+ sensor->ae_target = 52;
+
+diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c
+index dfcd33e9ee136..220c53565b0a7 100644
+--- a/drivers/media/i2c/ov5648.c
++++ b/drivers/media/i2c/ov5648.c
+@@ -2597,6 +2597,7 @@ static int ov5648_remove(struct i2c_client *client)
+ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+ mutex_destroy(&sensor->mutex);
+ media_entity_cleanup(&subdev->entity);
++ v4l2_fwnode_endpoint_free(&sensor->endpoint);
+
+ return 0;
+ }
+diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
+index 7973ae42873a6..c10997e2271d2 100644
+--- a/drivers/media/pci/saa7164/saa7164-core.c
++++ b/drivers/media/pci/saa7164/saa7164-core.c
+@@ -1259,7 +1259,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
+
+ if (saa7164_dev_setup(dev) < 0) {
+ err = -EINVAL;
+- goto fail_free;
++ goto fail_dev;
+ }
+
+ /* print pci info */
+@@ -1427,6 +1427,8 @@ fail_fw:
+
+ fail_irq:
+ saa7164_dev_unregister(dev);
++fail_dev:
++ pci_disable_device(pci_dev);
+ fail_free:
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
+index 4a546eeefe38f..6d87fbb0ee04a 100644
+--- a/drivers/media/pci/solo6x10/solo6x10-core.c
++++ b/drivers/media/pci/solo6x10/solo6x10-core.c
+@@ -420,6 +420,7 @@ static int solo_sysfs_init(struct solo_dev *solo_dev)
+ solo_dev->nr_chans);
+
+ if (device_register(dev)) {
++ put_device(dev);
+ dev->parent = NULL;
+ return -ENOMEM;
+ }
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index feb75dc204de8..b27e6bed85f0f 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -286,6 +286,7 @@ static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+ struct vpu_format *cur_fmt;
+ int i;
+
++ vpu_inst_lock(inst);
+ cur_fmt = vpu_get_format(inst, f->type);
+
+ pixmp->pixelformat = cur_fmt->pixfmt;
+@@ -303,6 +304,7 @@ static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+ f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+ f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+ f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
++ vpu_inst_unlock(inst);
+
+ return 0;
+ }
+@@ -753,6 +755,9 @@ static bool vdec_check_source_change(struct vpu_inst *inst)
+ if (!inst->fh.m2m_ctx)
+ return false;
+
++ if (vdec->reset_codec)
++ return false;
++
+ if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
+ return true;
+ fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+@@ -1088,7 +1093,8 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info
+ vdec->seq_tag = vdec->codec_info.tag;
+ if (vdec->is_source_changed) {
+ vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+- vpu_notify_source_change(inst);
++ vdec->source_change++;
++ vdec_handle_resolution_change(inst);
+ vdec->is_source_changed = false;
+ }
+ }
+@@ -1335,6 +1341,8 @@ static void vdec_abort(struct vpu_inst *inst)
+ vdec->decoded_frame_count,
+ vdec->display_frame_count,
+ vdec->sequence);
++ if (!vdec->seq_hdr_found)
++ vdec->reset_codec = true;
+ vdec->params.end_flag = 0;
+ vdec->drain = 0;
+ vdec->params.frame_count = 0;
+@@ -1342,6 +1350,7 @@ static void vdec_abort(struct vpu_inst *inst)
+ vdec->display_frame_count = 0;
+ vdec->sequence = 0;
+ vdec->aborting = false;
++ inst->extra_size = 0;
+ }
+
+ static void vdec_stop(struct vpu_inst *inst, bool free)
+@@ -1464,8 +1473,7 @@ static int vdec_start_session(struct vpu_inst *inst, u32 type)
+ }
+
+ if (V4L2_TYPE_IS_OUTPUT(type)) {
+- if (inst->state == VPU_CODEC_STATE_SEEK)
+- vdec_update_state(inst, vdec->state, 1);
++ vdec_update_state(inst, vdec->state, 1);
+ vdec->eos_received = 0;
+ vpu_process_output_buffer(inst);
+ } else {
+@@ -1629,6 +1637,7 @@ static int vdec_open(struct file *file)
+ return ret;
+
+ vdec->fixed_fmt = false;
++ vdec->state = VPU_CODEC_STATE_ACTIVE;
+ inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+ inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
+ vdec_init(file);
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index beac0309ca8d9..048c23c2bf4db 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -13,6 +13,7 @@
+ #include <linux/mailbox_controller.h>
+ #include <linux/kfifo.h>
+
++#define VPU_TIMEOUT_WAKEUP msecs_to_jiffies(200)
+ #define VPU_TIMEOUT msecs_to_jiffies(1000)
+ #define VPU_INST_NULL_ID (-1L)
+ #define VPU_MSG_BUFFER_SIZE (8192)
+diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
+index f4d7ca78a6212..fa581ba6bab2d 100644
+--- a/drivers/media/platform/amphion/vpu_cmds.c
++++ b/drivers/media/platform/amphion/vpu_cmds.c
+@@ -269,7 +269,7 @@ exit:
+ return flag;
+ }
+
+-static int sync_session_response(struct vpu_inst *inst, unsigned long key)
++static int sync_session_response(struct vpu_inst *inst, unsigned long key, long timeout, int try)
+ {
+ struct vpu_core *core;
+
+@@ -279,10 +279,12 @@ static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+ core = inst->core;
+
+ call_void_vop(inst, wait_prepare);
+- wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), VPU_TIMEOUT);
++ wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), timeout);
+ call_void_vop(inst, wait_finish);
+
+ if (!check_is_responsed(inst, key)) {
++ if (try)
++ return -EINVAL;
+ dev_err(inst->dev, "[%d] sync session timeout\n", inst->id);
+ set_bit(inst->id, &core->hang_mask);
+ mutex_lock(&inst->core->cmd_lock);
+@@ -294,6 +296,19 @@ static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+ return 0;
+ }
+
++static void vpu_core_keep_active(struct vpu_core *core)
++{
++ struct vpu_rpc_event pkt;
++
++ memset(&pkt, 0, sizeof(pkt));
++ vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_NOOP, NULL);
++
++ dev_dbg(core->dev, "try to wake up\n");
++ mutex_lock(&core->cmd_lock);
++ vpu_cmd_send(core, &pkt);
++ mutex_unlock(&core->cmd_lock);
++}
++
+ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+ {
+ unsigned long key;
+@@ -304,9 +319,25 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+ return -EINVAL;
+
+ ret = vpu_request_cmd(inst, id, data, &key, &sync);
+- if (!ret && sync)
+- ret = sync_session_response(inst, key);
++ if (ret)
++ goto exit;
++
++ /* workaround for a firmware issue,
++ * firmware should be waked up by start or configure command,
++ * but there is a very small change that firmware failed to wakeup.
++ * in such case, try to wakeup firmware again by sending a noop command
++ */
++ if (sync && (id == VPU_CMD_ID_CONFIGURE_CODEC || id == VPU_CMD_ID_START)) {
++ if (sync_session_response(inst, key, VPU_TIMEOUT_WAKEUP, 1))
++ vpu_core_keep_active(inst->core);
++ else
++ goto exit;
++ }
++
++ if (sync)
++ ret = sync_session_response(inst, key, VPU_TIMEOUT, 0);
+
++exit:
+ if (ret)
+ dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id);
+
+diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c
+index 9d5a5075343d3..f01ce49d27e80 100644
+--- a/drivers/media/platform/amphion/vpu_drv.c
++++ b/drivers/media/platform/amphion/vpu_drv.c
+@@ -245,7 +245,11 @@ static int __init vpu_driver_init(void)
+ if (ret)
+ return ret;
+
+- return vpu_core_driver_init();
++ ret = vpu_core_driver_init();
++ if (ret)
++ platform_driver_unregister(&hion_vpu_driver);
++
++ return ret;
+ }
+
+ static void __exit vpu_driver_exit(void)
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index 51e0702f9ae17..9f2890730fd70 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -692,6 +692,7 @@ int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+ }
+
+ static struct vpu_pair malone_cmds[] = {
++ {VPU_CMD_ID_NOOP, VID_API_CMD_NULL},
+ {VPU_CMD_ID_START, VID_API_CMD_START},
+ {VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+ {VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
+index d8247f36d84ba..92672a802b492 100644
+--- a/drivers/media/platform/amphion/vpu_msgs.c
++++ b/drivers/media/platform/amphion/vpu_msgs.c
+@@ -43,6 +43,7 @@ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc
+ req_data.ref_frame_num,
+ req_data.act_buf_size,
+ req_data.act_buf_num);
++ vpu_inst_lock(inst);
+ call_void_vop(inst, mem_request,
+ req_data.enc_frame_size,
+ req_data.enc_frame_num,
+@@ -50,6 +51,7 @@ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc
+ req_data.ref_frame_num,
+ req_data.act_buf_size,
+ req_data.act_buf_num);
++ vpu_inst_unlock(inst);
+ }
+
+ static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index b779e0ba916ca..590d1084e5a5d 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -65,18 +65,11 @@ unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
+
+ void vpu_v4l2_set_error(struct vpu_inst *inst)
+ {
+- struct vb2_queue *src_q;
+- struct vb2_queue *dst_q;
+-
+ vpu_inst_lock(inst);
+ dev_err(inst->dev, "some error occurs in codec\n");
+ if (inst->fh.m2m_ctx) {
+- src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+- dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+- src_q->error = 1;
+- dst_q->error = 1;
+- wake_up(&src_q->done_wq);
+- wake_up(&dst_q->done_wq);
++ vb2_queue_error(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx));
++ vb2_queue_error(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx));
+ }
+ vpu_inst_unlock(inst);
+ }
+@@ -249,8 +242,12 @@ int vpu_process_capture_buffer(struct vpu_inst *inst)
+
+ struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst)
+ {
+- struct vb2_v4l2_buffer *src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
++ struct vb2_v4l2_buffer *src_buf = NULL;
++
++ if (!inst->fh.m2m_ctx)
++ return NULL;
+
++ src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
+ if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
+ return NULL;
+
+@@ -273,7 +270,7 @@ void vpu_skip_frame(struct vpu_inst *inst, int count)
+ enum vb2_buffer_state state;
+ int i = 0;
+
+- if (count <= 0)
++ if (count <= 0 || !inst->fh.m2m_ctx)
+ return;
+
+ while (i < count) {
+@@ -603,10 +600,6 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
+ inst->workqueue = NULL;
+ }
+
+- if (inst->fh.m2m_ctx) {
+- v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+- inst->fh.m2m_ctx = NULL;
+- }
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
+ mutex_destroy(&inst->lock);
+ v4l2_fh_del(&inst->fh);
+@@ -689,6 +682,13 @@ int vpu_v4l2_close(struct file *file)
+
+ vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+
++ vpu_inst_lock(inst);
++ if (inst->fh.m2m_ctx) {
++ v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
++ inst->fh.m2m_ctx = NULL;
++ }
++ vpu_inst_unlock(inst);
++
+ call_void_vop(inst, release);
+ vpu_inst_unregister(inst);
+ vpu_inst_put(inst);
+diff --git a/drivers/media/platform/amphion/vpu_windsor.c b/drivers/media/platform/amphion/vpu_windsor.c
+index 1526af2ef9da4..b93c8cfdee7f5 100644
+--- a/drivers/media/platform/amphion/vpu_windsor.c
++++ b/drivers/media/platform/amphion/vpu_windsor.c
+@@ -658,6 +658,7 @@ int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+ }
+
+ static struct vpu_pair windsor_cmds[] = {
++ {VPU_CMD_ID_NOOP, GTB_ENC_CMD_NOOP},
+ {VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+ {VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+ {VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+diff --git a/drivers/media/platform/chips-media/coda-bit.c b/drivers/media/platform/chips-media/coda-bit.c
+index 2736a902e3df3..ed47d5bd8d61e 100644
+--- a/drivers/media/platform/chips-media/coda-bit.c
++++ b/drivers/media/platform/chips-media/coda-bit.c
+@@ -854,7 +854,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+ /* Only H.264BP and H.263P3 are considered */
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w64);
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w64);
+- if (!iram_info->buf_dbk_c_use)
++ if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+ goto out;
+ iram_info->axi_sram_use |= dbk_bits;
+
+@@ -878,7 +878,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w128);
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w128);
+- if (!iram_info->buf_dbk_c_use)
++ if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+ goto out;
+ iram_info->axi_sram_use |= dbk_bits;
+
+@@ -1084,10 +1084,16 @@ static int coda_start_encoding(struct coda_ctx *ctx)
+ }
+
+ if (dst_fourcc == V4L2_PIX_FMT_JPEG) {
+- if (!ctx->params.jpeg_qmat_tab[0])
++ if (!ctx->params.jpeg_qmat_tab[0]) {
+ ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+- if (!ctx->params.jpeg_qmat_tab[1])
++ if (!ctx->params.jpeg_qmat_tab[0])
++ return -ENOMEM;
++ }
++ if (!ctx->params.jpeg_qmat_tab[1]) {
+ ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++ if (!ctx->params.jpeg_qmat_tab[1])
++ return -ENOMEM;
++ }
+ coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+ }
+
+diff --git a/drivers/media/platform/chips-media/coda-jpeg.c b/drivers/media/platform/chips-media/coda-jpeg.c
+index a0b22b07f69ac..2284e04209348 100644
+--- a/drivers/media/platform/chips-media/coda-jpeg.c
++++ b/drivers/media/platform/chips-media/coda-jpeg.c
+@@ -1053,10 +1053,16 @@ static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
+ v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
+ return ret;
+ }
+- if (!ctx->params.jpeg_qmat_tab[0])
++ if (!ctx->params.jpeg_qmat_tab[0]) {
+ ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+- if (!ctx->params.jpeg_qmat_tab[1])
++ if (!ctx->params.jpeg_qmat_tab[0])
++ return -ENOMEM;
++ }
++ if (!ctx->params.jpeg_qmat_tab[1]) {
+ ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++ if (!ctx->params.jpeg_qmat_tab[1])
++ return -ENOMEM;
++ }
+ coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+
+ return 0;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+index c45bd2599bb2d..ffbcee04dc26f 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+@@ -138,10 +138,13 @@ static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error
+ state = VB2_BUF_STATE_DONE;
+
+ vb2_dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+- v4l2_m2m_buf_done(vb2_dst, state);
+-
+- mtk_v4l2_debug(2, "free frame buffer id:%d to done list",
+- vb2_dst->vb2_buf.index);
++ if (vb2_dst) {
++ v4l2_m2m_buf_done(vb2_dst, state);
++ mtk_v4l2_debug(2, "free frame buffer id:%d to done list",
++ vb2_dst->vb2_buf.index);
++ } else {
++ mtk_v4l2_err("dst buffer is NULL");
++ }
+
+ if (src_buf_req)
+ v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+@@ -250,7 +253,7 @@ static void mtk_vdec_worker(struct work_struct *work)
+
+ state = ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE;
+ if (!IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch) ||
+- ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME || ret) {
++ ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME) {
+ v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, state);
+ if (src_buf_req)
+ v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+index 4cc92700692b3..955b2d0c8f53f 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+@@ -471,14 +471,19 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+ sizeof(share_info->h264_slice_params));
+
+ fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+- y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+- vdec_fb_va = (unsigned long)fb;
++ if (!fb) {
++ err = -EBUSY;
++ mtk_vcodec_err(inst, "fb buffer is NULL");
++ goto vdec_dec_end;
++ }
+
++ vdec_fb_va = (unsigned long)fb;
++ y_fb_dma = (u64)fb->base_y.dma_addr;
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+ c_fb_dma =
+ y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+ else
+- c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
++ c_fb_dma = (u64)fb->base_c.dma_addr;
+
+ mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+ c_fb_dma);
+@@ -539,6 +544,29 @@ vdec_dec_end:
+ return 0;
+ }
+
++static void vdec_h264_insert_startcode(struct mtk_vcodec_dev *vcodec_dev, unsigned char *buf,
++ size_t *bs_size, struct mtk_h264_pps_param *pps)
++{
++ struct device *dev = &vcodec_dev->plat_dev->dev;
++
++ /* Need to add pending data at the end of bitstream when bs_sz is small than
++ * 20 bytes for cavlc bitstream, or lat will decode fail. This pending data is
++ * useful for mt8192 and mt8195 platform.
++ *
++ * cavlc bitstream when entropy_coding_mode_flag is false.
++ */
++ if (pps->entropy_coding_mode_flag || *bs_size > 20 ||
++ !(of_device_is_compatible(dev->of_node, "mediatek,mt8192-vcodec-dec") ||
++ of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-dec")))
++ return;
++
++ buf[*bs_size] = 0;
++ buf[*bs_size + 1] = 0;
++ buf[*bs_size + 2] = 1;
++ buf[*bs_size + 3] = 0xff;
++ (*bs_size) += 4;
++}
++
+ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ struct vdec_fb *fb, bool *res_chg)
+ {
+@@ -582,9 +610,6 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ }
+
+ inst->vsi->dec.nal_info = buf[nal_start_idx];
+- inst->vsi->dec.bs_buf_addr = (u64)bs->dma_addr;
+- inst->vsi->dec.bs_buf_size = bs->size;
+-
+ lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
+ v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true);
+
+@@ -592,6 +617,12 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ if (err)
+ goto err_free_fb_out;
+
++ vdec_h264_insert_startcode(inst->ctx->dev, buf, &bs->size,
++ &share_info->h264_slice_params.pps);
++
++ inst->vsi->dec.bs_buf_addr = (uint64_t)bs->dma_addr;
++ inst->vsi->dec.bs_buf_size = bs->size;
++
+ *res_chg = inst->resolution_changed;
+ if (inst->resolution_changed) {
+ mtk_vcodec_debug(inst, "- resolution changed -");
+@@ -630,7 +661,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ err = vpu_dec_start(vpu, data, 2);
+ if (err) {
+ mtk_vcodec_debug(inst, "lat decode err: %d", err);
+- goto err_scp_decode;
++ goto err_free_fb_out;
+ }
+
+ share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+@@ -647,12 +678,17 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ /* wait decoder done interrupt */
+ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
++ if (timeout)
++ mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num);
+ inst->vsi->dec.timeout = !!timeout;
+
+ err = vpu_dec_end(vpu);
+- if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+- err = -EINVAL;
+- goto err_scp_decode;
++ if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) {
++ if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
++ vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
++ inst->slice_dec_num++;
++ mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err);
++ return -EINVAL;
+ }
+
+ share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+@@ -669,10 +705,6 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+
+ inst->slice_dec_num++;
+ return 0;
+-
+-err_scp_decode:
+- if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
+- vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
+ err_free_fb_out:
+ vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
+ mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+index fb1c36a3592d1..cbb6728b8a40b 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+@@ -2073,21 +2073,23 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ return -EBUSY;
+ }
+ pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+- if (!pfc)
+- return -EINVAL;
++ if (!pfc) {
++ ret = -EINVAL;
++ goto err_free_fb_out;
++ }
+ vsi = &pfc->vsi;
+
+ ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc);
+ if (ret) {
+ mtk_vcodec_err(instance, "Failed to setup VP9 lat ret %d\n", ret);
+- return ret;
++ goto err_free_fb_out;
+ }
+ vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi);
+
+ ret = vpu_dec_start(&instance->vpu, NULL, 0);
+ if (ret) {
+ mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret);
+- return ret;
++ goto err_free_fb_out;
+ }
+
+ if (instance->irq) {
+@@ -2107,7 +2109,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ /* LAT trans full, no more UBE or decode timeout */
+ if (ret) {
+ mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret);
+- return ret;
++ goto err_free_fb_out;
+ }
+
+ mtk_vcodec_debug(instance, "lat dma addr: 0x%lx 0x%lx\n",
+@@ -2120,6 +2122,9 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+
+ return 0;
++err_free_fb_out:
++ vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
++ return ret;
+ }
+
+ static int vdec_vp9_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+index ae500980ad45c..dc2004790a472 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+@@ -221,7 +221,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
+ mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
+ vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+
+- if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
++ if (!list_empty(&dev->msg_queue_core_ctx.ready_queue)) {
+ mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
+ dev->msg_queue_core_ctx.ready_num);
+ queue_work(dev->core_workqueue, &msg_queue->core_work);
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+index 9418fcf740a82..ef28122a5ed49 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+@@ -76,12 +76,14 @@ void print_wrapper_info(struct device *dev, void __iomem *reg)
+
+ void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
+ {
+- writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++ writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
++ writel(0xF0C, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
+ }
+
+ void mxc_jpeg_disable_irq(void __iomem *reg, int slot)
+ {
+ writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++ writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+ }
+
+ void mxc_jpeg_sw_reset(void __iomem *reg)
+diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
+index 290df04c4d02c..a25fffb0b8ec5 100644
+--- a/drivers/media/platform/qcom/camss/camss-video.c
++++ b/drivers/media/platform/qcom/camss/camss-video.c
+@@ -495,7 +495,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+
+ ret = media_pipeline_start(&vdev->entity, &video->pipe);
+ if (ret < 0)
+- return ret;
++ goto flush_buffers;
+
+ ret = video_check_format(video);
+ if (ret < 0)
+@@ -524,6 +524,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+ error:
+ media_pipeline_stop(&vdev->entity);
+
++flush_buffers:
+ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
+
+ return ret;
+diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
+index 1118c40886d52..a157cac72e0ab 100644
+--- a/drivers/media/platform/qcom/camss/camss.c
++++ b/drivers/media/platform/qcom/camss/camss.c
+@@ -1465,6 +1465,14 @@ static int camss_configure_pd(struct camss *camss)
+ return camss->genpd_num;
+ }
+
++ /*
++ * If a platform device has just one power domain, then it is attached
++ * at platform_probe() level, thus there shall be no need and even no
++ * option to attach it again, this is the case for CAMSS on MSM8916.
++ */
++ if (camss->genpd_num == 1)
++ return 0;
++
+ camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
+ sizeof(*camss->genpd), GFP_KERNEL);
+ if (!camss->genpd)
+@@ -1698,6 +1706,9 @@ void camss_delete(struct camss *camss)
+
+ pm_runtime_disable(camss->dev);
+
++ if (camss->genpd_num == 1)
++ return;
++
+ for (i = 0; i < camss->genpd_num; i++) {
+ device_link_del(camss->genpd_link[i]);
+ dev_pm_domain_detach(camss->genpd[i], true);
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index c93d2906e4c7d..48c9084bb4dba 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -869,8 +869,8 @@ static int vcodec_domains_get(struct venus_core *core)
+ for (i = 0; i < res->vcodec_pmdomains_num; i++) {
+ pd = dev_pm_domain_attach_by_name(dev,
+ res->vcodec_pmdomains[i]);
+- if (IS_ERR(pd))
+- return PTR_ERR(pd);
++ if (IS_ERR_OR_NULL(pd))
++ return PTR_ERR(pd) ? : -ENODATA;
+ core->pmdomains[i] = pd;
+ }
+
+diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
+index 91cc8d58a663b..1791100b69353 100644
+--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
+@@ -1173,7 +1173,7 @@ int __init fimc_register_driver(void)
+ return platform_driver_register(&fimc_driver);
+ }
+
+-void __exit fimc_unregister_driver(void)
++void fimc_unregister_driver(void)
+ {
+ platform_driver_unregister(&fimc_driver);
+ }
+diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.c b/drivers/media/platform/samsung/exynos4-is/media-dev.c
+index 52b43ea040302..2f3071acb9c97 100644
+--- a/drivers/media/platform/samsung/exynos4-is/media-dev.c
++++ b/drivers/media/platform/samsung/exynos4-is/media-dev.c
+@@ -1380,9 +1380,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+
+ /* Find platform data for this sensor subdev */
+ for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
+- if (fmd->sensor[i].asd &&
+- fmd->sensor[i].asd->match.fwnode ==
+- of_fwnode_handle(subdev->dev->of_node))
++ if (fmd->sensor[i].asd == asd)
+ si = &fmd->sensor[i];
+
+ if (si == NULL)
+@@ -1474,7 +1472,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+ pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+- if (ret != EPROBE_DEFER)
++ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get pinctrl: %d\n", ret);
+ goto err_clk;
+ }
+@@ -1586,7 +1584,11 @@ static int __init fimc_md_init(void)
+ if (ret)
+ return ret;
+
+- return platform_driver_register(&fimc_md_driver);
++ ret = platform_driver_register(&fimc_md_driver);
++ if (ret)
++ fimc_unregister_driver();
++
++ return ret;
+ }
+
+ static void __exit fimc_md_exit(void)
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+index f85d1eebaface..7bdbe767500e6 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+@@ -1576,8 +1576,18 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = {
+ .port_num = MFC_NUM_PORTS_V7,
+ .buf_size = &buf_size_v7,
+ .fw_name[0] = "s5p-mfc-v7.fw",
+- .clk_names = {"mfc", "sclk_mfc"},
+- .num_clocks = 2,
++ .clk_names = {"mfc"},
++ .num_clocks = 1,
++};
++
++static struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
++ .version = MFC_VERSION_V7,
++ .version_bit = MFC_V7_BIT,
++ .port_num = MFC_NUM_PORTS_V7,
++ .buf_size = &buf_size_v7,
++ .fw_name[0] = "s5p-mfc-v7.fw",
++ .clk_names = {"mfc", "sclk_mfc"},
++ .num_clocks = 2,
+ };
+
+ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
+@@ -1647,6 +1657,9 @@ static const struct of_device_id exynos_mfc_match[] = {
+ }, {
+ .compatible = "samsung,mfc-v7",
+ .data = &mfc_drvdata_v7,
++ }, {
++ .compatible = "samsung,exynos3250-mfc",
++ .data = &mfc_drvdata_v7_3250,
+ }, {
+ .compatible = "samsung,mfc-v8",
+ .data = &mfc_drvdata_v8,
+diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
+index cefe6b7bfdc4e..1dbb89f0ddb8c 100644
+--- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
++++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
+@@ -925,6 +925,7 @@ static int configure_channels(struct c8sectpfei *fei)
+ if (ret) {
+ dev_err(fei->dev,
+ "configure_memdma_and_inputblock failed\n");
++ of_node_put(child);
+ goto err_unmap;
+ }
+ index++;
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+index 30d6c0c5161f4..484ac5f054d53 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+@@ -498,6 +498,7 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ struct v4l2_async_notifier *notifier = &bridge->notifier;
+ struct media_pad *pads = bridge->pads;
+ struct device *dev = csi2_dev->dev;
++ bool notifier_registered = false;
+ int ret;
+
+ mutex_init(&bridge->lock);
+@@ -519,8 +520,10 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+
+ /* Media Pads */
+
+- pads[SUN6I_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+- pads[SUN6I_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
++ pads[SUN6I_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
++ MEDIA_PAD_FL_MUST_CONNECT;
++ pads[SUN6I_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
++ MEDIA_PAD_FL_MUST_CONNECT;
+
+ ret = media_entity_pads_init(&subdev->entity, SUN6I_MIPI_CSI2_PAD_COUNT,
+ pads);
+@@ -533,12 +536,17 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ notifier->ops = &sun6i_mipi_csi2_notifier_ops;
+
+ ret = sun6i_mipi_csi2_bridge_source_setup(csi2_dev);
+- if (ret)
++ if (ret && ret != -ENODEV)
+ goto error_v4l2_notifier_cleanup;
+
+- ret = v4l2_async_subdev_nf_register(subdev, notifier);
+- if (ret < 0)
+- goto error_v4l2_notifier_cleanup;
++ /* Only register the notifier when a sensor is connected. */
++ if (ret != -ENODEV) {
++ ret = v4l2_async_subdev_nf_register(subdev, notifier);
++ if (ret < 0)
++ goto error_v4l2_notifier_cleanup;
++
++ notifier_registered = true;
++ }
+
+ /* V4L2 Subdev */
+
+@@ -549,7 +557,8 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ return 0;
+
+ error_v4l2_notifier_unregister:
+- v4l2_async_nf_unregister(notifier);
++ if (notifier_registered)
++ v4l2_async_nf_unregister(notifier);
+
+ error_v4l2_notifier_cleanup:
+ v4l2_async_nf_cleanup(notifier);
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+index b032ec13a683a..d993c09a48202 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+@@ -536,6 +536,7 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ struct v4l2_async_notifier *notifier = &bridge->notifier;
+ struct media_pad *pads = bridge->pads;
+ struct device *dev = csi2_dev->dev;
++ bool notifier_registered = false;
+ int ret;
+
+ mutex_init(&bridge->lock);
+@@ -557,8 +558,10 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+
+ /* Media Pads */
+
+- pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+- pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
++ pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
++ MEDIA_PAD_FL_MUST_CONNECT;
++ pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
++ MEDIA_PAD_FL_MUST_CONNECT;
+
+ ret = media_entity_pads_init(&subdev->entity,
+ SUN8I_A83T_MIPI_CSI2_PAD_COUNT, pads);
+@@ -571,12 +574,17 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops;
+
+ ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev);
+- if (ret)
++ if (ret && ret != -ENODEV)
+ goto error_v4l2_notifier_cleanup;
+
+- ret = v4l2_async_subdev_nf_register(subdev, notifier);
+- if (ret < 0)
+- goto error_v4l2_notifier_cleanup;
++ /* Only register the notifier when a sensor is connected. */
++ if (ret != -ENODEV) {
++ ret = v4l2_async_subdev_nf_register(subdev, notifier);
++ if (ret < 0)
++ goto error_v4l2_notifier_cleanup;
++
++ notifier_registered = true;
++ }
+
+ /* V4L2 Subdev */
+
+@@ -587,7 +595,8 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ return 0;
+
+ error_v4l2_notifier_unregister:
+- v4l2_async_nf_unregister(notifier);
++ if (notifier_registered)
++ v4l2_async_nf_unregister(notifier);
+
+ error_v4l2_notifier_cleanup:
+ v4l2_async_nf_cleanup(notifier);
+diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
+index 6b2768623c883..aa7a580dbecc0 100644
+--- a/drivers/media/radio/si470x/radio-si470x-usb.c
++++ b/drivers/media/radio/si470x/radio-si470x-usb.c
+@@ -727,8 +727,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
+
+ /* start radio */
+ retval = si470x_start_usb(radio);
+- if (retval < 0)
++ if (retval < 0 && !radio->int_in_running)
+ goto err_buf;
++ else if (retval < 0) /* in case of radio->int_in_running == 1 */
++ goto err_all;
+
+ /* set initial frequency */
+ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
+index 735b925da9984..91d8056666ec8 100644
+--- a/drivers/media/rc/imon.c
++++ b/drivers/media/rc/imon.c
+@@ -646,15 +646,14 @@ static int send_packet(struct imon_context *ictx)
+ pr_err_ratelimited("error submitting urb(%d)\n", retval);
+ } else {
+ /* Wait for transmission to complete (or abort) */
+- mutex_unlock(&ictx->lock);
+ retval = wait_for_completion_interruptible(
+ &ictx->tx.finished);
+ if (retval) {
+ usb_kill_urb(ictx->tx_urb);
+ pr_err_ratelimited("task interrupted\n");
+ }
+- mutex_lock(&ictx->lock);
+
++ ictx->tx.busy = false;
+ retval = ictx->tx.status;
+ if (retval)
+ pr_err_ratelimited("packet tx failed (%d)\n", retval);
+@@ -955,7 +954,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
+ if (ictx->disconnected)
+ return -ENODEV;
+
+- mutex_lock(&ictx->lock);
++ if (mutex_lock_interruptible(&ictx->lock))
++ return -ERESTARTSYS;
+
+ if (!ictx->dev_present_intf0) {
+ pr_err_ratelimited("no iMON device present\n");
+diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+index 82620613d56b8..dff7265a42ca2 100644
+--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+@@ -459,26 +459,20 @@ fail_dmx_conn:
+ for (j = j - 1; j >= 0; --j)
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx,
+ &dvb->dmx_fe[j]);
+-fail_dmx_dev:
+ dvb_dmxdev_release(&dvb->dmx_dev);
+-fail_dmx:
++fail_dmx_dev:
+ dvb_dmx_release(&dvb->demux);
++fail_dmx:
++fail_demod_probe:
++ for (i = i - 1; i >= 0; --i) {
++ dvb_unregister_frontend(dvb->fe[i]);
+ fail_fe:
+- for (j = i; j >= 0; --j)
+- dvb_unregister_frontend(dvb->fe[j]);
++ dvb_module_release(dvb->i2c_client_tuner[i]);
+ fail_tuner_probe:
+- for (j = i; j >= 0; --j)
+- if (dvb->i2c_client_tuner[j])
+- dvb_module_release(dvb->i2c_client_tuner[j]);
+-
+-fail_demod_probe:
+- for (j = i; j >= 0; --j)
+- if (dvb->i2c_client_demod[j])
+- dvb_module_release(dvb->i2c_client_demod[j]);
+-
++ dvb_module_release(dvb->i2c_client_demod[i]);
++ }
+ fail_adapter:
+ dvb_unregister_adapter(&dvb->adapter);
+-
+ fail_i2c:
+ i2c_del_adapter(&dvb->i2c_adapter);
+
+diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c
+index 2ae7a0f11ebfc..e82cfa5ffbf47 100644
+--- a/drivers/media/test-drivers/vimc/vimc-core.c
++++ b/drivers/media/test-drivers/vimc/vimc-core.c
+@@ -433,7 +433,7 @@ static int __init vimc_init(void)
+ if (ret) {
+ dev_err(&vimc_pdev.dev,
+ "platform driver registration failed (err=%d)\n", ret);
+- platform_driver_unregister(&vimc_pdrv);
++ platform_device_unregister(&vimc_pdev);
+ return ret;
+ }
+
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index 99139a8cd4c4f..331a3f4286d2e 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -961,6 +961,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ if (dev->has_compose_cap) {
+ v4l2_rect_set_min_size(compose, &min_rect);
+ v4l2_rect_set_max_size(compose, &max_rect);
++ v4l2_rect_map_inside(compose, &fmt);
+ }
+ dev->fmt_cap_rect = fmt;
+ tpg_s_buf_height(&dev->tpg, fmt.height);
+diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
+index cf15988dfb510..7d78ee09be5e1 100644
+--- a/drivers/media/usb/dvb-usb/az6027.c
++++ b/drivers/media/usb/dvb-usb/az6027.c
+@@ -975,6 +975,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
+ if (msg[i].addr == 0x99) {
+ req = 0xBE;
+ index = 0;
++ if (msg[i].len < 1) {
++ i = -EOPNOTSUPP;
++ break;
++ }
+ value = msg[i].buf[0] & 0x00ff;
+ length = 1;
+ az6027_usb_out_op(d, req, value, index, data, length);
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+index 61439c8f33cab..58eea8ab54779 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+@@ -81,7 +81,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+
+ ret = dvb_usb_adapter_stream_init(adap);
+ if (ret)
+- return ret;
++ goto stream_init_err;
+
+ ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
+ if (ret)
+@@ -114,6 +114,8 @@ frontend_init_err:
+ dvb_usb_adapter_dvb_exit(adap);
+ dvb_init_err:
+ dvb_usb_adapter_stream_exit(adap);
++stream_init_err:
++ kfree(adap->priv);
+ return ret;
+ }
+
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
+index 50d012ba3c02e..7781ebd7ee95f 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
+@@ -155,6 +155,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
+ * then return an error.
+ */
+ if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
++ ctrl->is_new = 1;
+ return -ERANGE;
+ }
+ return ret;
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+index 1f85828d6694d..322f9f715b65b 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+@@ -1762,7 +1762,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+ else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
+ qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len);
+
+- if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) {
++ if ((!qmenu && !qmenu_int) || (qmenu_int && max >= qmenu_int_len)) {
+ handler_set_err(hdl, -EINVAL);
+ return NULL;
+ }
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index e6fd355a2e92c..de83714f0d403 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1347,23 +1347,23 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
+ case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break;
+ case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break;
+ case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break;
+- case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break;
+- case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break;
+- case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break;
+- case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break;
+- case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break;
+- case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break;
+- case V4L2_PIX_FMT_P010: descr = "10-bit Y/CbCr 4:2:0"; break;
+- case V4L2_PIX_FMT_NV12_4L4: descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
+- case V4L2_PIX_FMT_NV12_16L16: descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
+- case V4L2_PIX_FMT_NV12_32L32: descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
+- case V4L2_PIX_FMT_P010_4L4: descr = "10-bit Y/CbCr 4:2:0 (4x4 Linear)"; break;
+- case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break;
+- case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break;
+- case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break;
+- case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break;
+- case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
+- case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
++ case V4L2_PIX_FMT_NV12: descr = "Y/UV 4:2:0"; break;
++ case V4L2_PIX_FMT_NV21: descr = "Y/VU 4:2:0"; break;
++ case V4L2_PIX_FMT_NV16: descr = "Y/UV 4:2:2"; break;
++ case V4L2_PIX_FMT_NV61: descr = "Y/VU 4:2:2"; break;
++ case V4L2_PIX_FMT_NV24: descr = "Y/UV 4:4:4"; break;
++ case V4L2_PIX_FMT_NV42: descr = "Y/VU 4:4:4"; break;
++ case V4L2_PIX_FMT_P010: descr = "10-bit Y/UV 4:2:0"; break;
++ case V4L2_PIX_FMT_NV12_4L4: descr = "Y/UV 4:2:0 (4x4 Linear)"; break;
++ case V4L2_PIX_FMT_NV12_16L16: descr = "Y/UV 4:2:0 (16x16 Linear)"; break;
++ case V4L2_PIX_FMT_NV12_32L32: descr = "Y/UV 4:2:0 (32x32 Linear)"; break;
++ case V4L2_PIX_FMT_P010_4L4: descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break;
++ case V4L2_PIX_FMT_NV12M: descr = "Y/UV 4:2:0 (N-C)"; break;
++ case V4L2_PIX_FMT_NV21M: descr = "Y/VU 4:2:0 (N-C)"; break;
++ case V4L2_PIX_FMT_NV16M: descr = "Y/UV 4:2:2 (N-C)"; break;
++ case V4L2_PIX_FMT_NV61M: descr = "Y/VU 4:2:2 (N-C)"; break;
++ case V4L2_PIX_FMT_NV12MT: descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
++ case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
+ case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break;
+ case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break;
+diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
+index 52312ce2ba056..f2c4393595574 100644
+--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
++++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
+@@ -36,12 +36,11 @@ struct videobuf_dma_contig_memory {
+
+ static int __videobuf_dc_alloc(struct device *dev,
+ struct videobuf_dma_contig_memory *mem,
+- unsigned long size, gfp_t flags)
++ unsigned long size)
+ {
+ mem->size = size;
+- mem->vaddr = dma_alloc_coherent(dev, mem->size,
+- &mem->dma_handle, flags);
+-
++ mem->vaddr = dma_alloc_coherent(dev, mem->size, &mem->dma_handle,
++ GFP_KERNEL);
+ if (!mem->vaddr) {
+ dev_err(dev, "memory alloc size %ld failed\n", mem->size);
+ return -ENOMEM;
+@@ -258,8 +257,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
+ return videobuf_dma_contig_user_get(mem, vb);
+
+ /* allocate memory for the read() method */
+- if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
+- GFP_KERNEL))
++ if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size)))
+ return -ENOMEM;
+ break;
+ case V4L2_MEMORY_OVERLAY:
+@@ -295,22 +293,18 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+- if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
+- GFP_KERNEL | __GFP_COMP))
++ if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize)))
+ goto error;
+
+- /* Try to remap memory */
+- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+-
+ /* the "vm_pgoff" is just used in v4l2 to find the
+ * corresponding buffer data structure which is allocated
+ * earlier and it does not mean the offset from the physical
+ * buffer start address as usual. So set it to 0 to pass
+- * the sanity check in vm_iomap_memory().
++ * the sanity check in dma_mmap_coherent().
+ */
+ vma->vm_pgoff = 0;
+-
+- retval = vm_iomap_memory(vma, mem->dma_handle, mem->size);
++ retval = dma_mmap_coherent(q->dev, vma, mem->vaddr, mem->dma_handle,
++ mem->size);
+ if (retval) {
+ dev_err(q->dev, "mmap: remap failed with error %d. ",
+ retval);
+diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
+index 4316988d791a5..61c288d403750 100644
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -317,6 +317,9 @@ int rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
+ regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_PHYMEM_MASK,
+ RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0));
+
++ /* DMA Transfer is not supported */
++ regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_HS, 0);
++
+ if (rpc->type == RPCIF_RCAR_GEN3)
+ regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
+ RPCIF_PHYCNT_STRTIM(7), RPCIF_PHYCNT_STRTIM(7));
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index ba84145195158..04115cd92433b 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -2116,6 +2116,11 @@ static int msb_init_disk(struct memstick_dev *card)
+ dbg("Set total disk size to %lu sectors", capacity);
+
+ msb->io_queue = alloc_ordered_workqueue("ms_block", WQ_MEM_RECLAIM);
++ if (!msb->io_queue) {
++ rc = -ENOMEM;
++ goto out_cleanup_disk;
++ }
++
+ INIT_WORK(&msb->io_work, msb_io_work);
+ sg_init_table(msb->prealloc_sg, MS_BLOCK_MAX_SEGS+1);
+
+@@ -2125,10 +2130,12 @@ static int msb_init_disk(struct memstick_dev *card)
+ msb_start(card);
+ rc = device_add_disk(&card->dev, msb->disk, NULL);
+ if (rc)
+- goto out_cleanup_disk;
++ goto out_destroy_workqueue;
+ dbg("Disk added");
+ return 0;
+
++out_destroy_workqueue:
++ destroy_workqueue(msb->io_queue);
+ out_cleanup_disk:
+ put_disk(msb->disk);
+ out_free_tag_set:
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index abb58ab1a1a4f..3e8becef3cb05 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -1968,6 +1968,7 @@ config MFD_ROHM_BD957XMUF
+ depends on I2C=y
+ depends on OF
+ select REGMAP_I2C
++ select REGMAP_IRQ
+ select MFD_CORE
+ help
+ Select this option to get support for the ROHM BD9576MUF and
+diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
+index 88a212a8168cf..880c41fa7021b 100644
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -842,7 +842,7 @@ static void axp20x_power_off(void)
+ AXP20X_OFF);
+
+ /* Give capacitors etc. time to drain to avoid kernel panic msg. */
+- msleep(500);
++ mdelay(500);
+ }
+
+ int axp20x_match_device(struct axp20x_dev *axp20x)
+diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
+index 4b8ff947762f2..9f3c4a01b4c1c 100644
+--- a/drivers/mfd/qcom-pm8008.c
++++ b/drivers/mfd/qcom-pm8008.c
+@@ -215,8 +215,8 @@ static int pm8008_probe(struct i2c_client *client)
+
+ dev = &client->dev;
+ regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
+- if (!regmap)
+- return -ENODEV;
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
+
+ i2c_set_clientdata(client, regmap);
+
+diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
+index 71bc34b74bc9c..8fea0e511550a 100644
+--- a/drivers/mfd/qcom_rpm.c
++++ b/drivers/mfd/qcom_rpm.c
+@@ -547,7 +547,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ init_completion(&rpm->ack);
+
+ /* Enable message RAM clock */
+- rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
++ rpm->ramclk = devm_clk_get_enabled(&pdev->dev, "ram");
+ if (IS_ERR(rpm->ramclk)) {
+ ret = PTR_ERR(rpm->ramclk);
+ if (ret == -EPROBE_DEFER)
+@@ -558,7 +558,6 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ */
+ rpm->ramclk = NULL;
+ }
+- clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
+
+ irq_ack = platform_get_irq_byname(pdev, "ack");
+ if (irq_ack < 0)
+@@ -673,22 +672,11 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ if (ret)
+ dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n");
+
+- return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+-}
+-
+-static int qcom_rpm_remove(struct platform_device *pdev)
+-{
+- struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
+-
+- of_platform_depopulate(&pdev->dev);
+- clk_disable_unprepare(rpm->ramclk);
+-
+- return 0;
++ return devm_of_platform_populate(&pdev->dev);
+ }
+
+ static struct platform_driver qcom_rpm_driver = {
+ .probe = qcom_rpm_probe,
+- .remove = qcom_rpm_remove,
+ .driver = {
+ .name = "qcom_rpm",
+ .of_match_table = qcom_rpm_of_match,
+diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
+index 375f692ae9d68..fb95a2d5cef48 100644
+--- a/drivers/misc/cxl/guest.c
++++ b/drivers/misc/cxl/guest.c
+@@ -965,10 +965,10 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+ * if it returns an error!
+ */
+ if ((rc = cxl_register_afu(afu)))
+- goto err_put1;
++ goto err_put_dev;
+
+ if ((rc = cxl_sysfs_afu_add(afu)))
+- goto err_put1;
++ goto err_del_dev;
+
+ /*
+ * pHyp doesn't expose the programming models supported by the
+@@ -984,7 +984,7 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+ afu->modes_supported = CXL_MODE_DIRECTED;
+
+ if ((rc = cxl_afu_select_best_mode(afu)))
+- goto err_put2;
++ goto err_remove_sysfs;
+
+ adapter->afu[afu->slice] = afu;
+
+@@ -1004,10 +1004,12 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+
+ return 0;
+
+-err_put2:
++err_remove_sysfs:
+ cxl_sysfs_afu_remove(afu);
+-err_put1:
+- device_unregister(&afu->dev);
++err_del_dev:
++ device_del(&afu->dev);
++err_put_dev:
++ put_device(&afu->dev);
+ free = false;
+ guest_release_serr_irq(afu);
+ err2:
+@@ -1141,18 +1143,20 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic
+ * even if it returns an error!
+ */
+ if ((rc = cxl_register_adapter(adapter)))
+- goto err_put1;
++ goto err_put_dev;
+
+ if ((rc = cxl_sysfs_adapter_add(adapter)))
+- goto err_put1;
++ goto err_del_dev;
+
+ /* release the context lock as the adapter is configured */
+ cxl_adapter_context_unlock(adapter);
+
+ return adapter;
+
+-err_put1:
+- device_unregister(&adapter->dev);
++err_del_dev:
++ device_del(&adapter->dev);
++err_put_dev:
++ put_device(&adapter->dev);
+ free = false;
+ cxl_guest_remove_chardev(adapter);
+ err1:
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index 3de0aea62ade4..0ff944860dda9 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -387,6 +387,7 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
+ rc = get_phb_index(np, phb_index);
+ if (rc) {
+ pr_err("cxl: invalid phb index\n");
++ of_node_put(np);
+ return rc;
+ }
+
+@@ -1164,10 +1165,10 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+ * if it returns an error!
+ */
+ if ((rc = cxl_register_afu(afu)))
+- goto err_put1;
++ goto err_put_dev;
+
+ if ((rc = cxl_sysfs_afu_add(afu)))
+- goto err_put1;
++ goto err_del_dev;
+
+ adapter->afu[afu->slice] = afu;
+
+@@ -1176,10 +1177,12 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+
+ return 0;
+
+-err_put1:
++err_del_dev:
++ device_del(&afu->dev);
++err_put_dev:
+ pci_deconfigure_afu(afu);
+ cxl_debugfs_afu_remove(afu);
+- device_unregister(&afu->dev);
++ put_device(&afu->dev);
+ return rc;
+
+ err_free_native:
+@@ -1667,23 +1670,25 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
+ * even if it returns an error!
+ */
+ if ((rc = cxl_register_adapter(adapter)))
+- goto err_put1;
++ goto err_put_dev;
+
+ if ((rc = cxl_sysfs_adapter_add(adapter)))
+- goto err_put1;
++ goto err_del_dev;
+
+ /* Release the context lock as adapter is configured */
+ cxl_adapter_context_unlock(adapter);
+
+ return adapter;
+
+-err_put1:
++err_del_dev:
++ device_del(&adapter->dev);
++err_put_dev:
+ /* This should mirror cxl_remove_adapter, except without the
+ * sysfs parts
+ */
+ cxl_debugfs_adapter_remove(adapter);
+ cxl_deconfigure_adapter(adapter);
+- device_unregister(&adapter->dev);
++ put_device(&adapter->dev);
+ return ERR_PTR(rc);
+
+ err_release:
+diff --git a/drivers/misc/lkdtm/cfi.c b/drivers/misc/lkdtm/cfi.c
+index 71483cb1e422a..f4fd30f7a9a0e 100644
+--- a/drivers/misc/lkdtm/cfi.c
++++ b/drivers/misc/lkdtm/cfi.c
+@@ -51,7 +51,11 @@ static void lkdtm_CFI_FORWARD_PROTO(void)
+ # ifdef CONFIG_ARM64_BTI_KERNEL
+ # define __no_pac "branch-protection=bti"
+ # else
+-# define __no_pac "branch-protection=none"
++# ifdef CONFIG_CC_HAS_BRANCH_PROT_PAC_RET
++# define __no_pac "branch-protection=none"
++# else
++# define __no_pac "sign-return-address=none"
++# endif
+ # endif
+ # define __no_ret_protection __noscs __attribute__((__target__(__no_pac)))
+ #else
+diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
+index e401a51596b9c..92ab49705f645 100644
+--- a/drivers/misc/ocxl/config.c
++++ b/drivers/misc/ocxl/config.c
+@@ -193,6 +193,18 @@ static int read_dvsec_vendor(struct pci_dev *dev)
+ return 0;
+ }
+
++/**
++ * get_dvsec_vendor0() - Find a related PCI device (function 0)
++ * @dev: PCI device to match
++ * @dev0: The PCI device (function 0) found
++ * @out_pos: The position of PCI device (function 0)
++ *
++ * Returns 0 on success, negative on failure.
++ *
++ * NOTE: If it's successful, the reference of dev0 is increased,
++ * so after using it, the callers must call pci_dev_put() to give
++ * up the reference.
++ */
+ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+ int *out_pos)
+ {
+@@ -202,10 +214,14 @@ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+ dev = get_function_0(dev);
+ if (!dev)
+ return -1;
++ } else {
++ dev = pci_dev_get(dev);
+ }
+ pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
+- if (!pos)
++ if (!pos) {
++ pci_dev_put(dev);
+ return -1;
++ }
+ *dev0 = dev;
+ *out_pos = pos;
+ return 0;
+@@ -222,6 +238,7 @@ int ocxl_config_get_reset_reload(struct pci_dev *dev, int *val)
+
+ pci_read_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+ &reset_reload);
++ pci_dev_put(dev0);
+ *val = !!(reset_reload & BIT(0));
+ return 0;
+ }
+@@ -243,6 +260,7 @@ int ocxl_config_set_reset_reload(struct pci_dev *dev, int val)
+ reset_reload &= ~BIT(0);
+ pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+ reset_reload);
++ pci_dev_put(dev0);
+ return 0;
+ }
+
+diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
+index d46dba2df5a10..452d5777a0e4c 100644
+--- a/drivers/misc/ocxl/file.c
++++ b/drivers/misc/ocxl/file.c
+@@ -541,8 +541,11 @@ int ocxl_file_register_afu(struct ocxl_afu *afu)
+ goto err_put;
+
+ rc = device_register(&info->dev);
+- if (rc)
+- goto err_put;
++ if (rc) {
++ free_minor(info);
++ put_device(&info->dev);
++ return rc;
++ }
+
+ rc = ocxl_sysfs_register_afu(info);
+ if (rc)
+diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
+index d7ef61e602ede..b836936e97471 100644
+--- a/drivers/misc/sgi-gru/grufault.c
++++ b/drivers/misc/sgi-gru/grufault.c
+@@ -648,6 +648,7 @@ int gru_handle_user_call_os(unsigned long cb)
+ if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
+ return -EINVAL;
+
++again:
+ gts = gru_find_lock_gts(cb);
+ if (!gts)
+ return -EINVAL;
+@@ -656,7 +657,11 @@ int gru_handle_user_call_os(unsigned long cb)
+ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
+ goto exit;
+
+- gru_check_context_placement(gts);
++ if (gru_check_context_placement(gts)) {
++ gru_unlock_gts(gts);
++ gru_unload_context(gts, 1);
++ goto again;
++ }
+
+ /*
+ * CCH may contain stale data if ts_force_cch_reload is set.
+@@ -874,7 +879,11 @@ int gru_set_context_option(unsigned long arg)
+ } else {
+ gts->ts_user_blade_id = req.val1;
+ gts->ts_user_chiplet_id = req.val0;
+- gru_check_context_placement(gts);
++ if (gru_check_context_placement(gts)) {
++ gru_unlock_gts(gts);
++ gru_unload_context(gts, 1);
++ return ret;
++ }
+ }
+ break;
+ case sco_gseg_owner:
+diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
+index 9afda47efbf2e..3a16eb8e03f73 100644
+--- a/drivers/misc/sgi-gru/grumain.c
++++ b/drivers/misc/sgi-gru/grumain.c
+@@ -716,9 +716,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru,
+ * chiplet. Misassignment can occur if the process migrates to a different
+ * blade or if the user changes the selected blade/chiplet.
+ */
+-void gru_check_context_placement(struct gru_thread_state *gts)
++int gru_check_context_placement(struct gru_thread_state *gts)
+ {
+ struct gru_state *gru;
++ int ret = 0;
+
+ /*
+ * If the current task is the context owner, verify that the
+@@ -726,15 +727,23 @@ void gru_check_context_placement(struct gru_thread_state *gts)
+ * references. Pthread apps use non-owner references to the CBRs.
+ */
+ gru = gts->ts_gru;
++ /*
++ * If gru or gts->ts_tgid_owner isn't initialized properly, return
++ * success to indicate that the caller does not need to unload the
++ * gru context.The caller is responsible for their inspection and
++ * reinitialization if needed.
++ */
+ if (!gru || gts->ts_tgid_owner != current->tgid)
+- return;
++ return ret;
+
+ if (!gru_check_chiplet_assignment(gru, gts)) {
+ STAT(check_context_unload);
+- gru_unload_context(gts, 1);
++ ret = -EINVAL;
+ } else if (gru_retarget_intr(gts)) {
+ STAT(check_context_retarget_intr);
+ }
++
++ return ret;
+ }
+
+
+@@ -934,7 +943,12 @@ again:
+ mutex_lock(>s->ts_ctxlock);
+ preempt_disable();
+
+- gru_check_context_placement(gts);
++ if (gru_check_context_placement(gts)) {
++ preempt_enable();
++ mutex_unlock(>s->ts_ctxlock);
++ gru_unload_context(gts, 1);
++ return VM_FAULT_NOPAGE;
++ }
+
+ if (!gts->ts_gru) {
+ STAT(load_user_context);
+diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
+index 5efc869fe59a0..f4a5a787685fb 100644
+--- a/drivers/misc/sgi-gru/grutables.h
++++ b/drivers/misc/sgi-gru/grutables.h
+@@ -632,7 +632,7 @@ extern int gru_user_flush_tlb(unsigned long arg);
+ extern int gru_user_unload_context(unsigned long arg);
+ extern int gru_get_exception_detail(unsigned long arg);
+ extern int gru_set_context_option(unsigned long address);
+-extern void gru_check_context_placement(struct gru_thread_state *gts);
++extern int gru_check_context_placement(struct gru_thread_state *gts);
+ extern int gru_cpu_fault_map_id(void);
+ extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
+ extern void gru_flush_all_tlb(struct gru_state *gru);
+diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
+index 017c2f7d62871..7dd86a9858aba 100644
+--- a/drivers/misc/tifm_7xx1.c
++++ b/drivers/misc/tifm_7xx1.c
+@@ -190,7 +190,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
+ spin_unlock_irqrestore(&fm->lock, flags);
+ }
+ if (sock)
+- tifm_free_device(&sock->dev);
++ put_device(&sock->dev);
+ }
+ spin_lock_irqsave(&fm->lock, flags);
+ }
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index 3662bf5320ce5..72b664ed90cf6 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1259,7 +1259,7 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ */
+ err = sd_read_ext_reg(card, 0, 0, 0, 512, gen_info_buf);
+ if (err) {
+- pr_warn("%s: error %d reading general info of SD ext reg\n",
++ pr_err("%s: error %d reading general info of SD ext reg\n",
+ mmc_hostname(card->host), err);
+ goto out;
+ }
+@@ -1273,7 +1273,12 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ /* Number of extensions to be find. */
+ num_ext = gen_info_buf[4];
+
+- /* We support revision 0, but limit it to 512 bytes for simplicity. */
++ /*
++ * We only support revision 0 and limit it to 512 bytes for simplicity.
++ * No matter what, let's return zero to allow us to continue using the
++ * card, even if we can't support the features from the SD function
++ * extensions registers.
++ */
+ if (rev != 0 || len > 512) {
+ pr_warn("%s: non-supported SD ext reg layout\n",
+ mmc_hostname(card->host));
+@@ -1288,7 +1293,7 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ for (i = 0; i < num_ext; i++) {
+ err = sd_parse_ext_reg(card, gen_info_buf, &next_ext_addr);
+ if (err) {
+- pr_warn("%s: error %d parsing SD ext reg\n",
++ pr_err("%s: error %d parsing SD ext reg\n",
+ mmc_hostname(card->host), err);
+ goto out;
+ }
+diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c
+index bfb8efeb7eb80..d01df01d4b4d1 100644
+--- a/drivers/mmc/host/alcor.c
++++ b/drivers/mmc/host/alcor.c
+@@ -1114,7 +1114,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ alcor_hw_init(host);
+
+ dev_set_drvdata(&pdev->dev, host);
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto free_host;
++
+ return 0;
+
+ free_host:
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 91d52ba7a39fc..bb9bbf1c927b6 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -2222,6 +2222,7 @@ static int atmci_init_slot(struct atmel_mci *host,
+ {
+ struct mmc_host *mmc;
+ struct atmel_mci_slot *slot;
++ int ret;
+
+ mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
+ if (!mmc)
+@@ -2305,11 +2306,13 @@ static int atmci_init_slot(struct atmel_mci *host,
+
+ host->slot[id] = slot;
+ mmc_regulator_get_supply(mmc);
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret) {
++ mmc_free_host(mmc);
++ return ret;
++ }
+
+ if (gpio_is_valid(slot->detect_pin)) {
+- int ret;
+-
+ timer_setup(&slot->detect_timer, atmci_detect_change, 0);
+
+ ret = request_irq(gpio_to_irq(slot->detect_pin),
+diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
+index 6ba0d63b8c078..39c6707fdfdbc 100644
+--- a/drivers/mmc/host/litex_mmc.c
++++ b/drivers/mmc/host/litex_mmc.c
+@@ -502,6 +502,7 @@ static int litex_mmc_irq_init(struct platform_device *pdev,
+
+ use_polling:
+ host->mmc->caps |= MMC_CAP_NEEDS_POLL;
++ host->irq = 0;
+ return 0;
+ }
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index fc462995cf94a..4fd3d545e4081 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1291,7 +1291,9 @@ static int meson_mmc_probe(struct platform_device *pdev)
+ }
+
+ mmc->ops = &meson_mmc_ops;
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto err_free_irq;
+
+ return 0;
+
+diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
+index 012aa85489d86..b9e5dfe74e5c7 100644
+--- a/drivers/mmc/host/mmci.c
++++ b/drivers/mmc/host/mmci.c
+@@ -2256,7 +2256,9 @@ static int mmci_probe(struct amba_device *dev,
+ pm_runtime_set_autosuspend_delay(&dev->dev, 50);
+ pm_runtime_use_autosuspend(&dev->dev);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto clk_disable;
+
+ pm_runtime_put(&dev->dev);
+ return 0;
+diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
+index dfc3ffd5b1f8c..52ed30f2d9f4f 100644
+--- a/drivers/mmc/host/moxart-mmc.c
++++ b/drivers/mmc/host/moxart-mmc.c
+@@ -665,7 +665,9 @@ static int moxart_probe(struct platform_device *pdev)
+ goto out;
+
+ dev_set_drvdata(dev, mmc);
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto out;
+
+ dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width);
+
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 2cf0413407ea2..668f865f3efb0 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1143,7 +1143,9 @@ static int mxcmci_probe(struct platform_device *pdev)
+
+ timer_setup(&host->watchdog, mxcmci_watchdog, 0);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto out_free_dma;
+
+ return 0;
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index fca30add563e9..4bd7447552055 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1946,7 +1946,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ if (!ret)
+ mmc->caps |= MMC_CAP_SDIO_IRQ;
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto err_irq;
+
+ if (mmc_pdata(host)->name != NULL) {
+ ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name);
+diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
+index e4003f6058eb5..2a988f942b6ca 100644
+--- a/drivers/mmc/host/pxamci.c
++++ b/drivers/mmc/host/pxamci.c
+@@ -763,7 +763,12 @@ static int pxamci_probe(struct platform_device *pdev)
+ dev_warn(dev, "gpio_ro and get_ro() both defined\n");
+ }
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret) {
++ if (host->pdata && host->pdata->exit)
++ host->pdata->exit(dev, mmc);
++ goto out;
++ }
+
+ return 0;
+
+diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
+index c4abfee1ebae1..e4c490729c98e 100644
+--- a/drivers/mmc/host/renesas_sdhi.h
++++ b/drivers/mmc/host/renesas_sdhi.h
+@@ -44,6 +44,7 @@ struct renesas_sdhi_quirks {
+ bool fixed_addr_mode;
+ bool dma_one_rx_only;
+ bool manual_tap_correction;
++ bool old_info1_layout;
+ u32 hs400_bad_taps;
+ const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
+ };
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index b970699743e0a..e38d0e8b8e0ed 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -546,7 +546,7 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
+ SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
+ sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
+
+- if (priv->adjust_hs400_calib_table)
++ if (priv->quirks && (priv->quirks->hs400_calib_table || priv->quirks->hs400_bad_taps))
+ renesas_sdhi_adjust_hs400_mode_disable(host);
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+@@ -1068,11 +1068,14 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ if (ver >= SDHI_VER_GEN3_SD)
+ host->get_timeout_cycles = renesas_sdhi_gen3_get_cycles;
+
++ /* Check for SCC so we can reset it if needed */
++ if (of_data && of_data->scc_offset && ver >= SDHI_VER_GEN2_SDR104)
++ priv->scc_ctl = host->ctl + of_data->scc_offset;
++
+ /* Enable tuning iff we have an SCC and a supported mode */
+- if (of_data && of_data->scc_offset &&
+- (host->mmc->caps & MMC_CAP_UHS_SDR104 ||
+- host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
+- MMC_CAP2_HS400_1_8V))) {
++ if (priv->scc_ctl && (host->mmc->caps & MMC_CAP_UHS_SDR104 ||
++ host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
++ MMC_CAP2_HS400_1_8V))) {
+ const struct renesas_sdhi_scc *taps = of_data->taps;
+ bool use_4tap = quirks && quirks->hs400_4taps;
+ bool hit = false;
+@@ -1092,7 +1095,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ if (!hit)
+ dev_warn(&host->pdev->dev, "Unknown clock rate for tuning\n");
+
+- priv->scc_ctl = host->ctl + of_data->scc_offset;
+ host->check_retune = renesas_sdhi_check_scc_error;
+ host->ops.execute_tuning = renesas_sdhi_execute_tuning;
+ host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
+diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+index 42937596c4c41..7c81c2680701f 100644
+--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
++++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+@@ -49,7 +49,8 @@
+ /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
+ #define INFO1_CLEAR 0
+ #define INFO1_MASK_CLEAR GENMASK_ULL(31, 0)
+-#define INFO1_DTRANEND1 BIT(17)
++#define INFO1_DTRANEND1 BIT(20)
++#define INFO1_DTRANEND1_OLD BIT(17)
+ #define INFO1_DTRANEND0 BIT(16)
+
+ /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+@@ -165,6 +166,7 @@ static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400_one_rx = {
+ .hs400_disabled = true,
+ .hs400_4taps = true,
+ .dma_one_rx_only = true,
++ .old_info1_layout = true,
+ };
+
+ static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
+diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
+index e1580f78c6b2d..8098726dcc0bf 100644
+--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
++++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
+@@ -1474,6 +1474,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ struct realtek_pci_sdmmc *host;
+ struct rtsx_pcr *pcr;
+ struct pcr_handle *handle = pdev->dev.platform_data;
++ int ret;
+
+ if (!handle)
+ return -ENXIO;
+@@ -1511,7 +1512,13 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_use_autosuspend(&pdev->dev);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret) {
++ pm_runtime_dont_use_autosuspend(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++ mmc_free_host(mmc);
++ return ret;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
+index 5fe4528e296e6..1be3a355f10d5 100644
+--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
++++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
+@@ -1332,6 +1332,7 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+ #ifdef RTSX_USB_USE_LEDS_CLASS
+ int err;
+ #endif
++ int ret;
+
+ ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent));
+ if (!ucr)
+@@ -1368,7 +1369,15 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+ INIT_WORK(&host->led_work, rtsx_usb_update_led);
+
+ #endif
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret) {
++#ifdef RTSX_USB_USE_LEDS_CLASS
++ led_classdev_unregister(&host->led);
++#endif
++ mmc_free_host(mmc);
++ pm_runtime_disable(&pdev->dev);
++ return ret;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
+index 3f5977979cf25..6c4f43e112826 100644
+--- a/drivers/mmc/host/sdhci_f_sdh30.c
++++ b/drivers/mmc/host/sdhci_f_sdh30.c
+@@ -168,6 +168,9 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+ if (reg & SDHCI_CAN_DO_8BIT)
+ priv->vendor_hs200 = F_SDH30_EMMC_HS200;
+
++ if (!(reg & SDHCI_TIMEOUT_CLK_MASK))
++ host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
++
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_add_host;
+diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c
+index 8d037c2071abc..497791ffada6d 100644
+--- a/drivers/mmc/host/toshsd.c
++++ b/drivers/mmc/host/toshsd.c
+@@ -651,7 +651,9 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ if (ret)
+ goto unmap;
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto free_irq;
+
+ base = pci_resource_start(pdev, 0);
+ dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq);
+@@ -660,6 +662,8 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ return 0;
+
++free_irq:
++ free_irq(pdev->irq, host);
+ unmap:
+ pci_iounmap(pdev, host->ioaddr);
+ release:
+diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
+index 88662a90ed960..a2b0d9461665b 100644
+--- a/drivers/mmc/host/via-sdmmc.c
++++ b/drivers/mmc/host/via-sdmmc.c
+@@ -1151,7 +1151,9 @@ static int via_sd_probe(struct pci_dev *pcidev,
+ pcidev->subsystem_device == 0x3891)
+ sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY;
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto unmap;
+
+ return 0;
+
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index 97beece62fec4..ab36ec4797478 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2299,14 +2299,14 @@ static int vub300_probe(struct usb_interface *interface,
+ 0x0000, 0x0000, &vub300->system_port_status,
+ sizeof(vub300->system_port_status), 1000);
+ if (retval < 0) {
+- goto error4;
++ goto error5;
+ } else if (sizeof(vub300->system_port_status) == retval) {
+ vub300->card_present =
+ (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0;
+ vub300->read_only =
+ (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0;
+ } else {
+- goto error4;
++ goto error5;
+ }
+ usb_set_intfdata(interface, vub300);
+ INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread);
+@@ -2329,8 +2329,13 @@ static int vub300_probe(struct usb_interface *interface,
+ "USB vub300 remote SDIO host controller[%d]"
+ "connected with no SD/SDIO card inserted\n",
+ interface_to_InterfaceNumber(interface));
+- mmc_add_host(mmc);
++ retval = mmc_add_host(mmc);
++ if (retval)
++ goto error6;
++
+ return 0;
++error6:
++ del_timer_sync(&vub300->inactivity_timer);
+ error5:
+ mmc_free_host(mmc);
+ /*
+diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
+index 67ecd342fe5f1..7c7ec8d10232b 100644
+--- a/drivers/mmc/host/wbsd.c
++++ b/drivers/mmc/host/wbsd.c
+@@ -1698,7 +1698,17 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma,
+ */
+ wbsd_init_device(host);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret) {
++ if (!pnp)
++ wbsd_chip_poweroff(host);
++
++ wbsd_release_resources(host);
++ wbsd_free_mmc(dev);
++
++ mmc_free_host(mmc);
++ return ret;
++ }
+
+ pr_info("%s: W83L51xD", mmc_hostname(mmc));
+ if (host->chip_id != 0)
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 9b5c503e3a3fc..9aa3027ca25e4 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -856,11 +856,15 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ /* configure the controller to a known 'ready' state */
+ wmt_reset_hardware(mmc);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (ret)
++ goto fail7;
+
+ dev_info(&pdev->dev, "WMT SDHC Controller initialized\n");
+
+ return 0;
++fail7:
++ clk_disable_unprepare(priv->clk_sdmmc);
+ fail6:
+ clk_put(priv->clk_sdmmc);
+ fail5_and_a_half:
+diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c
+index 367e2d906de02..e71af4c490969 100644
+--- a/drivers/mtd/lpddr/lpddr2_nvm.c
++++ b/drivers/mtd/lpddr/lpddr2_nvm.c
+@@ -433,6 +433,8 @@ static int lpddr2_nvm_probe(struct platform_device *pdev)
+
+ /* lpddr2_nvm address range */
+ add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!add_range)
++ return -ENODEV;
+
+ /* Populate map_info data structure */
+ *map = (struct map_info) {
+diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
+index 1749dbbacc135..62a5bf41a6d72 100644
+--- a/drivers/mtd/maps/pxa2xx-flash.c
++++ b/drivers/mtd/maps/pxa2xx-flash.c
+@@ -64,6 +64,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+ if (!info->map.virt) {
+ printk(KERN_WARNING "Failed to ioremap %s\n",
+ info->map.name);
++ kfree(info);
+ return -ENOMEM;
+ }
+ info->map.cached = ioremap_cache(info->map.phys, info->map.size);
+@@ -85,6 +86,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+ iounmap((void *)info->map.virt);
+ if (info->map.cached)
+ iounmap(info->map.cached);
++ kfree(info);
+ return -EIO;
+ }
+ info->mtd->dev.parent = &pdev->dev;
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 477707bcad972..c14196bbf008e 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -723,8 +723,10 @@ int add_mtd_device(struct mtd_info *mtd)
+ mtd_check_of_node(mtd);
+ of_node_get(mtd_get_of_node(mtd));
+ error = device_register(&mtd->dev);
+- if (error)
++ if (error) {
++ put_device(&mtd->dev);
+ goto fail_added;
++ }
+
+ /* Add the nvmem provider */
+ error = mtd_nvmem_add(mtd);
+@@ -774,6 +776,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ {
+ int ret;
+ struct mtd_notifier *not;
++ struct device_node *mtd_of_node;
+
+ mutex_lock(&mtd_table_mutex);
+
+@@ -792,6 +795,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ mtd->index, mtd->name, mtd->usecount);
+ ret = -EBUSY;
+ } else {
++ mtd_of_node = mtd_get_of_node(mtd);
+ debugfs_remove_recursive(mtd->dbg.dfs_dir);
+
+ /* Try to remove the NVMEM provider */
+@@ -803,7 +807,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ memset(&mtd->dev, 0, sizeof(mtd->dev));
+
+ idr_remove(&mtd_idr, mtd->index);
+- of_node_put(mtd_get_of_node(mtd));
++ of_node_put(mtd_of_node);
+
+ module_put(THIS_MODULE);
+ ret = 0;
+@@ -2450,6 +2454,7 @@ static int __init init_mtd(void)
+ out_procfs:
+ if (proc_mtd)
+ remove_proc_entry("mtd", NULL);
++ bdi_unregister(mtd_bdi);
+ bdi_put(mtd_bdi);
+ err_bdi:
+ class_unregister(&mtd_class);
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index bee8fc4c9f078..0cf1a1797ea32 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1914,7 +1914,8 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor,
+ spi_nor_spimem_setup_op(nor, &op, read->proto);
+
+ /* convert the dummy cycles to the number of bytes */
+- op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
++ op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) *
++ op.dummy.buswidth / 8;
+ if (spi_nor_protocol_is_dtr(nor->read_proto))
+ op.dummy.nbytes *= 2;
+
+diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
+index 9aec9d8a98ada..4c3b351aef245 100644
+--- a/drivers/mtd/spi-nor/sysfs.c
++++ b/drivers/mtd/spi-nor/sysfs.c
+@@ -67,6 +67,19 @@ static struct bin_attribute *spi_nor_sysfs_bin_entries[] = {
+ NULL
+ };
+
++static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj,
++ struct attribute *attr, int n)
++{
++ struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
++ struct spi_mem *spimem = spi_get_drvdata(spi);
++ struct spi_nor *nor = spi_mem_get_drvdata(spimem);
++
++ if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len)
++ return 0;
++
++ return 0444;
++}
++
+ static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
+ struct bin_attribute *attr, int n)
+ {
+@@ -82,6 +95,7 @@ static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
+
+ static const struct attribute_group spi_nor_sysfs_group = {
+ .name = "spi-nor",
++ .is_visible = spi_nor_sysfs_is_visible,
+ .is_bin_visible = spi_nor_sysfs_is_bin_visible,
+ .attrs = spi_nor_sysfs_entries,
+ .bin_attrs = spi_nor_sysfs_bin_entries,
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index c2939621b683c..771f2a533d3f6 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2531,12 +2531,21 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
+ /* called with rcu_read_lock() */
+ static int bond_miimon_inspect(struct bonding *bond)
+ {
++ bool ignore_updelay = false;
+ int link_state, commit = 0;
+ struct list_head *iter;
+ struct slave *slave;
+- bool ignore_updelay;
+
+- ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
++ ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++ } else {
++ struct bond_up_slave *usable_slaves;
++
++ usable_slaves = rcu_dereference(bond->usable_slaves);
++
++ if (usable_slaves && usable_slaves->count == 0)
++ ignore_updelay = true;
++ }
+
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
+@@ -2644,8 +2653,9 @@ static void bond_miimon_link_change(struct bonding *bond,
+
+ static void bond_miimon_commit(struct bonding *bond)
+ {
+- struct list_head *iter;
+ struct slave *slave, *primary;
++ bool do_failover = false;
++ struct list_head *iter;
+
+ bond_for_each_slave(bond, slave, iter) {
+ switch (slave->link_new_state) {
+@@ -2689,8 +2699,9 @@ static void bond_miimon_commit(struct bonding *bond)
+
+ bond_miimon_link_change(bond, slave, BOND_LINK_UP);
+
+- if (!bond->curr_active_slave || slave == primary)
+- goto do_failover;
++ if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
++ slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
++ do_failover = true;
+
+ continue;
+
+@@ -2711,7 +2722,7 @@ static void bond_miimon_commit(struct bonding *bond)
+ bond_miimon_link_change(bond, slave, BOND_LINK_DOWN);
+
+ if (slave == rcu_access_pointer(bond->curr_active_slave))
+- goto do_failover;
++ do_failover = true;
+
+ continue;
+
+@@ -2722,8 +2733,9 @@ static void bond_miimon_commit(struct bonding *bond)
+
+ continue;
+ }
++ }
+
+-do_failover:
++ if (do_failover) {
+ block_netpoll_tx();
+ bond_select_active_slave(bond);
+ unblock_netpoll_tx();
+@@ -3521,6 +3533,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
+ */
+ static void bond_ab_arp_commit(struct bonding *bond)
+ {
++ bool do_failover = false;
+ struct list_head *iter;
+ unsigned long last_tx;
+ struct slave *slave;
+@@ -3550,8 +3563,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
+ slave_info(bond->dev, slave->dev, "link status definitely up\n");
+
+ if (!rtnl_dereference(bond->curr_active_slave) ||
+- slave == rtnl_dereference(bond->primary_slave))
+- goto do_failover;
++ slave == rtnl_dereference(bond->primary_slave) ||
++ slave->prio > rtnl_dereference(bond->curr_active_slave)->prio)
++ do_failover = true;
+
+ }
+
+@@ -3570,7 +3584,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
+
+ if (slave == rtnl_dereference(bond->curr_active_slave)) {
+ RCU_INIT_POINTER(bond->current_arp_slave, NULL);
+- goto do_failover;
++ do_failover = true;
+ }
+
+ continue;
+@@ -3594,8 +3608,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
+ slave->link_new_state);
+ continue;
+ }
++ }
+
+-do_failover:
++ if (do_failover) {
+ block_netpoll_tx();
+ bond_select_active_slave(bond);
+ unblock_netpoll_tx();
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 153d8fd08bd88..a562f36a99f8a 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1233,10 +1233,17 @@ static int m_can_set_bittiming(struct net_device *dev)
+ * - setup bittiming
+ * - configure timestamp generation
+ */
+-static void m_can_chip_config(struct net_device *dev)
++static int m_can_chip_config(struct net_device *dev)
+ {
+ struct m_can_classdev *cdev = netdev_priv(dev);
+ u32 cccr, test;
++ int err;
++
++ err = m_can_init_ram(cdev);
++ if (err) {
++ dev_err(cdev->dev, "Message RAM configuration failed\n");
++ return err;
++ }
+
+ m_can_config_endisable(cdev, true);
+
+@@ -1360,18 +1367,25 @@ static void m_can_chip_config(struct net_device *dev)
+
+ if (cdev->ops->init)
+ cdev->ops->init(cdev);
++
++ return 0;
+ }
+
+-static void m_can_start(struct net_device *dev)
++static int m_can_start(struct net_device *dev)
+ {
+ struct m_can_classdev *cdev = netdev_priv(dev);
++ int ret;
+
+ /* basic m_can configuration */
+- m_can_chip_config(dev);
++ ret = m_can_chip_config(dev);
++ if (ret)
++ return ret;
+
+ cdev->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ m_can_enable_all_interrupts(cdev);
++
++ return 0;
+ }
+
+ static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
+@@ -1800,7 +1814,9 @@ static int m_can_open(struct net_device *dev)
+ }
+
+ /* start the m_can controller */
+- m_can_start(dev);
++ err = m_can_start(dev);
++ if (err)
++ goto exit_irq_fail;
+
+ if (!cdev->is_peripheral)
+ napi_enable(&cdev->napi);
+@@ -2059,9 +2075,13 @@ int m_can_class_resume(struct device *dev)
+ ret = m_can_clk_start(cdev);
+ if (ret)
+ return ret;
++ ret = m_can_start(ndev);
++ if (ret) {
++ m_can_clk_stop(cdev);
++
++ return ret;
++ }
+
+- m_can_init_ram(cdev);
+- m_can_start(ndev);
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
+index eee47bad05920..de6d8e01bf2e8 100644
+--- a/drivers/net/can/m_can/m_can_platform.c
++++ b/drivers/net/can/m_can/m_can_platform.c
+@@ -140,10 +140,6 @@ static int m_can_plat_probe(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, mcan_class);
+
+- ret = m_can_init_ram(mcan_class);
+- if (ret)
+- goto probe_fail;
+-
+ pm_runtime_enable(mcan_class->dev);
+ ret = m_can_class_register(mcan_class);
+ if (ret)
+diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
+index 41645a24384ce..2342aa011647c 100644
+--- a/drivers/net/can/m_can/tcan4x5x-core.c
++++ b/drivers/net/can/m_can/tcan4x5x-core.c
+@@ -10,7 +10,7 @@
+ #define TCAN4X5X_DEV_ID1 0x04
+ #define TCAN4X5X_REV 0x08
+ #define TCAN4X5X_STATUS 0x0C
+-#define TCAN4X5X_ERROR_STATUS 0x10
++#define TCAN4X5X_ERROR_STATUS_MASK 0x10
+ #define TCAN4X5X_CONTROL 0x14
+
+ #define TCAN4X5X_CONFIG 0x800
+@@ -204,17 +204,7 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
+ if (ret)
+ return ret;
+
+- ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_MCAN_INT_REG,
+- TCAN4X5X_ENABLE_MCAN_INT);
+- if (ret)
+- return ret;
+-
+- ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS,
+- TCAN4X5X_CLEAR_ALL_INT);
+- if (ret)
+- return ret;
+-
+- return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS,
++ return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS,
+ TCAN4X5X_CLEAR_ALL_INT);
+ }
+
+@@ -234,8 +224,8 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
+ if (ret)
+ return ret;
+
+- /* Zero out the MCAN buffers */
+- ret = m_can_init_ram(cdev);
++ ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS_MASK,
++ TCAN4X5X_CLEAR_ALL_INT);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index f6c0938027ece..ff10b3790d844 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context {
+ u32 echo_index;
+ };
+
++struct kvaser_usb_busparams {
++ __le32 bitrate;
++ u8 tseg1;
++ u8 tseg2;
++ u8 sjw;
++ u8 nsamples;
++} __packed;
++
+ struct kvaser_usb {
+ struct usb_device *udev;
+ struct usb_interface *intf;
+@@ -104,13 +112,19 @@ struct kvaser_usb_net_priv {
+ struct can_priv can;
+ struct can_berr_counter bec;
+
++ /* subdriver-specific data */
++ void *sub_priv;
++
+ struct kvaser_usb *dev;
+ struct net_device *netdev;
+ int channel;
+
+- struct completion start_comp, stop_comp, flush_comp;
++ struct completion start_comp, stop_comp, flush_comp,
++ get_busparams_comp;
+ struct usb_anchor tx_submitted;
+
++ struct kvaser_usb_busparams busparams_nominal, busparams_data;
++
+ spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
+ int active_tx_contexts;
+ struct kvaser_usb_tx_urb_context tx_contexts[];
+@@ -120,11 +134,15 @@ struct kvaser_usb_net_priv {
+ * struct kvaser_usb_dev_ops - Device specific functions
+ * @dev_set_mode: used for can.do_set_mode
+ * @dev_set_bittiming: used for can.do_set_bittiming
++ * @dev_get_busparams: readback arbitration busparams
+ * @dev_set_data_bittiming: used for can.do_set_data_bittiming
++ * @dev_get_data_busparams: readback data busparams
+ * @dev_get_berr_counter: used for can.do_get_berr_counter
+ *
+ * @dev_setup_endpoints: setup USB in and out endpoints
+ * @dev_init_card: initialize card
++ * @dev_init_channel: initialize channel
++ * @dev_remove_channel: uninitialize channel
+ * @dev_get_software_info: get software info
+ * @dev_get_software_details: get software details
+ * @dev_get_card_info: get card info
+@@ -140,12 +158,18 @@ struct kvaser_usb_net_priv {
+ */
+ struct kvaser_usb_dev_ops {
+ int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
+- int (*dev_set_bittiming)(struct net_device *netdev);
+- int (*dev_set_data_bittiming)(struct net_device *netdev);
++ int (*dev_set_bittiming)(const struct net_device *netdev,
++ const struct kvaser_usb_busparams *busparams);
++ int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
++ int (*dev_set_data_bittiming)(const struct net_device *netdev,
++ const struct kvaser_usb_busparams *busparams);
++ int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
+ int (*dev_get_berr_counter)(const struct net_device *netdev,
+ struct can_berr_counter *bec);
+ int (*dev_setup_endpoints)(struct kvaser_usb *dev);
+ int (*dev_init_card)(struct kvaser_usb *dev);
++ int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
++ void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
+ int (*dev_get_software_info)(struct kvaser_usb *dev);
+ int (*dev_get_software_details)(struct kvaser_usb *dev);
+ int (*dev_get_card_info)(struct kvaser_usb *dev);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 802e27c0ecedb..3a2bfaad14065 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -440,10 +440,6 @@ static int kvaser_usb_open(struct net_device *netdev)
+ if (err)
+ return err;
+
+- err = kvaser_usb_setup_rx_urbs(dev);
+- if (err)
+- goto error;
+-
+ err = ops->dev_set_opt_mode(priv);
+ if (err)
+ goto error;
+@@ -534,6 +530,93 @@ static int kvaser_usb_close(struct net_device *netdev)
+ return 0;
+ }
+
++static int kvaser_usb_set_bittiming(struct net_device *netdev)
++{
++ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++ struct kvaser_usb *dev = priv->dev;
++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++ struct can_bittiming *bt = &priv->can.bittiming;
++
++ struct kvaser_usb_busparams busparams;
++ int tseg1 = bt->prop_seg + bt->phase_seg1;
++ int tseg2 = bt->phase_seg2;
++ int sjw = bt->sjw;
++ int err = -EOPNOTSUPP;
++
++ busparams.bitrate = cpu_to_le32(bt->bitrate);
++ busparams.sjw = (u8)sjw;
++ busparams.tseg1 = (u8)tseg1;
++ busparams.tseg2 = (u8)tseg2;
++ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
++ busparams.nsamples = 3;
++ else
++ busparams.nsamples = 1;
++
++ err = ops->dev_set_bittiming(netdev, &busparams);
++ if (err)
++ return err;
++
++ err = kvaser_usb_setup_rx_urbs(priv->dev);
++ if (err)
++ return err;
++
++ err = ops->dev_get_busparams(priv);
++ if (err) {
++ /* Treat EOPNOTSUPP as success */
++ if (err == -EOPNOTSUPP)
++ err = 0;
++ return err;
++ }
++
++ if (memcmp(&busparams, &priv->busparams_nominal,
++ sizeof(priv->busparams_nominal)) != 0)
++ err = -EINVAL;
++
++ return err;
++}
++
++static int kvaser_usb_set_data_bittiming(struct net_device *netdev)
++{
++ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++ struct kvaser_usb *dev = priv->dev;
++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++ struct can_bittiming *dbt = &priv->can.data_bittiming;
++
++ struct kvaser_usb_busparams busparams;
++ int tseg1 = dbt->prop_seg + dbt->phase_seg1;
++ int tseg2 = dbt->phase_seg2;
++ int sjw = dbt->sjw;
++ int err;
++
++ if (!ops->dev_set_data_bittiming ||
++ !ops->dev_get_data_busparams)
++ return -EOPNOTSUPP;
++
++ busparams.bitrate = cpu_to_le32(dbt->bitrate);
++ busparams.sjw = (u8)sjw;
++ busparams.tseg1 = (u8)tseg1;
++ busparams.tseg2 = (u8)tseg2;
++ busparams.nsamples = 1;
++
++ err = ops->dev_set_data_bittiming(netdev, &busparams);
++ if (err)
++ return err;
++
++ err = kvaser_usb_setup_rx_urbs(priv->dev);
++ if (err)
++ return err;
++
++ err = ops->dev_get_data_busparams(priv);
++ if (err)
++ return err;
++
++ if (memcmp(&busparams, &priv->busparams_data,
++ sizeof(priv->busparams_data)) != 0)
++ err = -EINVAL;
++
++ return err;
++}
++
+ static void kvaser_usb_write_bulk_callback(struct urb *urb)
+ {
+ struct kvaser_usb_tx_urb_context *context = urb->context;
+@@ -684,6 +767,7 @@ static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+
+ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ {
++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ int i;
+
+ for (i = 0; i < dev->nchannels; i++) {
+@@ -699,6 +783,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ if (!dev->nets[i])
+ continue;
+
++ if (ops->dev_remove_channel)
++ ops->dev_remove_channel(dev->nets[i]);
++
+ free_candev(dev->nets[i]->netdev);
+ }
+ }
+@@ -730,6 +817,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ init_completion(&priv->start_comp);
+ init_completion(&priv->stop_comp);
+ init_completion(&priv->flush_comp);
++ init_completion(&priv->get_busparams_comp);
+ priv->can.ctrlmode_supported = 0;
+
+ priv->dev = dev;
+@@ -742,7 +830,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ priv->can.state = CAN_STATE_STOPPED;
+ priv->can.clock.freq = dev->cfg->clock.freq;
+ priv->can.bittiming_const = dev->cfg->bittiming_const;
+- priv->can.do_set_bittiming = ops->dev_set_bittiming;
++ priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
+ priv->can.do_set_mode = ops->dev_set_mode;
+ if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
+ (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
+@@ -754,7 +842,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+
+ if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
+ priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
+- priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;
++ priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming;
+ }
+
+ netdev->flags |= IFF_ECHO;
+@@ -772,17 +860,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+
+ dev->nets[channel] = priv;
+
++ if (ops->dev_init_channel) {
++ err = ops->dev_init_channel(priv);
++ if (err)
++ goto err;
++ }
++
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(&dev->intf->dev, "Failed to register CAN device\n");
+- free_candev(netdev);
+- dev->nets[channel] = NULL;
+- return err;
++ goto err;
+ }
+
+ netdev_dbg(netdev, "device registered\n");
+
+ return 0;
++
++err:
++ free_candev(netdev);
++ dev->nets[channel] = NULL;
++ return err;
+ }
+
+ static int kvaser_usb_probe(struct usb_interface *intf,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 3abfaa77e8935..52ef76bd9bdb8 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -45,6 +45,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt;
+
+ /* Minihydra command IDs */
+ #define CMD_SET_BUSPARAMS_REQ 16
++#define CMD_GET_BUSPARAMS_REQ 17
++#define CMD_GET_BUSPARAMS_RESP 18
+ #define CMD_GET_CHIP_STATE_REQ 19
+ #define CMD_CHIP_STATE_EVENT 20
+ #define CMD_SET_DRIVERMODE_REQ 21
+@@ -196,21 +198,26 @@ struct kvaser_cmd_chip_state_event {
+ #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01
+ #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02
+ struct kvaser_cmd_set_busparams {
+- __le32 bitrate;
+- u8 tseg1;
+- u8 tseg2;
+- u8 sjw;
+- u8 nsamples;
++ struct kvaser_usb_busparams busparams_nominal;
+ u8 reserved0[4];
+- __le32 bitrate_d;
+- u8 tseg1_d;
+- u8 tseg2_d;
+- u8 sjw_d;
+- u8 nsamples_d;
++ struct kvaser_usb_busparams busparams_data;
+ u8 canfd_mode;
+ u8 reserved1[7];
+ } __packed;
+
++/* Busparam type */
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN 0x00
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD 0x01
++struct kvaser_cmd_get_busparams_req {
++ u8 type;
++ u8 reserved[27];
++} __packed;
++
++struct kvaser_cmd_get_busparams_res {
++ struct kvaser_usb_busparams busparams;
++ u8 reserved[20];
++} __packed;
++
+ /* Ctrl modes */
+ #define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01
+ #define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02
+@@ -281,6 +288,8 @@ struct kvaser_cmd {
+ struct kvaser_cmd_error_event error_event;
+
+ struct kvaser_cmd_set_busparams set_busparams_req;
++ struct kvaser_cmd_get_busparams_req get_busparams_req;
++ struct kvaser_cmd_get_busparams_res get_busparams_res;
+
+ struct kvaser_cmd_chip_state_event chip_state_event;
+
+@@ -363,6 +372,10 @@ struct kvaser_cmd_ext {
+ } __packed;
+ } __packed;
+
++struct kvaser_usb_net_hydra_priv {
++ int pending_get_busparams_type;
++};
++
+ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
+ .name = "kvaser_usb_kcan",
+ .tseg1_min = 1,
+@@ -840,6 +853,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev,
+ complete(&priv->flush_comp);
+ }
+
++static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev,
++ const struct kvaser_cmd *cmd)
++{
++ struct kvaser_usb_net_priv *priv;
++ struct kvaser_usb_net_hydra_priv *hydra;
++
++ priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd);
++ if (!priv)
++ return;
++
++ hydra = priv->sub_priv;
++ if (!hydra)
++ return;
++
++ switch (hydra->pending_get_busparams_type) {
++ case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN:
++ memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams,
++ sizeof(priv->busparams_nominal));
++ break;
++ case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD:
++ memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams,
++ sizeof(priv->busparams_nominal));
++ break;
++ default:
++ dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n",
++ hydra->pending_get_busparams_type);
++ break;
++ }
++ hydra->pending_get_busparams_type = -1;
++
++ complete(&priv->get_busparams_comp);
++}
++
+ static void
+ kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
+ u8 bus_status,
+@@ -1326,6 +1372,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev,
+ kvaser_usb_hydra_state_event(dev, cmd);
+ break;
+
++ case CMD_GET_BUSPARAMS_RESP:
++ kvaser_usb_hydra_get_busparams_reply(dev, cmd);
++ break;
++
+ case CMD_ERROR_EVENT:
+ kvaser_usb_hydra_error_event(dev, cmd);
+ break;
+@@ -1522,15 +1572,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev,
+ return err;
+ }
+
+-static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
++ int busparams_type)
++{
++ struct kvaser_usb *dev = priv->dev;
++ struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv;
++ struct kvaser_cmd *cmd;
++ int err;
++
++ if (!hydra)
++ return -EINVAL;
++
++ cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
++ if (!cmd)
++ return -ENOMEM;
++
++ cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ;
++ kvaser_usb_hydra_set_cmd_dest_he
++ (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
++ kvaser_usb_hydra_set_cmd_transid
++ (cmd, kvaser_usb_hydra_get_next_transid(dev));
++ cmd->get_busparams_req.type = busparams_type;
++ hydra->pending_get_busparams_type = busparams_type;
++
++ reinit_completion(&priv->get_busparams_comp);
++
++ err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
++ if (err)
++ return err;
++
++ if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++ msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++ return -ETIMEDOUT;
++
++ return err;
++}
++
++static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv)
++{
++ return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN);
++}
++
++static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv)
++{
++ return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD);
++}
++
++static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
++ const struct kvaser_usb_busparams *busparams)
+ {
+ struct kvaser_cmd *cmd;
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+- struct can_bittiming *bt = &priv->can.bittiming;
+ struct kvaser_usb *dev = priv->dev;
+- int tseg1 = bt->prop_seg + bt->phase_seg1;
+- int tseg2 = bt->phase_seg2;
+- int sjw = bt->sjw;
+ int err;
+
+ cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1538,11 +1631,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+ return -ENOMEM;
+
+ cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
+- cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate);
+- cmd->set_busparams_req.sjw = (u8)sjw;
+- cmd->set_busparams_req.tseg1 = (u8)tseg1;
+- cmd->set_busparams_req.tseg2 = (u8)tseg2;
+- cmd->set_busparams_req.nsamples = 1;
++ memcpy(&cmd->set_busparams_req.busparams_nominal, busparams,
++ sizeof(cmd->set_busparams_req.busparams_nominal));
+
+ kvaser_usb_hydra_set_cmd_dest_he
+ (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
+@@ -1556,15 +1646,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+ return err;
+ }
+
+-static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
++ const struct kvaser_usb_busparams *busparams)
+ {
+ struct kvaser_cmd *cmd;
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+- struct can_bittiming *dbt = &priv->can.data_bittiming;
+ struct kvaser_usb *dev = priv->dev;
+- int tseg1 = dbt->prop_seg + dbt->phase_seg1;
+- int tseg2 = dbt->phase_seg2;
+- int sjw = dbt->sjw;
+ int err;
+
+ cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1572,11 +1659,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
+ return -ENOMEM;
+
+ cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
+- cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate);
+- cmd->set_busparams_req.sjw_d = (u8)sjw;
+- cmd->set_busparams_req.tseg1_d = (u8)tseg1;
+- cmd->set_busparams_req.tseg2_d = (u8)tseg2;
+- cmd->set_busparams_req.nsamples_d = 1;
++ memcpy(&cmd->set_busparams_req.busparams_data, busparams,
++ sizeof(cmd->set_busparams_req.busparams_data));
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
+@@ -1683,6 +1767,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev)
+ return 0;
+ }
+
++static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv)
++{
++ struct kvaser_usb_net_hydra_priv *hydra;
++
++ hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL);
++ if (!hydra)
++ return -ENOMEM;
++
++ priv->sub_priv = hydra;
++
++ return 0;
++}
++
+ static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
+ {
+ struct kvaser_cmd cmd;
+@@ -2027,10 +2124,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = {
+ .dev_set_mode = kvaser_usb_hydra_set_mode,
+ .dev_set_bittiming = kvaser_usb_hydra_set_bittiming,
++ .dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams,
+ .dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming,
++ .dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams,
+ .dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter,
+ .dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints,
+ .dev_init_card = kvaser_usb_hydra_init_card,
++ .dev_init_channel = kvaser_usb_hydra_init_channel,
+ .dev_get_software_info = kvaser_usb_hydra_get_software_info,
+ .dev_get_software_details = kvaser_usb_hydra_get_software_details,
+ .dev_get_card_info = kvaser_usb_hydra_get_card_info,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 19958037720f4..b423fd4c79890 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -21,6 +21,7 @@
+ #include <linux/types.h>
+ #include <linux/units.h>
+ #include <linux/usb.h>
++#include <linux/workqueue.h>
+
+ #include <linux/can.h>
+ #include <linux/can/dev.h>
+@@ -56,6 +57,9 @@
+ #define CMD_RX_EXT_MESSAGE 14
+ #define CMD_TX_EXT_MESSAGE 15
+ #define CMD_SET_BUS_PARAMS 16
++#define CMD_GET_BUS_PARAMS 17
++#define CMD_GET_BUS_PARAMS_REPLY 18
++#define CMD_GET_CHIP_STATE 19
+ #define CMD_CHIP_STATE_EVENT 20
+ #define CMD_SET_CTRL_MODE 21
+ #define CMD_RESET_CHIP 24
+@@ -70,10 +74,13 @@
+ #define CMD_GET_CARD_INFO_REPLY 35
+ #define CMD_GET_SOFTWARE_INFO 38
+ #define CMD_GET_SOFTWARE_INFO_REPLY 39
++#define CMD_ERROR_EVENT 45
+ #define CMD_FLUSH_QUEUE 48
+ #define CMD_TX_ACKNOWLEDGE 50
+ #define CMD_CAN_ERROR_EVENT 51
+ #define CMD_FLUSH_QUEUE_REPLY 68
++#define CMD_GET_CAPABILITIES_REQ 95
++#define CMD_GET_CAPABILITIES_RESP 96
+
+ #define CMD_LEAF_LOG_MESSAGE 106
+
+@@ -83,6 +90,8 @@
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
+
++#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12)
++
+ /* error factors */
+ #define M16C_EF_ACKE BIT(0)
+ #define M16C_EF_CRCE BIT(1)
+@@ -157,11 +166,7 @@ struct usbcan_cmd_softinfo {
+ struct kvaser_cmd_busparams {
+ u8 tid;
+ u8 channel;
+- __le32 bitrate;
+- u8 tseg1;
+- u8 tseg2;
+- u8 sjw;
+- u8 no_samp;
++ struct kvaser_usb_busparams busparams;
+ } __packed;
+
+ struct kvaser_cmd_tx_can {
+@@ -230,7 +235,7 @@ struct kvaser_cmd_tx_acknowledge_header {
+ u8 tid;
+ } __packed;
+
+-struct leaf_cmd_error_event {
++struct leaf_cmd_can_error_event {
+ u8 tid;
+ u8 flags;
+ __le16 time[3];
+@@ -242,7 +247,7 @@ struct leaf_cmd_error_event {
+ u8 error_factor;
+ } __packed;
+
+-struct usbcan_cmd_error_event {
++struct usbcan_cmd_can_error_event {
+ u8 tid;
+ u8 padding;
+ u8 tx_errors_count_ch0;
+@@ -254,6 +259,28 @@ struct usbcan_cmd_error_event {
+ __le16 time;
+ } __packed;
+
++/* CMD_ERROR_EVENT error codes */
++#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8
++#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9
++
++struct leaf_cmd_error_event {
++ u8 tid;
++ u8 error_code;
++ __le16 timestamp[3];
++ __le16 padding;
++ __le16 info1;
++ __le16 info2;
++} __packed;
++
++struct usbcan_cmd_error_event {
++ u8 tid;
++ u8 error_code;
++ __le16 info1;
++ __le16 info2;
++ __le16 timestamp;
++ __le16 padding;
++} __packed;
++
+ struct kvaser_cmd_ctrl_mode {
+ u8 tid;
+ u8 channel;
+@@ -278,6 +305,28 @@ struct leaf_cmd_log_message {
+ u8 data[8];
+ } __packed;
+
++/* Sub commands for cap_req and cap_res */
++#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02
++#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05
++struct kvaser_cmd_cap_req {
++ __le16 padding0;
++ __le16 cap_cmd;
++ __le16 padding1;
++ __le16 channel;
++} __packed;
++
++/* Status codes for cap_res */
++#define KVASER_USB_LEAF_CAP_STAT_OK 0x00
++#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01
++#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02
++struct kvaser_cmd_cap_res {
++ __le16 padding;
++ __le16 cap_cmd;
++ __le16 status;
++ __le32 mask;
++ __le32 value;
++} __packed;
++
+ struct kvaser_cmd {
+ u8 len;
+ u8 id;
+@@ -293,14 +342,18 @@ struct kvaser_cmd {
+ struct leaf_cmd_softinfo softinfo;
+ struct leaf_cmd_rx_can rx_can;
+ struct leaf_cmd_chip_state_event chip_state_event;
+- struct leaf_cmd_error_event error_event;
++ struct leaf_cmd_can_error_event can_error_event;
+ struct leaf_cmd_log_message log_message;
++ struct leaf_cmd_error_event error_event;
++ struct kvaser_cmd_cap_req cap_req;
++ struct kvaser_cmd_cap_res cap_res;
+ } __packed leaf;
+
+ union {
+ struct usbcan_cmd_softinfo softinfo;
+ struct usbcan_cmd_rx_can rx_can;
+ struct usbcan_cmd_chip_state_event chip_state_event;
++ struct usbcan_cmd_can_error_event can_error_event;
+ struct usbcan_cmd_error_event error_event;
+ } __packed usbcan;
+
+@@ -323,7 +376,10 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can),
+ [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message),
+ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event),
+- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event),
++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event),
++ [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res),
++ [CMD_GET_BUS_PARAMS_REPLY] = kvaser_fsize(u.busparams),
++ [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event),
+ /* ignored events: */
+ [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY,
+ };
+@@ -337,7 +393,8 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
+ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can),
+ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can),
+ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event),
+- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event),
++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event),
++ [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event),
+ /* ignored events: */
+ [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
+ };
+@@ -365,6 +422,12 @@ struct kvaser_usb_err_summary {
+ };
+ };
+
++struct kvaser_usb_net_leaf_priv {
++ struct kvaser_usb_net_priv *net;
++
++ struct delayed_work chip_state_req_work;
++};
++
+ static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
+ .name = "kvaser_usb_ucii",
+ .tseg1_min = 4,
+@@ -606,6 +669,9 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
+ dev->fw_version = le32_to_cpu(softinfo->fw_version);
+ dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
+
++ if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP)
++ dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP;
++
+ if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+ /* Firmware expects bittiming parameters calculated for 16MHz
+ * clock, regardless of the actual clock
+@@ -693,6 +759,116 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
+ return 0;
+ }
+
++static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev,
++ u16 cap_cmd_req, u16 *status)
++{
++ struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
++ struct kvaser_cmd *cmd;
++ u32 value = 0;
++ u32 mask = 0;
++ u16 cap_cmd_res;
++ int err;
++ int i;
++
++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
++ if (!cmd)
++ return -ENOMEM;
++
++ cmd->id = CMD_GET_CAPABILITIES_REQ;
++ cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req);
++ cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req);
++
++ err = kvaser_usb_send_cmd(dev, cmd, cmd->len);
++ if (err)
++ goto end;
++
++ err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd);
++ if (err)
++ goto end;
++
++ *status = le16_to_cpu(cmd->u.leaf.cap_res.status);
++
++ if (*status != KVASER_USB_LEAF_CAP_STAT_OK)
++ goto end;
++
++ cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd);
++ switch (cap_cmd_res) {
++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++ value = le32_to_cpu(cmd->u.leaf.cap_res.value);
++ mask = le32_to_cpu(cmd->u.leaf.cap_res.mask);
++ break;
++ default:
++ dev_warn(&dev->intf->dev, "Unknown capability command %u\n",
++ cap_cmd_res);
++ break;
++ }
++
++ for (i = 0; i < dev->nchannels; i++) {
++ if (BIT(i) & (value & mask)) {
++ switch (cap_cmd_res) {
++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++ card_data->ctrlmode_supported |=
++ CAN_CTRLMODE_LISTENONLY;
++ break;
++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++ card_data->capabilities |=
++ KVASER_USB_CAP_BERR_CAP;
++ break;
++ }
++ }
++ }
++
++end:
++ kfree(cmd);
++
++ return err;
++}
++
++static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev)
++{
++ int err;
++ u16 status;
++
++ if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) {
++ dev_info(&dev->intf->dev,
++ "No extended capability support. Upgrade device firmware.\n");
++ return 0;
++ }
++
++ err = kvaser_usb_leaf_get_single_capability(dev,
++ KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE,
++ &status);
++ if (err)
++ return err;
++ if (status)
++ dev_info(&dev->intf->dev,
++ "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n",
++ status);
++
++ err = kvaser_usb_leaf_get_single_capability(dev,
++ KVASER_USB_LEAF_CAP_CMD_ERR_REPORT,
++ &status);
++ if (err)
++ return err;
++ if (status)
++ dev_info(&dev->intf->dev,
++ "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n",
++ status);
++
++ return 0;
++}
++
++static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev)
++{
++ int err = 0;
++
++ if (dev->driver_info->family == KVASER_LEAF)
++ err = kvaser_usb_leaf_get_capabilities_leaf(dev);
++
++ return err;
++}
++
+ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+ const struct kvaser_cmd *cmd)
+ {
+@@ -721,7 +897,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+ context = &priv->tx_contexts[tid % dev->max_tx_urbs];
+
+ /* Sometimes the state change doesn't come after a bus-off event */
+- if (priv->can.restart_ms && priv->can.state >= CAN_STATE_BUS_OFF) {
++ if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) {
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+@@ -774,6 +950,16 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv,
+ return err;
+ }
+
++static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work)
++{
++ struct kvaser_usb_net_leaf_priv *leaf =
++ container_of(work, struct kvaser_usb_net_leaf_priv,
++ chip_state_req_work.work);
++ struct kvaser_usb_net_priv *priv = leaf->net;
++
++ kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE);
++}
++
+ static void
+ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ const struct kvaser_usb_err_summary *es,
+@@ -792,20 +978,16 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ new_state = CAN_STATE_BUS_OFF;
+ } else if (es->status & M16C_STATE_BUS_PASSIVE) {
+ new_state = CAN_STATE_ERROR_PASSIVE;
+- } else if (es->status & M16C_STATE_BUS_ERROR) {
++ } else if ((es->status & M16C_STATE_BUS_ERROR) &&
++ cur_state >= CAN_STATE_BUS_OFF) {
+ /* Guard against spurious error events after a busoff */
+- if (cur_state < CAN_STATE_BUS_OFF) {
+- if (es->txerr >= 128 || es->rxerr >= 128)
+- new_state = CAN_STATE_ERROR_PASSIVE;
+- else if (es->txerr >= 96 || es->rxerr >= 96)
+- new_state = CAN_STATE_ERROR_WARNING;
+- else if (cur_state > CAN_STATE_ERROR_ACTIVE)
+- new_state = CAN_STATE_ERROR_ACTIVE;
+- }
+- }
+-
+- if (!es->status)
++ } else if (es->txerr >= 128 || es->rxerr >= 128) {
++ new_state = CAN_STATE_ERROR_PASSIVE;
++ } else if (es->txerr >= 96 || es->rxerr >= 96) {
++ new_state = CAN_STATE_ERROR_WARNING;
++ } else {
+ new_state = CAN_STATE_ERROR_ACTIVE;
++ }
+
+ if (new_state != cur_state) {
+ tx_state = (es->txerr >= es->rxerr) ? new_state : 0;
+@@ -815,7 +997,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ }
+
+ if (priv->can.restart_ms &&
+- cur_state >= CAN_STATE_BUS_OFF &&
++ cur_state == CAN_STATE_BUS_OFF &&
+ new_state < CAN_STATE_BUS_OFF)
+ priv->can.can_stats.restarts++;
+
+@@ -849,6 +1031,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ struct sk_buff *skb;
+ struct net_device_stats *stats;
+ struct kvaser_usb_net_priv *priv;
++ struct kvaser_usb_net_leaf_priv *leaf;
+ enum can_state old_state, new_state;
+
+ if (es->channel >= dev->nchannels) {
+@@ -858,8 +1041,13 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ }
+
+ priv = dev->nets[es->channel];
++ leaf = priv->sub_priv;
+ stats = &priv->netdev->stats;
+
++ /* Ignore e.g. state change to bus-off reported just after stopping */
++ if (!netif_running(priv->netdev))
++ return;
++
+ /* Update all of the CAN interface's state and error counters before
+ * trying any memory allocation that can actually fail with -ENOMEM.
+ *
+@@ -874,6 +1062,14 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf);
+ new_state = priv->can.state;
+
++ /* If there are errors, request status updates periodically as we do
++ * not get automatic notifications of improved state.
++ */
++ if (new_state < CAN_STATE_BUS_OFF &&
++ (es->rxerr || es->txerr || new_state == CAN_STATE_ERROR_PASSIVE))
++ schedule_delayed_work(&leaf->chip_state_req_work,
++ msecs_to_jiffies(500));
++
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (!skb) {
+ stats->rx_dropped++;
+@@ -891,7 +1087,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ }
+
+ if (priv->can.restart_ms &&
+- old_state >= CAN_STATE_BUS_OFF &&
++ old_state == CAN_STATE_BUS_OFF &&
+ new_state < CAN_STATE_BUS_OFF) {
+ cf->can_id |= CAN_ERR_RESTARTED;
+ netif_carrier_on(priv->netdev);
+@@ -990,11 +1186,11 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+
+ case CMD_CAN_ERROR_EVENT:
+ es.channel = 0;
+- es.status = cmd->u.usbcan.error_event.status_ch0;
+- es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0;
+- es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0;
++ es.status = cmd->u.usbcan.can_error_event.status_ch0;
++ es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0;
++ es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0;
+ es.usbcan.other_ch_status =
+- cmd->u.usbcan.error_event.status_ch1;
++ cmd->u.usbcan.can_error_event.status_ch1;
+ kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+
+ /* The USBCAN firmware supports up to 2 channels.
+@@ -1002,13 +1198,13 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+ */
+ if (dev->nchannels == MAX_USBCAN_NET_DEVICES) {
+ es.channel = 1;
+- es.status = cmd->u.usbcan.error_event.status_ch1;
++ es.status = cmd->u.usbcan.can_error_event.status_ch1;
+ es.txerr =
+- cmd->u.usbcan.error_event.tx_errors_count_ch1;
++ cmd->u.usbcan.can_error_event.tx_errors_count_ch1;
+ es.rxerr =
+- cmd->u.usbcan.error_event.rx_errors_count_ch1;
++ cmd->u.usbcan.can_error_event.rx_errors_count_ch1;
+ es.usbcan.other_ch_status =
+- cmd->u.usbcan.error_event.status_ch0;
++ cmd->u.usbcan.can_error_event.status_ch0;
+ kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+ }
+ break;
+@@ -1025,11 +1221,11 @@ static void kvaser_usb_leaf_leaf_rx_error(const struct kvaser_usb *dev,
+
+ switch (cmd->id) {
+ case CMD_CAN_ERROR_EVENT:
+- es.channel = cmd->u.leaf.error_event.channel;
+- es.status = cmd->u.leaf.error_event.status;
+- es.txerr = cmd->u.leaf.error_event.tx_errors_count;
+- es.rxerr = cmd->u.leaf.error_event.rx_errors_count;
+- es.leaf.error_factor = cmd->u.leaf.error_event.error_factor;
++ es.channel = cmd->u.leaf.can_error_event.channel;
++ es.status = cmd->u.leaf.can_error_event.status;
++ es.txerr = cmd->u.leaf.can_error_event.tx_errors_count;
++ es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count;
++ es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor;
+ break;
+ case CMD_LEAF_LOG_MESSAGE:
+ es.channel = cmd->u.leaf.log_message.channel;
+@@ -1162,6 +1358,74 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+ netif_rx(skb);
+ }
+
++static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev,
++ const struct kvaser_cmd *cmd)
++{
++ u16 info1 = 0;
++
++ switch (dev->driver_info->family) {
++ case KVASER_LEAF:
++ info1 = le16_to_cpu(cmd->u.leaf.error_event.info1);
++ break;
++ case KVASER_USBCAN:
++ info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1);
++ break;
++ }
++
++ /* info1 will contain the offending cmd_no */
++ switch (info1) {
++ case CMD_SET_CTRL_MODE:
++ dev_warn(&dev->intf->dev,
++ "CMD_SET_CTRL_MODE error in parameter\n");
++ break;
++
++ case CMD_SET_BUS_PARAMS:
++ dev_warn(&dev->intf->dev,
++ "CMD_SET_BUS_PARAMS error in parameter\n");
++ break;
++
++ default:
++ dev_warn(&dev->intf->dev,
++ "Unhandled parameter error event cmd_no (%u)\n",
++ info1);
++ break;
++ }
++}
++
++static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev,
++ const struct kvaser_cmd *cmd)
++{
++ u8 error_code = 0;
++
++ switch (dev->driver_info->family) {
++ case KVASER_LEAF:
++ error_code = cmd->u.leaf.error_event.error_code;
++ break;
++ case KVASER_USBCAN:
++ error_code = cmd->u.usbcan.error_event.error_code;
++ break;
++ }
++
++ switch (error_code) {
++ case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL:
++ /* Received additional CAN message, when firmware TX queue is
++ * already full. Something is wrong with the driver.
++ * This should never happen!
++ */
++ dev_err(&dev->intf->dev,
++ "Received error event TX_QUEUE_FULL\n");
++ break;
++ case KVASER_USB_LEAF_ERROR_EVENT_PARAM:
++ kvaser_usb_leaf_error_event_parameter(dev, cmd);
++ break;
++
++ default:
++ dev_warn(&dev->intf->dev,
++ "Unhandled error event (%d)\n", error_code);
++ break;
++ }
++}
++
+ static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev,
+ const struct kvaser_cmd *cmd)
+ {
+@@ -1202,6 +1466,25 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev,
+ complete(&priv->stop_comp);
+ }
+
++static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev,
++ const struct kvaser_cmd *cmd)
++{
++ struct kvaser_usb_net_priv *priv;
++ u8 channel = cmd->u.busparams.channel;
++
++ if (channel >= dev->nchannels) {
++ dev_err(&dev->intf->dev,
++ "Invalid channel number (%d)\n", channel);
++ return;
++ }
++
++ priv = dev->nets[channel];
++ memcpy(&priv->busparams_nominal, &cmd->u.busparams.busparams,
++ sizeof(priv->busparams_nominal));
++
++ complete(&priv->get_busparams_comp);
++}
++
+ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ const struct kvaser_cmd *cmd)
+ {
+@@ -1240,6 +1523,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ kvaser_usb_leaf_tx_acknowledge(dev, cmd);
+ break;
+
++ case CMD_ERROR_EVENT:
++ kvaser_usb_leaf_error_event(dev, cmd);
++ break;
++
++ case CMD_GET_BUS_PARAMS_REPLY:
++ kvaser_usb_leaf_get_busparams_reply(dev, cmd);
++ break;
++
+ /* Ignored commands */
+ case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
+ if (dev->driver_info->family != KVASER_USBCAN)
+@@ -1336,10 +1627,13 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
+
+ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
++ struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
+ int err;
+
+ reinit_completion(&priv->stop_comp);
+
++ cancel_delayed_work(&leaf->chip_state_req_work);
++
+ err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
+ priv->channel);
+ if (err)
+@@ -1386,10 +1680,35 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
+ return 0;
+ }
+
+-static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv)
++{
++ struct kvaser_usb_net_leaf_priv *leaf;
++
++ leaf = devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL);
++ if (!leaf)
++ return -ENOMEM;
++
++ leaf->net = priv;
++ INIT_DELAYED_WORK(&leaf->chip_state_req_work,
++ kvaser_usb_leaf_chip_state_req_work);
++
++ priv->sub_priv = leaf;
++
++ return 0;
++}
++
++static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv)
++{
++ struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
++
++ if (leaf)
++ cancel_delayed_work_sync(&leaf->chip_state_req_work);
++}
++
++static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev,
++ const struct kvaser_usb_busparams *busparams)
+ {
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+- struct can_bittiming *bt = &priv->can.bittiming;
+ struct kvaser_usb *dev = priv->dev;
+ struct kvaser_cmd *cmd;
+ int rc;
+@@ -1402,15 +1721,8 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+ cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams);
+ cmd->u.busparams.channel = priv->channel;
+ cmd->u.busparams.tid = 0xff;
+- cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate);
+- cmd->u.busparams.sjw = bt->sjw;
+- cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
+- cmd->u.busparams.tseg2 = bt->phase_seg2;
+-
+- if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+- cmd->u.busparams.no_samp = 3;
+- else
+- cmd->u.busparams.no_samp = 1;
++ memcpy(&cmd->u.busparams.busparams, busparams,
++ sizeof(cmd->u.busparams.busparams));
+
+ rc = kvaser_usb_send_cmd(dev, cmd, cmd->len);
+
+@@ -1418,6 +1730,27 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+ return rc;
+ }
+
++static int kvaser_usb_leaf_get_busparams(struct kvaser_usb_net_priv *priv)
++{
++ int err;
++
++ if (priv->dev->driver_info->family == KVASER_USBCAN)
++ return -EOPNOTSUPP;
++
++ reinit_completion(&priv->get_busparams_comp);
++
++ err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS,
++ priv->channel);
++ if (err)
++ return err;
++
++ if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++ msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++ return -ETIMEDOUT;
++
++ return 0;
++}
++
+ static int kvaser_usb_leaf_set_mode(struct net_device *netdev,
+ enum can_mode mode)
+ {
+@@ -1479,14 +1812,18 @@ static int kvaser_usb_leaf_setup_endpoints(struct kvaser_usb *dev)
+ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
+ .dev_set_mode = kvaser_usb_leaf_set_mode,
+ .dev_set_bittiming = kvaser_usb_leaf_set_bittiming,
++ .dev_get_busparams = kvaser_usb_leaf_get_busparams,
+ .dev_set_data_bittiming = NULL,
++ .dev_get_data_busparams = NULL,
+ .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter,
+ .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints,
+ .dev_init_card = kvaser_usb_leaf_init_card,
++ .dev_init_channel = kvaser_usb_leaf_init_channel,
++ .dev_remove_channel = kvaser_usb_leaf_remove_channel,
+ .dev_get_software_info = kvaser_usb_leaf_get_software_info,
+ .dev_get_software_details = NULL,
+ .dev_get_card_info = kvaser_usb_leaf_get_card_info,
+- .dev_get_capabilities = NULL,
++ .dev_get_capabilities = kvaser_usb_leaf_get_capabilities,
+ .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode,
+ .dev_start_chip = kvaser_usb_leaf_start_chip,
+ .dev_stop_chip = kvaser_usb_leaf_stop_chip,
+diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
+index 1de62604434d8..2ed64fa19d020 100644
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -1003,9 +1003,11 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
+ ret = lan9303_read_switch_port(
+ chip, port, lan9303_mib[u].offset, ®);
+
+- if (ret)
++ if (ret) {
+ dev_warn(chip->dev, "Reading status port %d reg %u failed\n",
+ port, lan9303_mib[u].offset);
++ reg = 0;
++ }
+ data[u] = reg;
+ }
+ }
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 546d90dae9331..0fd978e3ce2de 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -689,13 +689,12 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+
+ /* Port 4 supports automedia if the serdes is associated with it. */
+ if (port == 4) {
+- mv88e6xxx_reg_lock(chip);
+ err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
+ if (err < 0)
+ dev_err(chip->dev, "p%d: failed to read scratch\n",
+ port);
+ if (err <= 0)
+- goto unlock;
++ return;
+
+ cmode = mv88e6352_get_port4_serdes_cmode(chip);
+ if (cmode < 0)
+@@ -703,8 +702,6 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+ port);
+ else
+ mv88e6xxx_translate_cmode(cmode, supported);
+-unlock:
+- mv88e6xxx_reg_unlock(chip);
+ }
+ }
+
+@@ -823,7 +820,9 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
+ {
+ struct mv88e6xxx_chip *chip = ds->priv;
+
++ mv88e6xxx_reg_lock(chip);
+ chip->info->ops->phylink_get_caps(chip, port, config);
++ mv88e6xxx_reg_unlock(chip);
+
+ if (mv88e6xxx_phy_is_internal(ds, port)) {
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+@@ -3299,7 +3298,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
+ struct phylink_config pl_config = {};
+ unsigned long caps;
+
+- mv88e6xxx_get_caps(ds, port, &pl_config);
++ chip->info->ops->phylink_get_caps(chip, port, &pl_config);
+
+ caps = pl_config.mac_capabilities;
+
+diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
+index 27869164c6e62..ca12f9f488390 100644
+--- a/drivers/net/ethernet/amd/atarilance.c
++++ b/drivers/net/ethernet/amd/atarilance.c
+@@ -824,7 +824,7 @@ lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
+ head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
+ dev->stats.tx_bytes += skb->len;
+- dev_kfree_skb( skb );
++ dev_consume_skb_irq(skb);
+ lp->cur_tx++;
+ while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
+ lp->cur_tx -= TX_RING_SIZE;
+diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
+index 462016666752c..e3b8de9fc728f 100644
+--- a/drivers/net/ethernet/amd/lance.c
++++ b/drivers/net/ethernet/amd/lance.c
+@@ -1001,7 +1001,7 @@ static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+ skb_copy_from_linear_data(skb, &lp->tx_bounce_buffs[entry], skb->len);
+ lp->tx_ring[entry].base =
+ ((u32)isa_virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000;
+- dev_kfree_skb(skb);
++ dev_consume_skb_irq(skb);
+ } else {
+ lp->tx_skbuff[entry] = skb;
+ lp->tx_ring[entry].base = ((u32)isa_virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 601a9f2fa9bfc..1ef04326a5727 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -189,6 +189,7 @@ enum xgbe_sfp_cable {
+ XGBE_SFP_CABLE_UNKNOWN = 0,
+ XGBE_SFP_CABLE_ACTIVE,
+ XGBE_SFP_CABLE_PASSIVE,
++ XGBE_SFP_CABLE_FIBER,
+ };
+
+ enum xgbe_sfp_base {
+@@ -236,10 +237,7 @@ enum xgbe_sfp_speed {
+
+ #define XGBE_SFP_BASE_BR 12
+ #define XGBE_SFP_BASE_BR_1GBE_MIN 0x0a
+-#define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d
+ #define XGBE_SFP_BASE_BR_10GBE_MIN 0x64
+-#define XGBE_SFP_BASE_BR_10GBE_MAX 0x68
+-#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX 0x78
+
+ #define XGBE_SFP_BASE_CU_CABLE_LEN 18
+
+@@ -826,29 +824,22 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
+ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
+ enum xgbe_sfp_speed sfp_speed)
+ {
+- u8 *sfp_base, min, max;
++ u8 *sfp_base, min;
+
+ sfp_base = sfp_eeprom->base;
+
+ switch (sfp_speed) {
+ case XGBE_SFP_SPEED_1000:
+ min = XGBE_SFP_BASE_BR_1GBE_MIN;
+- max = XGBE_SFP_BASE_BR_1GBE_MAX;
+ break;
+ case XGBE_SFP_SPEED_10000:
+ min = XGBE_SFP_BASE_BR_10GBE_MIN;
+- if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
+- XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
+- max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
+- else
+- max = XGBE_SFP_BASE_BR_10GBE_MAX;
+ break;
+ default:
+ return false;
+ }
+
+- return ((sfp_base[XGBE_SFP_BASE_BR] >= min) &&
+- (sfp_base[XGBE_SFP_BASE_BR] <= max));
++ return sfp_base[XGBE_SFP_BASE_BR] >= min;
+ }
+
+ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
+@@ -1149,16 +1140,18 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
+ phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
+
+- /* Assume ACTIVE cable unless told it is PASSIVE */
++ /* Assume FIBER cable unless told otherwise */
+ if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) {
+ phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE;
+ phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN];
+- } else {
++ } else if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_ACTIVE) {
+ phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
++ } else {
++ phy_data->sfp_cable = XGBE_SFP_CABLE_FIBER;
+ }
+
+ /* Determine the type of SFP */
+- if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
++ if (phy_data->sfp_cable != XGBE_SFP_CABLE_FIBER &&
+ xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+ phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+ else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
+index 334de0d93c899..9e653e2925f78 100644
+--- a/drivers/net/ethernet/apple/bmac.c
++++ b/drivers/net/ethernet/apple/bmac.c
+@@ -1510,7 +1510,7 @@ static void bmac_tx_timeout(struct timer_list *t)
+ i = bp->tx_empty;
+ ++dev->stats.tx_errors;
+ if (i != bp->tx_fill) {
+- dev_kfree_skb(bp->tx_bufs[i]);
++ dev_kfree_skb_irq(bp->tx_bufs[i]);
+ bp->tx_bufs[i] = NULL;
+ if (++i >= N_TX_RING) i = 0;
+ bp->tx_empty = i;
+diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
+index d0a771b65e888..fd1b008b7208c 100644
+--- a/drivers/net/ethernet/apple/mace.c
++++ b/drivers/net/ethernet/apple/mace.c
+@@ -846,7 +846,7 @@ static void mace_tx_timeout(struct timer_list *t)
+ if (mp->tx_bad_runt) {
+ mp->tx_bad_runt = 0;
+ } else if (i != mp->tx_fill) {
+- dev_kfree_skb(mp->tx_bufs[i]);
++ dev_kfree_skb_irq(mp->tx_bufs[i]);
+ if (++i >= N_TX_RING)
+ i = 0;
+ mp->tx_empty = i;
+diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
+index 92462ed87bc43..d9f0c297ae2a0 100644
+--- a/drivers/net/ethernet/dnet.c
++++ b/drivers/net/ethernet/dnet.c
+@@ -550,11 +550,11 @@ static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+
+ skb_tx_timestamp(skb);
+
++ spin_unlock_irqrestore(&bp->lock, flags);
++
+ /* free the buffer */
+ dev_kfree_skb(skb);
+
+- spin_unlock_irqrestore(&bp->lock, flags);
+-
+ return NETDEV_TX_OK;
+ }
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 1d8ec1b120a13..525d506797fcf 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1489,23 +1489,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
+ rx_ring->stats.xdp_drops++;
+ }
+
+-static void enetc_xdp_free(struct enetc_bdr *rx_ring, int rx_ring_first,
+- int rx_ring_last)
+-{
+- while (rx_ring_first != rx_ring_last) {
+- struct enetc_rx_swbd *rx_swbd = &rx_ring->rx_swbd[rx_ring_first];
+-
+- if (rx_swbd->page) {
+- dma_unmap_page(rx_ring->dev, rx_swbd->dma, PAGE_SIZE,
+- rx_swbd->dir);
+- __free_page(rx_swbd->page);
+- rx_swbd->page = NULL;
+- }
+- enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
+- }
+- rx_ring->stats.xdp_redirect_failures++;
+-}
+-
+ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ struct napi_struct *napi, int work_limit,
+ struct bpf_prog *prog)
+@@ -1527,8 +1510,8 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ int orig_i, orig_cleaned_cnt;
+ struct xdp_buff xdp_buff;
+ struct sk_buff *skb;
+- int tmp_orig_i, err;
+ u32 bd_status;
++ int err;
+
+ rxbd = enetc_rxbd(rx_ring, i);
+ bd_status = le32_to_cpu(rxbd->r.lstatus);
+@@ -1615,18 +1598,16 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ break;
+ }
+
+- tmp_orig_i = orig_i;
+-
+- while (orig_i != i) {
+- enetc_flip_rx_buff(rx_ring,
+- &rx_ring->rx_swbd[orig_i]);
+- enetc_bdr_idx_inc(rx_ring, &orig_i);
+- }
+-
+ err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog);
+ if (unlikely(err)) {
+- enetc_xdp_free(rx_ring, tmp_orig_i, i);
++ enetc_xdp_drop(rx_ring, orig_i, i);
++ rx_ring->stats.xdp_redirect_failures++;
+ } else {
++ while (orig_i != i) {
++ enetc_flip_rx_buff(rx_ring,
++ &rx_ring->rx_swbd[orig_i]);
++ enetc_bdr_idx_inc(rx_ring, &orig_i);
++ }
+ xdp_redirect_frm_cnt++;
+ rx_ring->stats.xdp_redirect++;
+ }
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index e53ea7ed0b1d2..8c07d92a6574c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -3692,6 +3692,24 @@ static int i40e_vsi_configure_tx(struct i40e_vsi *vsi)
+ return err;
+ }
+
++/**
++ * i40e_calculate_vsi_rx_buf_len - Calculates buffer length
++ *
++ * @vsi: VSI to calculate rx_buf_len from
++ */
++static u16 i40e_calculate_vsi_rx_buf_len(struct i40e_vsi *vsi)
++{
++ if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX))
++ return I40E_RXBUFFER_2048;
++
++#if (PAGE_SIZE < 8192)
++ if (!I40E_2K_TOO_SMALL_WITH_PADDING && vsi->netdev->mtu <= ETH_DATA_LEN)
++ return I40E_RXBUFFER_1536 - NET_IP_ALIGN;
++#endif
++
++ return PAGE_SIZE < 8192 ? I40E_RXBUFFER_3072 : I40E_RXBUFFER_2048;
++}
++
+ /**
+ * i40e_vsi_configure_rx - Configure the VSI for Rx
+ * @vsi: the VSI being configured
+@@ -3703,20 +3721,14 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
+ int err = 0;
+ u16 i;
+
+- if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) {
+- vsi->max_frame = I40E_MAX_RXBUFFER;
+- vsi->rx_buf_len = I40E_RXBUFFER_2048;
++ vsi->max_frame = I40E_MAX_RXBUFFER;
++ vsi->rx_buf_len = i40e_calculate_vsi_rx_buf_len(vsi);
++
+ #if (PAGE_SIZE < 8192)
+- } else if (!I40E_2K_TOO_SMALL_WITH_PADDING &&
+- (vsi->netdev->mtu <= ETH_DATA_LEN)) {
++ if (vsi->netdev && !I40E_2K_TOO_SMALL_WITH_PADDING &&
++ vsi->netdev->mtu <= ETH_DATA_LEN)
+ vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
+- vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
+ #endif
+- } else {
+- vsi->max_frame = I40E_MAX_RXBUFFER;
+- vsi->rx_buf_len = (PAGE_SIZE < 8192) ? I40E_RXBUFFER_3072 :
+- I40E_RXBUFFER_2048;
+- }
+
+ /* set up individual rings */
+ for (i = 0; i < vsi->num_queue_pairs && !err; i++)
+@@ -13290,7 +13302,7 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
+ int i;
+
+ /* Don't allow frames that span over multiple buffers */
+- if (frame_size > vsi->rx_buf_len) {
++ if (frame_size > i40e_calculate_vsi_rx_buf_len(vsi)) {
+ NL_SET_ERR_MSG_MOD(extack, "MTU too large to enable XDP");
+ return -EINVAL;
+ }
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index ea46649b2ed3e..0e36894db9863 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -1202,8 +1202,12 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
+ if (!q_vector) {
+ q_vector = kzalloc(size, GFP_KERNEL);
+ } else if (size > ksize(q_vector)) {
+- kfree_rcu(q_vector, rcu);
+- q_vector = kzalloc(size, GFP_KERNEL);
++ struct igb_q_vector *new_q_vector;
++
++ new_q_vector = kzalloc(size, GFP_KERNEL);
++ if (new_q_vector)
++ kfree_rcu(q_vector, rcu);
++ q_vector = new_q_vector;
+ } else {
+ memset(q_vector, 0, size);
+ }
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 1e7e7071f64d2..df3e26c0cf01a 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -94,6 +94,8 @@ struct igc_ring {
+ u8 queue_index; /* logical index of the ring*/
+ u8 reg_idx; /* physical index of the ring */
+ bool launchtime_enable; /* true if LaunchTime is enabled */
++ ktime_t last_tx_cycle; /* end of the cycle with a launchtime transmission */
++ ktime_t last_ff_cycle; /* Last cycle with an active first flag */
+
+ u32 start_time;
+ u32 end_time;
+@@ -182,6 +184,7 @@ struct igc_adapter {
+
+ ktime_t base_time;
+ ktime_t cycle_time;
++ bool qbv_enable;
+
+ /* OS defined structs */
+ struct pci_dev *pdev;
+diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
+index 5c66b97c0cfac..4f2c446ace4d9 100644
+--- a/drivers/net/ethernet/intel/igc/igc_defines.h
++++ b/drivers/net/ethernet/intel/igc/igc_defines.h
+@@ -321,6 +321,8 @@
+ #define IGC_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
+ #define IGC_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+
++#define IGC_ADVTXD_TSN_CNTX_FIRST 0x00000080
++
+ /* Transmit Control */
+ #define IGC_TCTL_EN 0x00000002 /* enable Tx */
+ #define IGC_TCTL_PSP 0x00000008 /* pad short packets */
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index ebff0e04045d6..76f015196fbf4 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1000,25 +1000,118 @@ static int igc_write_mc_addr_list(struct net_device *netdev)
+ return netdev_mc_count(netdev);
+ }
+
+-static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
++static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
++ bool *first_flag, bool *insert_empty)
+ {
++ struct igc_adapter *adapter = netdev_priv(ring->netdev);
+ ktime_t cycle_time = adapter->cycle_time;
+ ktime_t base_time = adapter->base_time;
++ ktime_t now = ktime_get_clocktai();
++ ktime_t baset_est, end_of_cycle;
+ u32 launchtime;
++ s64 n;
+
+- /* FIXME: when using ETF together with taprio, we may have a
+- * case where 'delta' is larger than the cycle_time, this may
+- * cause problems if we don't read the current value of
+- * IGC_BASET, as the value writen into the launchtime
+- * descriptor field may be misinterpreted.
++ n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
++
++ baset_est = ktime_add_ns(base_time, cycle_time * (n));
++ end_of_cycle = ktime_add_ns(baset_est, cycle_time);
++
++ if (ktime_compare(txtime, end_of_cycle) >= 0) {
++ if (baset_est != ring->last_ff_cycle) {
++ *first_flag = true;
++ ring->last_ff_cycle = baset_est;
++
++ if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
++ *insert_empty = true;
++ }
++ }
++
++ /* Introducing a window at end of cycle on which packets
++ * potentially not honor launchtime. Window of 5us chosen
++ * considering software update the tail pointer and packets
++ * are dma'ed to packet buffer.
+ */
+- div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
++ if ((ktime_sub_ns(end_of_cycle, now) < 5 * NSEC_PER_USEC))
++ netdev_warn(ring->netdev, "Packet with txtime=%llu may not be honoured\n",
++ txtime);
++
++ ring->last_tx_cycle = end_of_cycle;
++
++ launchtime = ktime_sub_ns(txtime, baset_est);
++ if (launchtime > 0)
++ div_s64_rem(launchtime, cycle_time, &launchtime);
++ else
++ launchtime = 0;
+
+ return cpu_to_le32(launchtime);
+ }
+
++static int igc_init_empty_frame(struct igc_ring *ring,
++ struct igc_tx_buffer *buffer,
++ struct sk_buff *skb)
++{
++ unsigned int size;
++ dma_addr_t dma;
++
++ size = skb_headlen(skb);
++
++ dma = dma_map_single(ring->dev, skb->data, size, DMA_TO_DEVICE);
++ if (dma_mapping_error(ring->dev, dma)) {
++ netdev_err_once(ring->netdev, "Failed to map DMA for TX\n");
++ return -ENOMEM;
++ }
++
++ buffer->skb = skb;
++ buffer->protocol = 0;
++ buffer->bytecount = skb->len;
++ buffer->gso_segs = 1;
++ buffer->time_stamp = jiffies;
++ dma_unmap_len_set(buffer, len, skb->len);
++ dma_unmap_addr_set(buffer, dma, dma);
++
++ return 0;
++}
++
++static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
++ struct sk_buff *skb,
++ struct igc_tx_buffer *first)
++{
++ union igc_adv_tx_desc *desc;
++ u32 cmd_type, olinfo_status;
++ int err;
++
++ if (!igc_desc_unused(ring))
++ return -EBUSY;
++
++ err = igc_init_empty_frame(ring, first, skb);
++ if (err)
++ return err;
++
++ cmd_type = IGC_ADVTXD_DTYP_DATA | IGC_ADVTXD_DCMD_DEXT |
++ IGC_ADVTXD_DCMD_IFCS | IGC_TXD_DCMD |
++ first->bytecount;
++ olinfo_status = first->bytecount << IGC_ADVTXD_PAYLEN_SHIFT;
++
++ desc = IGC_TX_DESC(ring, ring->next_to_use);
++ desc->read.cmd_type_len = cpu_to_le32(cmd_type);
++ desc->read.olinfo_status = cpu_to_le32(olinfo_status);
++ desc->read.buffer_addr = cpu_to_le64(dma_unmap_addr(first, dma));
++
++ netdev_tx_sent_queue(txring_txq(ring), skb->len);
++
++ first->next_to_watch = desc;
++
++ ring->next_to_use++;
++ if (ring->next_to_use == ring->count)
++ ring->next_to_use = 0;
++
++ return 0;
++}
++
++#define IGC_EMPTY_FRAME_SIZE 60
++
+ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+- struct igc_tx_buffer *first,
++ __le32 launch_time, bool first_flag,
+ u32 vlan_macip_lens, u32 type_tucmd,
+ u32 mss_l4len_idx)
+ {
+@@ -1037,26 +1130,17 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+ if (test_bit(IGC_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
+ mss_l4len_idx |= tx_ring->reg_idx << 4;
+
++ if (first_flag)
++ mss_l4len_idx |= IGC_ADVTXD_TSN_CNTX_FIRST;
++
+ context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
+ context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
+ context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+-
+- /* We assume there is always a valid Tx time available. Invalid times
+- * should have been handled by the upper layers.
+- */
+- if (tx_ring->launchtime_enable) {
+- struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
+- ktime_t txtime = first->skb->tstamp;
+-
+- skb_txtime_consumed(first->skb);
+- context_desc->launch_time = igc_tx_launchtime(adapter,
+- txtime);
+- } else {
+- context_desc->launch_time = 0;
+- }
++ context_desc->launch_time = launch_time;
+ }
+
+-static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
++static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first,
++ __le32 launch_time, bool first_flag)
+ {
+ struct sk_buff *skb = first->skb;
+ u32 vlan_macip_lens = 0;
+@@ -1096,7 +1180,8 @@ no_csum:
+ vlan_macip_lens |= skb_network_offset(skb) << IGC_ADVTXD_MACLEN_SHIFT;
+ vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+
+- igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, type_tucmd, 0);
++ igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++ vlan_macip_lens, type_tucmd, 0);
+ }
+
+ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
+@@ -1320,6 +1405,7 @@ dma_error:
+
+ static int igc_tso(struct igc_ring *tx_ring,
+ struct igc_tx_buffer *first,
++ __le32 launch_time, bool first_flag,
+ u8 *hdr_len)
+ {
+ u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
+@@ -1406,8 +1492,8 @@ static int igc_tso(struct igc_ring *tx_ring,
+ vlan_macip_lens |= (ip.hdr - skb->data) << IGC_ADVTXD_MACLEN_SHIFT;
+ vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+
+- igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens,
+- type_tucmd, mss_l4len_idx);
++ igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++ vlan_macip_lens, type_tucmd, mss_l4len_idx);
+
+ return 1;
+ }
+@@ -1415,11 +1501,14 @@ static int igc_tso(struct igc_ring *tx_ring,
+ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ struct igc_ring *tx_ring)
+ {
++ bool first_flag = false, insert_empty = false;
+ u16 count = TXD_USE_COUNT(skb_headlen(skb));
+ __be16 protocol = vlan_get_protocol(skb);
+ struct igc_tx_buffer *first;
++ __le32 launch_time = 0;
+ u32 tx_flags = 0;
+ unsigned short f;
++ ktime_t txtime;
+ u8 hdr_len = 0;
+ int tso = 0;
+
+@@ -1433,11 +1522,40 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ count += TXD_USE_COUNT(skb_frag_size(
+ &skb_shinfo(skb)->frags[f]));
+
+- if (igc_maybe_stop_tx(tx_ring, count + 3)) {
++ if (igc_maybe_stop_tx(tx_ring, count + 5)) {
+ /* this is a hard error */
+ return NETDEV_TX_BUSY;
+ }
+
++ if (!tx_ring->launchtime_enable)
++ goto done;
++
++ txtime = skb->tstamp;
++ skb->tstamp = ktime_set(0, 0);
++ launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, &insert_empty);
++
++ if (insert_empty) {
++ struct igc_tx_buffer *empty_info;
++ struct sk_buff *empty;
++ void *data;
++
++ empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
++ empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
++ if (!empty)
++ goto done;
++
++ data = skb_put(empty, IGC_EMPTY_FRAME_SIZE);
++ memset(data, 0, IGC_EMPTY_FRAME_SIZE);
++
++ igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
++
++ if (igc_init_tx_empty_descriptor(tx_ring,
++ empty,
++ empty_info) < 0)
++ dev_kfree_skb_any(empty);
++ }
++
++done:
+ /* record the location of the first descriptor for this packet */
+ first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
+ first->type = IGC_TX_BUFFER_TYPE_SKB;
+@@ -1474,11 +1592,11 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ first->tx_flags = tx_flags;
+ first->protocol = protocol;
+
+- tso = igc_tso(tx_ring, first, &hdr_len);
++ tso = igc_tso(tx_ring, first, launch_time, first_flag, &hdr_len);
+ if (tso < 0)
+ goto out_drop;
+ else if (!tso)
+- igc_tx_csum(tx_ring, first);
++ igc_tx_csum(tx_ring, first, launch_time, first_flag);
+
+ igc_tx_map(tx_ring, first, hdr_len);
+
+@@ -5881,10 +5999,16 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ bool queue_configured[IGC_MAX_TX_QUEUES] = { };
+ u32 start_time = 0, end_time = 0;
+ size_t n;
++ int i;
++
++ adapter->qbv_enable = qopt->enable;
+
+ if (!qopt->enable)
+ return igc_tsn_clear_schedule(adapter);
+
++ if (qopt->base_time < 0)
++ return -ERANGE;
++
+ if (adapter->base_time)
+ return -EALREADY;
+
+@@ -5896,10 +6020,24 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+
+ for (n = 0; n < qopt->num_entries; n++) {
+ struct tc_taprio_sched_entry *e = &qopt->entries[n];
+- int i;
+
+ end_time += e->interval;
+
++ /* If any of the conditions below are true, we need to manually
++ * control the end time of the cycle.
++ * 1. Qbv users can specify a cycle time that is not equal
++ * to the total GCL intervals. Hence, recalculation is
++ * necessary here to exclude the time interval that
++ * exceeds the cycle time.
++ * 2. According to IEEE Std. 802.1Q-2018 section 8.6.9.2,
++ * once the end of the list is reached, it will switch
++ * to the END_OF_CYCLE state and leave the gates in the
++ * same state until the next cycle is started.
++ */
++ if (end_time > adapter->cycle_time ||
++ n + 1 == qopt->num_entries)
++ end_time = adapter->cycle_time;
++
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igc_ring *ring = adapter->tx_ring[i];
+
+@@ -5920,6 +6058,18 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ start_time += e->interval;
+ }
+
++ /* Check whether a queue gets configured.
++ * If not, set the start and end time to be end time.
++ */
++ for (i = 0; i < adapter->num_tx_queues; i++) {
++ if (!queue_configured[i]) {
++ struct igc_ring *ring = adapter->tx_ring[i];
++
++ ring->start_time = end_time;
++ ring->end_time = end_time;
++ }
++ }
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
+index 0fce22de2ab85..356c7455c5cee 100644
+--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
+@@ -36,7 +36,7 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
+ {
+ unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
+
+- if (adapter->base_time)
++ if (adapter->qbv_enable)
+ new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
+
+ if (is_any_launchtime(adapter))
+@@ -110,15 +110,8 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
+ wr32(IGC_STQT(i), ring->start_time);
+ wr32(IGC_ENDQT(i), ring->end_time);
+
+- if (adapter->base_time) {
+- /* If we have a base_time we are in "taprio"
+- * mode and we need to be strict about the
+- * cycles: only transmit a packet if it can be
+- * completed during that cycle.
+- */
+- txqctl |= IGC_TXQCTL_STRICT_CYCLE |
+- IGC_TXQCTL_STRICT_END;
+- }
++ txqctl |= IGC_TXQCTL_STRICT_CYCLE |
++ IGC_TXQCTL_STRICT_END;
+
+ if (ring->launchtime_enable)
+ txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 5380caf0acc2f..559c7a42c1c9c 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3209,6 +3209,30 @@ static void mtk_dim_tx(struct work_struct *work)
+ dim->state = DIM_START_MEASURE;
+ }
+
++static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val)
++{
++ struct mtk_eth *eth = mac->hw;
++ u32 mcr_cur, mcr_new;
++
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
++ return;
++
++ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
++ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
++
++ if (val <= 1518)
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
++ else if (val <= 1536)
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
++ else if (val <= 1552)
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
++ else
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
++
++ if (mcr_new != mcr_cur)
++ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
++}
++
+ static int mtk_hw_init(struct mtk_eth *eth)
+ {
+ u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
+@@ -3248,16 +3272,17 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ return 0;
+ }
+
+- val = RSTCTRL_FE | RSTCTRL_PPE;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+-
+- val |= RSTCTRL_ETH;
+- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+- val |= RSTCTRL_PPE1;
++ val = RSTCTRL_PPE0_V2;
++ } else {
++ val = RSTCTRL_PPE0;
+ }
+
+- ethsys_reset(eth, val);
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++ val |= RSTCTRL_PPE1;
++
++ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+@@ -3283,8 +3308,16 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ * up with the more appropriate value when mtk_mac_config call is being
+ * invoked.
+ */
+- for (i = 0; i < MTK_MAC_COUNT; i++)
++ for (i = 0; i < MTK_MAC_COUNT; i++) {
++ struct net_device *dev = eth->netdev[i];
++
+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
++ if (dev) {
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
++ }
++ }
+
+ /* Indicates CDM to parse the MTK special tag from CPU
+ * which also is working out for untag packets.
+@@ -3311,9 +3344,12 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+- /* PSE should not drop port8 and port9 packets */
++ /* PSE should not drop port8 and port9 packets from WDMA Tx */
+ mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+
++ /* PSE should drop packets to port 8/9 on WDMA Rx ring full */
++ mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
++
+ /* PSE Free Queue Flow Control */
+ mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
+
+@@ -3400,7 +3436,6 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+ int length = new_mtu + MTK_RX_ETH_HLEN;
+ struct mtk_mac *mac = netdev_priv(dev);
+ struct mtk_eth *eth = mac->hw;
+- u32 mcr_cur, mcr_new;
+
+ if (rcu_access_pointer(eth->prog) &&
+ length > MTK_PP_MAX_BUF_SIZE) {
+@@ -3408,23 +3443,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+ return -EINVAL;
+ }
+
+- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
+- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
+-
+- if (length <= 1518)
+- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
+- else if (length <= 1536)
+- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
+- else if (length <= 1552)
+- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
+- else
+- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
+-
+- if (mcr_new != mcr_cur)
+- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
+- }
+-
++ mtk_set_mcr_max_rx(mac, length);
+ dev->mtu = new_mtu;
+
+ return 0;
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index 0f9668a4079d9..df8e6e95254ec 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -121,6 +121,7 @@
+ #define PSE_FQFC_CFG1 0x100
+ #define PSE_FQFC_CFG2 0x104
+ #define PSE_DROP_CFG 0x108
++#define PSE_PPE0_DROP 0x110
+
+ /* PSE Input Queue Reservation Register*/
+ #define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
+@@ -451,18 +452,14 @@
+ /* ethernet reset control register */
+ #define ETHSYS_RSTCTRL 0x34
+ #define RSTCTRL_FE BIT(6)
+-#define RSTCTRL_PPE BIT(31)
+-#define RSTCTRL_PPE1 BIT(30)
++#define RSTCTRL_PPE0 BIT(31)
++#define RSTCTRL_PPE0_V2 BIT(30)
++#define RSTCTRL_PPE1 BIT(31)
+ #define RSTCTRL_ETH BIT(23)
+
+ /* ethernet reset check idle register */
+ #define ETHSYS_FE_RST_CHK_IDLE_EN 0x28
+
+-/* ethernet reset control register */
+-#define ETHSYS_RSTCTRL 0x34
+-#define RSTCTRL_FE BIT(6)
+-#define RSTCTRL_PPE BIT(31)
+-
+ /* ethernet dma channel agent map */
+ #define ETHSYS_DMA_AG_MAP 0x408
+ #define ETHSYS_DMA_AG_MAP_PDMA BIT(0)
+diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+index 971dde8c32864..35410c9a3ecf0 100644
+--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+@@ -3913,6 +3913,7 @@ abort_with_slices:
+ myri10ge_free_slices(mgp);
+
+ abort_with_firmware:
++ kfree(mgp->msix_vectors);
+ myri10ge_dummy_rdma(mgp, 0);
+
+ abort_with_ioremap:
+diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
+index 8f74c039b3be2..29d39e5b9cf53 100644
+--- a/drivers/net/ethernet/neterion/s2io.c
++++ b/drivers/net/ethernet/neterion/s2io.c
+@@ -2386,7 +2386,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
+ skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+ if (skb) {
+ swstats->mem_freed += skb->truesize;
+- dev_kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ cnt++;
+ }
+ }
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 5250d1d1e49ca..86ecb080b1536 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -1972,9 +1972,10 @@ static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
+ u8 split_id)
+ {
+ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+- u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
++ u8 port_id = 0, pf_id = 0, vf_id = 0;
+ bool read_using_dmae = false;
+ u32 thresh;
++ u16 fid;
+
+ if (!dump)
+ return len;
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+index 9282321c2e7fb..f9dd50152b1e3 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+@@ -221,6 +221,8 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
+ return 0;
+
+ qlcnic_destroy_async_wq:
++ while (i--)
++ kfree(sriov->vf_info[i].vp);
+ destroy_workqueue(bc->bc_async_wq);
+
+ qlcnic_destroy_trans_wq:
+diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
+index a6bf7d5051786..322d4d72d2e05 100644
+--- a/drivers/net/ethernet/rdc/r6040.c
++++ b/drivers/net/ethernet/rdc/r6040.c
+@@ -1159,10 +1159,12 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ err = register_netdev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register net device\n");
+- goto err_out_mdio_unregister;
++ goto err_out_phy_disconnect;
+ }
+ return 0;
+
++err_out_phy_disconnect:
++ phy_disconnect(dev->phydev);
+ err_out_mdio_unregister:
+ mdiobus_unregister(lp->mii_bus);
+ err_out_mdio:
+@@ -1186,6 +1188,7 @@ static void r6040_remove_one(struct pci_dev *pdev)
+ struct r6040_private *lp = netdev_priv(dev);
+
+ unregister_netdev(dev);
++ phy_disconnect(dev->phydev);
+ mdiobus_unregister(lp->mii_bus);
+ mdiobus_free(lp->mii_bus);
+ netif_napi_del(&lp->napi);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+index 764832f4dae1a..8b50f03056b7b 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+@@ -47,7 +47,8 @@ static void config_sub_second_increment(void __iomem *ioaddr,
+ if (!(value & PTP_TCR_TSCTRLSSR))
+ data = (data * 1000) / 465;
+
+- data &= PTP_SSIR_SSINC_MASK;
++ if (data > PTP_SSIR_SSINC_MAX)
++ data = PTP_SSIR_SSINC_MAX;
+
+ reg_value = data;
+ if (gmac4)
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 0f080bfe8b176..bc4be1157aba7 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -7115,7 +7115,8 @@ int stmmac_dvr_probe(struct device *device,
+ priv->wq = create_singlethread_workqueue("stmmac_wq");
+ if (!priv->wq) {
+ dev_err(priv->device, "failed to create workqueue\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto error_wq_init;
+ }
+
+ INIT_WORK(&priv->service_task, stmmac_service_task);
+@@ -7343,6 +7344,7 @@ error_mdio_register:
+ stmmac_napi_del(ndev);
+ error_hw_init:
+ destroy_workqueue(priv->wq);
++error_wq_init:
+ bitmap_free(priv->af_xdp_zc_qps);
+
+ return ret;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+index 53172a4398101..bf619295d079f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+@@ -64,7 +64,7 @@
+ #define PTP_TCR_TSENMACADDR BIT(18)
+
+ /* SSIR defines */
+-#define PTP_SSIR_SSINC_MASK 0xff
++#define PTP_SSIR_SSINC_MAX 0xff
+ #define GMAC4_PTP_SSIR_SSINC_SHIFT 16
+
+ /* Auxiliary Control defines */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+index 49af7e78b7f59..687f43cd466c6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+@@ -1654,12 +1654,16 @@ static int stmmac_test_arpoffload(struct stmmac_priv *priv)
+ }
+
+ ret = stmmac_set_arp_offload(priv, priv->hw, true, ip_addr);
+- if (ret)
++ if (ret) {
++ kfree_skb(skb);
+ goto cleanup;
++ }
+
+ ret = dev_set_promiscuity(priv->dev, 1);
+- if (ret)
++ if (ret) {
++ kfree_skb(skb);
+ goto cleanup;
++ }
+
+ ret = dev_direct_xmit(skb, 0);
+ if (ret)
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 47da11b9ac286..58678843d7948 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -562,13 +562,13 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ ret = netif_set_real_num_tx_queues(ndev, common->tx_ch_num);
+ if (ret) {
+ dev_err(common->dev, "cannot set real number of tx queues\n");
+- return ret;
++ goto runtime_put;
+ }
+
+ ret = netif_set_real_num_rx_queues(ndev, AM65_CPSW_MAX_RX_QUEUES);
+ if (ret) {
+ dev_err(common->dev, "cannot set real number of rx queues\n");
+- return ret;
++ goto runtime_put;
+ }
+
+ for (i = 0; i < common->tx_ch_num; i++)
+@@ -576,7 +576,7 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+
+ ret = am65_cpsw_nuss_common_open(common, ndev->features);
+ if (ret)
+- return ret;
++ goto runtime_put;
+
+ common->usage_count++;
+
+@@ -609,6 +609,10 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ error_cleanup:
+ am65_cpsw_nuss_ndo_slave_stop(ndev);
+ return ret;
++
++runtime_put:
++ pm_runtime_put(common->dev);
++ return ret;
+ }
+
+ static void am65_cpsw_nuss_rx_cleanup(void *data, dma_addr_t desc_dma)
+diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
+index b15d44261e766..2672525609425 100644
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1261,7 +1261,7 @@ out:
+ }
+
+ /* Submit the packet */
+-static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++static netdev_tx_t netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+ struct netcp_intf *netcp = netdev_priv(ndev);
+ struct netcp_stats *tx_stats = &netcp->stats;
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index 016a9c4f2c6c7..ce0444b09664f 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -536,7 +536,7 @@ static void xemaclite_tx_timeout(struct net_device *dev, unsigned int txqueue)
+ xemaclite_enable_interrupts(lp);
+
+ if (lp->deferred_skb) {
+- dev_kfree_skb(lp->deferred_skb);
++ dev_kfree_skb_irq(lp->deferred_skb);
+ lp->deferred_skb = NULL;
+ dev->stats.tx_errors++;
+ }
+diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
+index b584ffe38ad68..1fef8a9b1a0fd 100644
+--- a/drivers/net/fddi/defxx.c
++++ b/drivers/net/fddi/defxx.c
+@@ -3831,10 +3831,24 @@ static int dfx_init(void)
+ int status;
+
+ status = pci_register_driver(&dfx_pci_driver);
+- if (!status)
+- status = eisa_driver_register(&dfx_eisa_driver);
+- if (!status)
+- status = tc_register_driver(&dfx_tc_driver);
++ if (status)
++ goto err_pci_register;
++
++ status = eisa_driver_register(&dfx_eisa_driver);
++ if (status)
++ goto err_eisa_register;
++
++ status = tc_register_driver(&dfx_tc_driver);
++ if (status)
++ goto err_tc_register;
++
++ return 0;
++
++err_tc_register:
++ eisa_driver_unregister(&dfx_eisa_driver);
++err_eisa_register:
++ pci_unregister_driver(&dfx_pci_driver);
++err_pci_register:
+ return status;
+ }
+
+diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
+index 3e69079ed694b..94720f8a8ba5e 100644
+--- a/drivers/net/hamradio/baycom_epp.c
++++ b/drivers/net/hamradio/baycom_epp.c
+@@ -758,7 +758,7 @@ static void epp_bh(struct work_struct *work)
+ * ===================== network driver interface =========================
+ */
+
+-static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct baycom_state *bc = netdev_priv(dev);
+
+diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
+index f90830d3dfa69..a9184a78650b0 100644
+--- a/drivers/net/hamradio/scc.c
++++ b/drivers/net/hamradio/scc.c
+@@ -302,12 +302,12 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
+ spin_lock_irqsave(&scc->lock, flags);
+ if (scc->tx_buff != NULL)
+ {
+- dev_kfree_skb(scc->tx_buff);
++ dev_kfree_skb_irq(scc->tx_buff);
+ scc->tx_buff = NULL;
+ }
+
+ while (!skb_queue_empty(&scc->tx_queue))
+- dev_kfree_skb(skb_dequeue(&scc->tx_queue));
++ dev_kfree_skb_irq(skb_dequeue(&scc->tx_queue));
+
+ spin_unlock_irqrestore(&scc->lock, flags);
+ }
+@@ -1668,7 +1668,7 @@ static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
+ if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) {
+ struct sk_buff *skb_del;
+ skb_del = skb_dequeue(&scc->tx_queue);
+- dev_kfree_skb(skb_del);
++ dev_kfree_skb_irq(skb_del);
+ }
+ skb_queue_tail(&scc->tx_queue, skb);
+ netif_trans_update(dev);
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 8dafc814282cb..022b2daabd74d 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2621,7 +2621,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ const struct macsec_ops *ops;
+ struct macsec_context ctx;
+ struct macsec_dev *macsec;
+- int ret;
++ int ret = 0;
+
+ if (!attrs[MACSEC_ATTR_IFINDEX])
+ return -EINVAL;
+@@ -2634,28 +2634,36 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ macsec_genl_offload_policy, NULL))
+ return -EINVAL;
+
++ rtnl_lock();
++
+ dev = get_dev_from_nl(genl_info_net(info), attrs);
+- if (IS_ERR(dev))
+- return PTR_ERR(dev);
++ if (IS_ERR(dev)) {
++ ret = PTR_ERR(dev);
++ goto out;
++ }
+ macsec = macsec_priv(dev);
+
+- if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE])
+- return -EINVAL;
++ if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]) {
++ ret = -EINVAL;
++ goto out;
++ }
+
+ offload = nla_get_u8(tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
+ if (macsec->offload == offload)
+- return 0;
++ goto out;
+
+ /* Check if the offloading mode is supported by the underlying layers */
+ if (offload != MACSEC_OFFLOAD_OFF &&
+- !macsec_check_offload(offload, macsec))
+- return -EOPNOTSUPP;
++ !macsec_check_offload(offload, macsec)) {
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
+
+ /* Check if the net device is busy. */
+- if (netif_running(dev))
+- return -EBUSY;
+-
+- rtnl_lock();
++ if (netif_running(dev)) {
++ ret = -EBUSY;
++ goto out;
++ }
+
+ prev_offload = macsec->offload;
+ macsec->offload = offload;
+@@ -2690,7 +2698,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+
+ rollback:
+ macsec->offload = prev_offload;
+-
++out:
+ rtnl_unlock();
+ return ret;
+ }
+diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c
+index 7cd103fd34ef7..9f9eaf896047c 100644
+--- a/drivers/net/mctp/mctp-serial.c
++++ b/drivers/net/mctp/mctp-serial.c
+@@ -35,6 +35,8 @@
+ #define BYTE_FRAME 0x7e
+ #define BYTE_ESC 0x7d
+
++#define FCS_INIT 0xffff
++
+ static DEFINE_IDA(mctp_serial_ida);
+
+ enum mctp_serial_state {
+@@ -123,7 +125,7 @@ static void mctp_serial_tx_work(struct work_struct *work)
+ buf[2] = dev->txlen;
+
+ if (!dev->txpos)
+- dev->txfcs = crc_ccitt(0, buf + 1, 2);
++ dev->txfcs = crc_ccitt(FCS_INIT, buf + 1, 2);
+
+ txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
+ if (txlen <= 0) {
+@@ -303,7 +305,7 @@ static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
+ case 1:
+ if (c == MCTP_SERIAL_VERSION) {
+ dev->rxpos++;
+- dev->rxfcs = crc_ccitt_byte(0, c);
++ dev->rxfcs = crc_ccitt_byte(FCS_INIT, c);
+ } else {
+ dev->rxstate = STATE_ERR;
+ }
+diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
+index dd7e273c90cbd..29b198472a2ca 100644
+--- a/drivers/net/ntb_netdev.c
++++ b/drivers/net/ntb_netdev.c
+@@ -137,7 +137,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
+ enqueue_again:
+ rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);
+ if (rc) {
+- dev_kfree_skb(skb);
++ dev_kfree_skb_any(skb);
+ ndev->stats.rx_errors++;
+ ndev->stats.rx_fifo_errors++;
+ }
+@@ -192,7 +192,7 @@ static void ntb_netdev_tx_handler(struct ntb_transport_qp *qp, void *qp_data,
+ ndev->stats.tx_aborted_errors++;
+ }
+
+- dev_kfree_skb(skb);
++ dev_kfree_skb_any(skb);
+
+ if (ntb_transport_tx_free_entry(dev->qp) >= tx_start) {
+ /* Make sure anybody stopping the queue after this sees the new
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 9206c660a72ed..d4c821c8cf57c 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -1743,6 +1743,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
+ int len;
+ unsigned char *cp;
+
++ skb->dev = ppp->dev;
++
+ if (proto < 0x8000) {
+ #ifdef CONFIG_PPP_FILTER
+ /* check if we should pass this packet */
+diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
+index 6a212c085435b..5b01642ca44e0 100644
+--- a/drivers/net/wan/farsync.c
++++ b/drivers/net/wan/farsync.c
+@@ -2545,6 +2545,7 @@ fst_remove_one(struct pci_dev *pdev)
+ struct net_device *dev = port_to_dev(&card->ports[i]);
+
+ unregister_hdlc_device(dev);
++ free_netdev(dev);
+ }
+
+ fst_disable_intr(card);
+@@ -2564,6 +2565,7 @@ fst_remove_one(struct pci_dev *pdev)
+ card->tx_dma_handle_card);
+ }
+ fst_card_array[card->card_no] = NULL;
++ kfree(card);
+ }
+
+ static struct pci_driver fst_driver = {
+diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
+index 6f937d2cc1263..ce3d613fa36c4 100644
+--- a/drivers/net/wireless/ath/ar5523/ar5523.c
++++ b/drivers/net/wireless/ath/ar5523/ar5523.c
+@@ -241,6 +241,11 @@ static void ar5523_cmd_tx_cb(struct urb *urb)
+ }
+ }
+
++static void ar5523_cancel_tx_cmd(struct ar5523 *ar)
++{
++ usb_kill_urb(ar->tx_cmd.urb_tx);
++}
++
+ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+ int ilen, void *odata, int olen, int flags)
+ {
+@@ -280,6 +285,7 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+ }
+
+ if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) {
++ ar5523_cancel_tx_cmd(ar);
+ cmd->odata = NULL;
+ ar5523_err(ar, "timeout waiting for command %02x reply\n",
+ code);
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index d1ac64026cb31..9a8ea7231a9ee 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -99,6 +99,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA988X_HW_2_0_VERSION,
+@@ -138,6 +139,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9887_HW_1_0_VERSION,
+@@ -178,6 +180,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA6174_HW_3_2_VERSION,
+@@ -213,6 +216,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -252,6 +256,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -291,6 +296,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA6174_HW_3_0_VERSION,
+@@ -330,6 +336,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA6174_HW_3_2_VERSION,
+@@ -373,6 +380,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -418,6 +426,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9984_HW_1_0_DEV_VERSION,
+@@ -470,6 +479,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9888_HW_2_0_DEV_VERSION,
+@@ -519,6 +529,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -558,6 +569,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -599,6 +611,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -631,6 +644,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = QCA4019_HW_1_0_DEV_VERSION,
+@@ -677,6 +691,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = false,
+ .hw_restart_disconnect = false,
+ .use_fw_tx_credits = true,
++ .delay_unmap_buffer = false,
+ },
+ {
+ .id = WCN3990_HW_1_0_DEV_VERSION,
+@@ -709,6 +724,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ .dynamic_sar_support = true,
+ .hw_restart_disconnect = true,
+ .use_fw_tx_credits = false,
++ .delay_unmap_buffer = true,
+ },
+ };
+
+diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
+index 6d1784f74bea4..5bfeecb95fca2 100644
+--- a/drivers/net/wireless/ath/ath10k/htc.c
++++ b/drivers/net/wireless/ath/ath10k/htc.c
+@@ -56,6 +56,15 @@ void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
+ ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
+ ep->eid, skb);
+
++ /* A corner case where the copy completion is reaching to host but still
++ * copy engine is processing it due to which host unmaps corresponding
++ * memory and causes SMMU fault, hence as workaround adding delay
++ * the unmapping memory to avoid SMMU faults.
++ */
++ if (ar->hw_params.delay_unmap_buffer &&
++ ep->ul_pipe_id == 3)
++ mdelay(2);
++
+ hdr = (struct ath10k_htc_hdr *)skb->data;
+ ath10k_htc_restore_tx_skb(ep->htc, skb);
+
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
+index 1b99f3a39a113..9643031a4427a 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -637,6 +637,8 @@ struct ath10k_hw_params {
+ bool hw_restart_disconnect;
+
+ bool use_fw_tx_credits;
++
++ bool delay_unmap_buffer;
+ };
+
+ struct htt_resp;
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index bf1c938be7d0a..8015b457a870f 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3793,18 +3793,22 @@ static struct pci_driver ath10k_pci_driver = {
+
+ static int __init ath10k_pci_init(void)
+ {
+- int ret;
++ int ret1, ret2;
+
+- ret = pci_register_driver(&ath10k_pci_driver);
+- if (ret)
++ ret1 = pci_register_driver(&ath10k_pci_driver);
++ if (ret1)
+ printk(KERN_ERR "failed to register ath10k pci driver: %d\n",
+- ret);
++ ret1);
+
+- ret = ath10k_ahb_init();
+- if (ret)
+- printk(KERN_ERR "ahb init failed: %d\n", ret);
++ ret2 = ath10k_ahb_init();
++ if (ret2)
++ printk(KERN_ERR "ahb init failed: %d\n", ret2);
+
+- return ret;
++ if (ret1 && ret2)
++ return ret1;
++
++ /* registered to at least one bus */
++ return 0;
+ }
+ module_init(ath10k_pci_init);
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 9df6aaae8a443..1e9e4eae7a1e0 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -535,6 +535,52 @@ static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base
+ return &ab->pdevs[0];
+ }
+
++void ath11k_fw_stats_pdevs_free(struct list_head *head)
++{
++ struct ath11k_fw_stats_pdev *i, *tmp;
++
++ list_for_each_entry_safe(i, tmp, head, list) {
++ list_del(&i->list);
++ kfree(i);
++ }
++}
++
++void ath11k_fw_stats_vdevs_free(struct list_head *head)
++{
++ struct ath11k_fw_stats_vdev *i, *tmp;
++
++ list_for_each_entry_safe(i, tmp, head, list) {
++ list_del(&i->list);
++ kfree(i);
++ }
++}
++
++void ath11k_fw_stats_bcn_free(struct list_head *head)
++{
++ struct ath11k_fw_stats_bcn *i, *tmp;
++
++ list_for_each_entry_safe(i, tmp, head, list) {
++ list_del(&i->list);
++ kfree(i);
++ }
++}
++
++void ath11k_fw_stats_init(struct ath11k *ar)
++{
++ INIT_LIST_HEAD(&ar->fw_stats.pdevs);
++ INIT_LIST_HEAD(&ar->fw_stats.vdevs);
++ INIT_LIST_HEAD(&ar->fw_stats.bcn);
++
++ init_completion(&ar->fw_stats_complete);
++}
++
++void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
++{
++ ath11k_fw_stats_pdevs_free(&stats->pdevs);
++ ath11k_fw_stats_vdevs_free(&stats->vdevs);
++ ath11k_fw_stats_bcn_free(&stats->bcn);
++}
++
+ int ath11k_core_suspend(struct ath11k_base *ab)
+ {
+ int ret;
+diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
+index afad8f55e4331..8edc1f4e5694d 100644
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -498,6 +498,8 @@ struct ath11k_sta {
+
+ bool use_4addr_set;
+ u16 tcl_metadata;
++
++ u32 bw_prev;
+ };
+
+ #define ATH11K_MIN_5G_FREQ 4150
+@@ -545,9 +547,6 @@ struct ath11k_debug {
+ struct dentry *debugfs_pdev;
+ struct ath11k_dbg_htt_stats htt_stats;
+ u32 extd_tx_stats;
+- struct ath11k_fw_stats fw_stats;
+- struct completion fw_stats_complete;
+- bool fw_stats_done;
+ u32 extd_rx_stats;
+ u32 pktlog_filter;
+ u32 pktlog_mode;
+@@ -710,6 +709,9 @@ struct ath11k {
+ u8 twt_enabled;
+ bool nlo_enabled;
+ u8 alpha2[REG_ALPHA2_LEN + 1];
++ struct ath11k_fw_stats fw_stats;
++ struct completion fw_stats_complete;
++ bool fw_stats_done;
+ };
+
+ struct ath11k_band_cap {
+@@ -1112,6 +1114,12 @@ struct ath11k_fw_stats_bcn {
+ u32 tx_bcn_outage_cnt;
+ };
+
++void ath11k_fw_stats_init(struct ath11k *ar);
++void ath11k_fw_stats_pdevs_free(struct list_head *head);
++void ath11k_fw_stats_vdevs_free(struct list_head *head);
++void ath11k_fw_stats_bcn_free(struct list_head *head);
++void ath11k_fw_stats_free(struct ath11k_fw_stats *stats);
++
+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq8074[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq8074[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018[];
+diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
+index 9648e00173936..649bf4495e4ac 100644
+--- a/drivers/net/wireless/ath/ath11k/debugfs.c
++++ b/drivers/net/wireless/ath/ath11k/debugfs.c
+@@ -91,91 +91,35 @@ void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
+ spin_unlock_bh(&dbr_data->lock);
+ }
+
+-static void ath11k_fw_stats_pdevs_free(struct list_head *head)
+-{
+- struct ath11k_fw_stats_pdev *i, *tmp;
+-
+- list_for_each_entry_safe(i, tmp, head, list) {
+- list_del(&i->list);
+- kfree(i);
+- }
+-}
+-
+-static void ath11k_fw_stats_vdevs_free(struct list_head *head)
+-{
+- struct ath11k_fw_stats_vdev *i, *tmp;
+-
+- list_for_each_entry_safe(i, tmp, head, list) {
+- list_del(&i->list);
+- kfree(i);
+- }
+-}
+-
+-static void ath11k_fw_stats_bcn_free(struct list_head *head)
+-{
+- struct ath11k_fw_stats_bcn *i, *tmp;
+-
+- list_for_each_entry_safe(i, tmp, head, list) {
+- list_del(&i->list);
+- kfree(i);
+- }
+-}
+-
+ static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
+ {
+ spin_lock_bh(&ar->data_lock);
+- ar->debug.fw_stats_done = false;
+- ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
+- ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
++ ar->fw_stats_done = false;
++ ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
++ ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
+ spin_unlock_bh(&ar->data_lock);
+ }
+
+-void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
++void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
+ {
+- struct ath11k_fw_stats stats = {};
+- struct ath11k *ar;
++ struct ath11k_base *ab = ar->ab;
+ struct ath11k_pdev *pdev;
+ bool is_end;
+ static unsigned int num_vdev, num_bcn;
+ size_t total_vdevs_started = 0;
+- int i, ret;
+-
+- INIT_LIST_HEAD(&stats.pdevs);
+- INIT_LIST_HEAD(&stats.vdevs);
+- INIT_LIST_HEAD(&stats.bcn);
+-
+- ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
+- if (ret) {
+- ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
+- goto free;
+- }
+-
+- rcu_read_lock();
+- ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
+- if (!ar) {
+- rcu_read_unlock();
+- ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
+- stats.pdev_id, ret);
+- goto free;
+- }
++ int i;
+
+- spin_lock_bh(&ar->data_lock);
++ /* WMI_REQUEST_PDEV_STAT request has been already processed */
+
+- if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
+- list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
+- ar->debug.fw_stats_done = true;
+- goto complete;
+- }
+-
+- if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
+- ar->debug.fw_stats_done = true;
+- goto complete;
++ if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
++ ar->fw_stats_done = true;
++ return;
+ }
+
+- if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
+- if (list_empty(&stats.vdevs)) {
++ if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
++ if (list_empty(&stats->vdevs)) {
+ ath11k_warn(ab, "empty vdev stats");
+- goto complete;
++ return;
+ }
+ /* FW sends all the active VDEV stats irrespective of PDEV,
+ * hence limit until the count of all VDEVs started
+@@ -188,43 +132,34 @@ void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb
+
+ is_end = ((++num_vdev) == total_vdevs_started);
+
+- list_splice_tail_init(&stats.vdevs,
+- &ar->debug.fw_stats.vdevs);
++ list_splice_tail_init(&stats->vdevs,
++ &ar->fw_stats.vdevs);
+
+ if (is_end) {
+- ar->debug.fw_stats_done = true;
++ ar->fw_stats_done = true;
+ num_vdev = 0;
+ }
+- goto complete;
++ return;
+ }
+
+- if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
+- if (list_empty(&stats.bcn)) {
++ if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
++ if (list_empty(&stats->bcn)) {
+ ath11k_warn(ab, "empty bcn stats");
+- goto complete;
++ return;
+ }
+ /* Mark end until we reached the count of all started VDEVs
+ * within the PDEV
+ */
+ is_end = ((++num_bcn) == ar->num_started_vdevs);
+
+- list_splice_tail_init(&stats.bcn,
+- &ar->debug.fw_stats.bcn);
++ list_splice_tail_init(&stats->bcn,
++ &ar->fw_stats.bcn);
+
+ if (is_end) {
+- ar->debug.fw_stats_done = true;
++ ar->fw_stats_done = true;
+ num_bcn = 0;
+ }
+ }
+-complete:
+- complete(&ar->debug.fw_stats_complete);
+- rcu_read_unlock();
+- spin_unlock_bh(&ar->data_lock);
+-
+-free:
+- ath11k_fw_stats_pdevs_free(&stats.pdevs);
+- ath11k_fw_stats_vdevs_free(&stats.vdevs);
+- ath11k_fw_stats_bcn_free(&stats.bcn);
+ }
+
+ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+@@ -245,7 +180,7 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+
+ ath11k_debugfs_fw_stats_reset(ar);
+
+- reinit_completion(&ar->debug.fw_stats_complete);
++ reinit_completion(&ar->fw_stats_complete);
+
+ ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
+
+@@ -255,9 +190,8 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+ return ret;
+ }
+
+- time_left =
+- wait_for_completion_timeout(&ar->debug.fw_stats_complete,
+- 1 * HZ);
++ time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
++
+ if (!time_left)
+ return -ETIMEDOUT;
+
+@@ -266,7 +200,7 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+ break;
+
+ spin_lock_bh(&ar->data_lock);
+- if (ar->debug.fw_stats_done) {
++ if (ar->fw_stats_done) {
+ spin_unlock_bh(&ar->data_lock);
+ break;
+ }
+@@ -338,8 +272,7 @@ static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
+ goto err_free;
+ }
+
+- ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+- buf);
++ ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+
+ file->private_data = buf;
+
+@@ -410,8 +343,7 @@ static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
+ goto err_free;
+ }
+
+- ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+- buf);
++ ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+
+ file->private_data = buf;
+
+@@ -488,14 +420,13 @@ static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
+ }
+ }
+
+- ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+- buf);
++ ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+
+ /* since beacon stats request is looped for all active VDEVs, saved fw
+ * stats is not freed for each request until done for all active VDEVs
+ */
+ spin_lock_bh(&ar->data_lock);
+- ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
++ ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
+ spin_unlock_bh(&ar->data_lock);
+
+ file->private_data = buf;
+@@ -1025,7 +956,7 @@ void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
+ struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
+ ar->debug.debugfs_pdev);
+
+- ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
++ ar->fw_stats.debugfs_fwstats = fwstats_dir;
+
+ /* all stats debugfs files created are under "fw_stats" directory
+ * created per PDEV
+@@ -1036,12 +967,6 @@ void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
+ &fops_vdev_stats);
+ debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
+ &fops_bcn_stats);
+-
+- INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
+- INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
+- INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
+-
+- init_completion(&ar->debug.fw_stats_complete);
+ }
+
+ static ssize_t ath11k_write_pktlog_filter(struct file *file,
+diff --git a/drivers/net/wireless/ath/ath11k/debugfs.h b/drivers/net/wireless/ath/ath11k/debugfs.h
+index 30c00cb283118..0a84645e2e063 100644
+--- a/drivers/net/wireless/ath/ath11k/debugfs.h
++++ b/drivers/net/wireless/ath/ath11k/debugfs.h
+@@ -269,7 +269,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab);
+ void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab);
+ int ath11k_debugfs_register(struct ath11k *ar);
+ void ath11k_debugfs_unregister(struct ath11k *ar);
+-void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb);
++void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats);
+
+ void ath11k_debugfs_fw_stats_init(struct ath11k *ar);
+ int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
+@@ -341,8 +341,8 @@ static inline void ath11k_debugfs_unregister(struct ath11k *ar)
+ {
+ }
+
+-static inline void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab,
+- struct sk_buff *skb)
++static inline void ath11k_debugfs_fw_stats_process(struct ath11k *ar,
++ struct ath11k_fw_stats *stats)
+ {
+ }
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 7f6521314b2d4..475ed20b495d0 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -4209,10 +4209,11 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ const u8 *ht_mcs_mask;
+ const u16 *vht_mcs_mask;
+ const u16 *he_mcs_mask;
+- u32 changed, bw, nss, smps;
++ u32 changed, bw, nss, smps, bw_prev;
+ int err, num_vht_rates, num_he_rates;
+ const struct cfg80211_bitrate_mask *mask;
+ struct peer_assoc_params peer_arg;
++ enum wmi_phy_mode peer_phymode;
+
+ arsta = container_of(wk, struct ath11k_sta, update_wk);
+ sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
+@@ -4233,6 +4234,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ arsta->changed = 0;
+
+ bw = arsta->bw;
++ bw_prev = arsta->bw_prev;
+ nss = arsta->nss;
+ smps = arsta->smps;
+
+@@ -4246,26 +4248,57 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ ath11k_mac_max_he_nss(he_mcs_mask)));
+
+ if (changed & IEEE80211_RC_BW_CHANGED) {
+- /* Send peer assoc command before set peer bandwidth param to
+- * avoid the mismatch between the peer phymode and the peer
+- * bandwidth.
+- */
+- ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true);
+-
+- peer_arg.is_assoc = false;
+- err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
+- if (err) {
+- ath11k_warn(ar->ab, "failed to send peer assoc for STA %pM vdev %i: %d\n",
+- sta->addr, arvif->vdev_id, err);
+- } else if (wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {
++ /* Get the peer phymode */
++ ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);
++ peer_phymode = peer_arg.peer_phymode;
++
++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
++ sta->addr, bw, peer_phymode);
++
++ if (bw > bw_prev) {
++ /* BW is upgraded. In this case we send WMI_PEER_PHYMODE
++ * followed by WMI_PEER_CHWIDTH
++ */
++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW upgrade for sta %pM new BW %d, old BW %d\n",
++ sta->addr, bw, bw_prev);
++
++ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++ WMI_PEER_PHYMODE, peer_phymode);
++
++ if (err) {
++ ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
++ sta->addr, peer_phymode, err);
++ goto err_rc_bw_changed;
++ }
++
+ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
+ WMI_PEER_CHWIDTH, bw);
++
+ if (err)
+ ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
+ sta->addr, bw, err);
+ } else {
+- ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",
+- sta->addr, arvif->vdev_id);
++ /* BW is downgraded. In this case we send WMI_PEER_CHWIDTH
++ * followed by WMI_PEER_PHYMODE
++ */
++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW downgrade for sta %pM new BW %d,old BW %d\n",
++ sta->addr, bw, bw_prev);
++
++ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++ WMI_PEER_CHWIDTH, bw);
++
++ if (err) {
++ ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
++ sta->addr, bw, err);
++ goto err_rc_bw_changed;
++ }
++
++ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++ WMI_PEER_PHYMODE, peer_phymode);
++
++ if (err)
++ ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
++ sta->addr, peer_phymode, err);
+ }
+ }
+
+@@ -4346,6 +4379,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ }
+ }
+
++err_rc_bw_changed:
+ mutex_unlock(&ar->conf_mutex);
+ }
+
+@@ -4499,6 +4533,34 @@ exit:
+ return ret;
+ }
+
++static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
++ struct ieee80211_sta *sta)
++{
++ u32 bw = WMI_PEER_CHWIDTH_20MHZ;
++
++ switch (sta->deflink.bandwidth) {
++ case IEEE80211_STA_RX_BW_20:
++ bw = WMI_PEER_CHWIDTH_20MHZ;
++ break;
++ case IEEE80211_STA_RX_BW_40:
++ bw = WMI_PEER_CHWIDTH_40MHZ;
++ break;
++ case IEEE80211_STA_RX_BW_80:
++ bw = WMI_PEER_CHWIDTH_80MHZ;
++ break;
++ case IEEE80211_STA_RX_BW_160:
++ bw = WMI_PEER_CHWIDTH_160MHZ;
++ break;
++ default:
++ ath11k_warn(ar->ab, "Invalid bandwidth %d for %pM\n",
++ sta->deflink.bandwidth, sta->addr);
++ bw = WMI_PEER_CHWIDTH_20MHZ;
++ break;
++ }
++
++ return bw;
++}
++
+ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+@@ -4583,6 +4645,12 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
+ if (ret)
+ ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
+ sta->addr);
++
++ spin_lock_bh(&ar->data_lock);
++ /* Set arsta bw and prev bw */
++ arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
++ arsta->bw_prev = arsta->bw;
++ spin_unlock_bh(&ar->data_lock);
+ } else if (old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTHORIZED) {
+ spin_lock_bh(&ar->ab->base_lock);
+@@ -4706,28 +4774,8 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
+ spin_lock_bh(&ar->data_lock);
+
+ if (changed & IEEE80211_RC_BW_CHANGED) {
+- bw = WMI_PEER_CHWIDTH_20MHZ;
+-
+- switch (sta->deflink.bandwidth) {
+- case IEEE80211_STA_RX_BW_20:
+- bw = WMI_PEER_CHWIDTH_20MHZ;
+- break;
+- case IEEE80211_STA_RX_BW_40:
+- bw = WMI_PEER_CHWIDTH_40MHZ;
+- break;
+- case IEEE80211_STA_RX_BW_80:
+- bw = WMI_PEER_CHWIDTH_80MHZ;
+- break;
+- case IEEE80211_STA_RX_BW_160:
+- bw = WMI_PEER_CHWIDTH_160MHZ;
+- break;
+- default:
+- ath11k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n",
+- sta->deflink.bandwidth, sta->addr);
+- bw = WMI_PEER_CHWIDTH_20MHZ;
+- break;
+- }
+-
++ bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
++ arsta->bw_prev = arsta->bw;
+ arsta->bw = bw;
+ }
+
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index e6ced8597e1d6..539134a6e9d98 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -3083,6 +3083,9 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),
+ .fn = ath11k_qmi_msg_fw_init_done_cb,
+ },
++
++ /* end of list */
++ {},
+ };
+
+ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index b658ea60dcf7d..ec9b7e954dfc8 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -7409,7 +7409,53 @@ static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff
+
+ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb)
+ {
+- ath11k_debugfs_fw_stats_process(ab, skb);
++ struct ath11k_fw_stats stats = {};
++ struct ath11k *ar;
++ int ret;
++
++ INIT_LIST_HEAD(&stats.pdevs);
++ INIT_LIST_HEAD(&stats.vdevs);
++ INIT_LIST_HEAD(&stats.bcn);
++
++ ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
++ if (ret) {
++ ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
++ goto free;
++ }
++
++ rcu_read_lock();
++ ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
++ if (!ar) {
++ rcu_read_unlock();
++ ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
++ stats.pdev_id, ret);
++ goto free;
++ }
++
++ spin_lock_bh(&ar->data_lock);
++
++ /* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
++ * debugfs fw stats. Therefore, processing it separately.
++ */
++ if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
++ list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs);
++ ar->fw_stats_done = true;
++ goto complete;
++ }
++
++ /* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
++ * are currently requested only via debugfs fw stats. Hence, processing these
++ * in debugfs context
++ */
++ ath11k_debugfs_fw_stats_process(ar, &stats);
++
++complete:
++ complete(&ar->fw_stats_complete);
++ rcu_read_unlock();
++ spin_unlock_bh(&ar->data_lock);
++
++free:
++ ath11k_fw_stats_free(&stats);
+ }
+
+ /* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index 4d9002a9d082c..1a2e0c7eeb023 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -708,14 +708,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+ struct hif_device_usb *hif_dev = rx_buf->hif_dev;
+ struct sk_buff *skb = rx_buf->skb;
+- struct sk_buff *nskb;
+ int ret;
+
+ if (!skb)
+ return;
+
+ if (!hif_dev)
+- goto free;
++ goto free_skb;
+
+ switch (urb->status) {
+ case 0:
+@@ -724,7 +723,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+- goto free;
++ goto free_skb;
+ default:
+ skb_reset_tail_pointer(skb);
+ skb_trim(skb, 0);
+@@ -735,25 +734,27 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ if (likely(urb->actual_length != 0)) {
+ skb_put(skb, urb->actual_length);
+
+- /* Process the command first */
++ /*
++ * Process the command first.
++ * skb is either freed here or passed to be
++ * managed to another callback function.
++ */
+ ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
+ skb->len, USB_REG_IN_PIPE);
+
+-
+- nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
+- if (!nskb) {
++ skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
++ if (!skb) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: REG_IN memory allocation failure\n");
+- urb->context = NULL;
+- return;
++ goto free_rx_buf;
+ }
+
+- rx_buf->skb = nskb;
++ rx_buf->skb = skb;
+
+ usb_fill_int_urb(urb, hif_dev->udev,
+ usb_rcvintpipe(hif_dev->udev,
+ USB_REG_IN_PIPE),
+- nskb->data, MAX_REG_IN_BUF_SIZE,
++ skb->data, MAX_REG_IN_BUF_SIZE,
+ ath9k_hif_usb_reg_in_cb, rx_buf, 1);
+ }
+
+@@ -762,12 +763,13 @@ resubmit:
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret) {
+ usb_unanchor_urb(urb);
+- goto free;
++ goto free_skb;
+ }
+
+ return;
+-free:
++free_skb:
+ kfree_skb(skb);
++free_rx_buf:
+ kfree(rx_buf);
+ urb->context = NULL;
+ }
+@@ -780,14 +782,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
+ spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+ list_for_each_entry_safe(tx_buf, tx_buf_tmp,
+ &hif_dev->tx.tx_buf, list) {
+- usb_get_urb(tx_buf->urb);
+- spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+- usb_kill_urb(tx_buf->urb);
+ list_del(&tx_buf->list);
+ usb_free_urb(tx_buf->urb);
+ kfree(tx_buf->buf);
+ kfree(tx_buf);
+- spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+ }
+ spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+
+@@ -1329,10 +1327,24 @@ static int send_eject_command(struct usb_interface *interface)
+ static int ath9k_hif_usb_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+ {
++ struct usb_endpoint_descriptor *bulk_in, *bulk_out, *int_in, *int_out;
+ struct usb_device *udev = interface_to_usbdev(interface);
++ struct usb_host_interface *alt;
+ struct hif_device_usb *hif_dev;
+ int ret = 0;
+
++ /* Verify the expected endpoints are present */
++ alt = interface->cur_altsetting;
++ if (usb_find_common_endpoints(alt, &bulk_in, &bulk_out, &int_in, &int_out) < 0 ||
++ usb_endpoint_num(bulk_in) != USB_WLAN_RX_PIPE ||
++ usb_endpoint_num(bulk_out) != USB_WLAN_TX_PIPE ||
++ usb_endpoint_num(int_in) != USB_REG_IN_PIPE ||
++ usb_endpoint_num(int_out) != USB_REG_OUT_PIPE) {
++ dev_err(&udev->dev,
++ "ath9k_htc: Device endpoint numbers are not the expected ones\n");
++ return -ENODEV;
++ }
++
+ if (id->driver_info == STORAGE_DEVICE)
+ return send_eject_command(interface);
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+index b8379e4034a4c..55d538978e9c1 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -737,6 +737,11 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
+ u32 i, j;
+ char end = '\0';
+
++ if (chiprev >= BITS_PER_TYPE(u32)) {
++ brcmf_err("Invalid chip revision %u\n", chiprev);
++ return NULL;
++ }
++
+ for (i = 0; i < table_size; i++) {
+ if (mapping_table[i].chipid == chip &&
+ mapping_table[i].revmask & BIT(chiprev))
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 97f0f13dfe505..5b1813c024113 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -626,7 +626,7 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
+ }
+
+ if (!brcmf_chip_set_active(devinfo->ci, resetintr))
+- return -EINVAL;
++ return -EIO;
+ return 0;
+ }
+
+@@ -1120,6 +1120,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
+ BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
+ }
++ if (max_flowrings > 256) {
++ brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
++ return -EIO;
++ }
+
+ if (devinfo->dma_idx_sz != 0) {
+ bufsz = (max_submissionrings + max_completionrings) *
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 8968809399c7a..2e4cd8096f037 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3412,6 +3412,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
+ /* Take arm out of reset */
+ if (!brcmf_chip_set_active(bus->ci, rstvec)) {
+ brcmf_err("error getting out of ARM core reset\n");
++ bcmerror = -EIO;
+ goto err;
+ }
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
+index 67122cfa22920..5409699c9a1fd 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
++++ b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
+@@ -446,9 +446,10 @@ void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info,
+ void iwl_mei_host_disassociated(void);
+
+ /**
+- * iwl_mei_device_down() - must be called when the device is down
++ * iwl_mei_device_state() - must be called when the device changes up/down state
++ * @up: true if the device is up, false otherwise.
+ */
+-void iwl_mei_device_down(void);
++void iwl_mei_device_state(bool up);
+
+ #else
+
+@@ -497,7 +498,7 @@ static inline void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_
+ static inline void iwl_mei_host_disassociated(void)
+ {}
+
+-static inline void iwl_mei_device_down(void)
++static inline void iwl_mei_device_state(bool up)
+ {}
+
+ #endif /* CONFIG_IWLMEI */
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+index 357f14626cf43..c0142093c7682 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+@@ -147,9 +147,13 @@ struct iwl_mei_filters {
+ * to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
+ * flow.
+ * @link_prot_state: true when we are in link protection PASSIVE
++ * @device_down: true if the device is down. Used to remember to send
++ * CSME_OWNERSHIP_CONFIRMED when the driver is already down.
+ * @csa_throttle_end_wk: used when &csa_throttled is true
+ * @data_q_lock: protects the access to the data queues which are
+ * accessed without the mutex.
++ * @netdev_work: used to defer registering and unregistering of the netdev to
++ * avoid taking the rtnl lock in the SAP messages handlers.
+ * @sap_seq_no: the sequence number for the SAP messages
+ * @seq_no: the sequence number for the SAP messages
+ * @dbgfs_dir: the debugfs dir entry
+@@ -167,8 +171,10 @@ struct iwl_mei {
+ bool csa_throttled;
+ bool csme_taking_ownership;
+ bool link_prot_state;
++ bool device_down;
+ struct delayed_work csa_throttle_end_wk;
+ spinlock_t data_q_lock;
++ struct work_struct netdev_work;
+
+ atomic_t sap_seq_no;
+ atomic_t seq_no;
+@@ -588,13 +594,38 @@ static rx_handler_result_t iwl_mei_rx_handler(struct sk_buff **pskb)
+ return res;
+ }
+
++static void iwl_mei_netdev_work(struct work_struct *wk)
++{
++ struct iwl_mei *mei =
++ container_of(wk, struct iwl_mei, netdev_work);
++ struct net_device *netdev;
++
++ /*
++ * First take rtnl and only then the mutex to avoid an ABBA
++ * with iwl_mei_set_netdev()
++ */
++ rtnl_lock();
++ mutex_lock(&iwl_mei_mutex);
++
++ netdev = rcu_dereference_protected(iwl_mei_cache.netdev,
++ lockdep_is_held(&iwl_mei_mutex));
++ if (netdev) {
++ if (mei->amt_enabled)
++ netdev_rx_handler_register(netdev, iwl_mei_rx_handler,
++ mei);
++ else
++ netdev_rx_handler_unregister(netdev);
++ }
++
++ mutex_unlock(&iwl_mei_mutex);
++ rtnl_unlock();
++}
++
+ static void
+ iwl_mei_handle_rx_start_ok(struct mei_cl_device *cldev,
+ const struct iwl_sap_me_msg_start_ok *rsp,
+ ssize_t len)
+ {
+- struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
+-
+ if (len != sizeof(*rsp)) {
+ dev_err(&cldev->dev,
+ "got invalid SAP_ME_MSG_START_OK from CSME firmware\n");
+@@ -613,13 +644,10 @@ iwl_mei_handle_rx_start_ok(struct mei_cl_device *cldev,
+
+ mutex_lock(&iwl_mei_mutex);
+ set_bit(IWL_MEI_STATUS_SAP_CONNECTED, &iwl_mei_status);
+- /* wifi driver has registered already */
+- if (iwl_mei_cache.ops) {
+- iwl_mei_send_sap_msg(mei->cldev,
+- SAP_MSG_NOTIF_WIFIDR_UP);
+- iwl_mei_cache.ops->sap_connected(iwl_mei_cache.priv);
+- }
+-
++ /*
++ * We'll receive AMT_STATE SAP message in a bit and
++ * that will continue the flow
++ */
+ mutex_unlock(&iwl_mei_mutex);
+ }
+
+@@ -712,6 +740,13 @@ static void iwl_mei_set_init_conf(struct iwl_mei *mei)
+ .val = cpu_to_le32(iwl_mei_cache.rf_kill),
+ };
+
++ /* wifi driver has registered already */
++ if (iwl_mei_cache.ops) {
++ iwl_mei_send_sap_msg(mei->cldev,
++ SAP_MSG_NOTIF_WIFIDR_UP);
++ iwl_mei_cache.ops->sap_connected(iwl_mei_cache.priv);
++ }
++
+ iwl_mei_send_sap_msg(mei->cldev, SAP_MSG_NOTIF_WHO_OWNS_NIC);
+
+ if (iwl_mei_cache.conn_info) {
+@@ -738,38 +773,23 @@ static void iwl_mei_handle_amt_state(struct mei_cl_device *cldev,
+ const struct iwl_sap_msg_dw *dw)
+ {
+ struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
+- struct net_device *netdev;
+
+- /*
+- * First take rtnl and only then the mutex to avoid an ABBA
+- * with iwl_mei_set_netdev()
+- */
+- rtnl_lock();
+ mutex_lock(&iwl_mei_mutex);
+
+- netdev = rcu_dereference_protected(iwl_mei_cache.netdev,
+- lockdep_is_held(&iwl_mei_mutex));
+-
+ if (mei->amt_enabled == !!le32_to_cpu(dw->val))
+ goto out;
+
+ mei->amt_enabled = dw->val;
+
+- if (mei->amt_enabled) {
+- if (netdev)
+- netdev_rx_handler_register(netdev, iwl_mei_rx_handler, mei);
+-
++ if (mei->amt_enabled)
+ iwl_mei_set_init_conf(mei);
+- } else {
+- if (iwl_mei_cache.ops)
+- iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false);
+- if (netdev)
+- netdev_rx_handler_unregister(netdev);
+- }
++ else if (iwl_mei_cache.ops)
++ iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false, false);
++
++ schedule_work(&mei->netdev_work);
+
+ out:
+ mutex_unlock(&iwl_mei_mutex);
+- rtnl_unlock();
+ }
+
+ static void iwl_mei_handle_nic_owner(struct mei_cl_device *cldev,
+@@ -798,14 +818,18 @@ static void iwl_mei_handle_csme_taking_ownership(struct mei_cl_device *cldev,
+
+ mei->got_ownership = false;
+
+- /*
+- * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi driver
+- * is finished taking the device down.
+- */
+- mei->csme_taking_ownership = true;
++ if (iwl_mei_cache.ops && !mei->device_down) {
++ /*
++ * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi
++ * driver is finished taking the device down.
++ */
++ mei->csme_taking_ownership = true;
+
+- if (iwl_mei_cache.ops)
+- iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true);
++ iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true, true);
++ } else {
++ iwl_mei_send_sap_msg(cldev,
++ SAP_MSG_NOTIF_CSME_OWNERSHIP_CONFIRMED);
++ }
+ }
+
+ static void iwl_mei_handle_nvm(struct mei_cl_device *cldev,
+@@ -1413,10 +1437,7 @@ void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info,
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
+- goto out;
+-
+- if (!mei->amt_enabled)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1445,7 +1466,7 @@ void iwl_mei_host_disassociated(void)
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1481,7 +1502,7 @@ void iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill)
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1510,7 +1531,7 @@ void iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address)
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1538,7 +1559,7 @@ void iwl_mei_set_country_code(u16 mcc)
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1564,7 +1585,7 @@ void iwl_mei_set_power_limit(const __le16 *power_limit)
+
+ mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+
+- if (!mei)
++ if (!mei && !mei->amt_enabled)
+ goto out;
+
+ memcpy(msg.sar_chain_info_table, power_limit, sizeof(msg.sar_chain_info_table));
+@@ -1616,7 +1637,7 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(iwl_mei_set_netdev);
+
+-void iwl_mei_device_down(void)
++void iwl_mei_device_state(bool up)
+ {
+ struct iwl_mei *mei;
+
+@@ -1630,7 +1651,9 @@ void iwl_mei_device_down(void)
+ if (!mei)
+ goto out;
+
+- if (!mei->csme_taking_ownership)
++ mei->device_down = !up;
++
++ if (up || !mei->csme_taking_ownership)
+ goto out;
+
+ iwl_mei_send_sap_msg(mei->cldev,
+@@ -1639,7 +1662,7 @@ void iwl_mei_device_down(void)
+ out:
+ mutex_unlock(&iwl_mei_mutex);
+ }
+-EXPORT_SYMBOL_GPL(iwl_mei_device_down);
++EXPORT_SYMBOL_GPL(iwl_mei_device_state);
+
+ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
+ {
+@@ -1669,9 +1692,10 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
+
+ /* we have already a SAP connection */
+ if (iwl_mei_is_connected()) {
+- iwl_mei_send_sap_msg(mei->cldev,
+- SAP_MSG_NOTIF_WIFIDR_UP);
+- ops->rfkill(priv, mei->link_prot_state);
++ if (mei->amt_enabled)
++ iwl_mei_send_sap_msg(mei->cldev,
++ SAP_MSG_NOTIF_WIFIDR_UP);
++ ops->rfkill(priv, mei->link_prot_state, false);
+ }
+ }
+ ret = 0;
+@@ -1818,9 +1842,11 @@ static int iwl_mei_probe(struct mei_cl_device *cldev,
+ iwl_mei_csa_throttle_end_wk);
+ init_waitqueue_head(&mei->get_ownership_wq);
+ spin_lock_init(&mei->data_q_lock);
++ INIT_WORK(&mei->netdev_work, iwl_mei_netdev_work);
+
+ mei_cldev_set_drvdata(cldev, mei);
+ mei->cldev = cldev;
++ mei->device_down = true;
+
+ do {
+ ret = iwl_mei_alloc_shared_mem(cldev);
+@@ -1921,29 +1947,32 @@ static void iwl_mei_remove(struct mei_cl_device *cldev)
+
+ mutex_lock(&iwl_mei_mutex);
+
+- /*
+- * Tell CSME that we are going down so that it won't access the
+- * memory anymore, make sure this message goes through immediately.
+- */
+- mei->csa_throttled = false;
+- iwl_mei_send_sap_msg(mei->cldev,
+- SAP_MSG_NOTIF_HOST_GOES_DOWN);
++ if (mei->amt_enabled) {
++ /*
++ * Tell CSME that we are going down so that it won't access the
++ * memory anymore, make sure this message goes through immediately.
++ */
++ mei->csa_throttled = false;
++ iwl_mei_send_sap_msg(mei->cldev,
++ SAP_MSG_NOTIF_HOST_GOES_DOWN);
+
+- for (i = 0; i < SEND_SAP_MAX_WAIT_ITERATION; i++) {
+- if (!iwl_mei_host_to_me_data_pending(mei))
+- break;
++ for (i = 0; i < SEND_SAP_MAX_WAIT_ITERATION; i++) {
++ if (!iwl_mei_host_to_me_data_pending(mei))
++ break;
+
+- msleep(5);
+- }
++ msleep(20);
++ }
+
+- /*
+- * If we couldn't make sure that CSME saw the HOST_GOES_DOWN message,
+- * it means that it will probably keep reading memory that we are going
+- * to unmap and free, expect IOMMU error messages.
+- */
+- if (i == SEND_SAP_MAX_WAIT_ITERATION)
+- dev_err(&mei->cldev->dev,
+- "Couldn't get ACK from CSME on HOST_GOES_DOWN message\n");
++ /*
++ * If we couldn't make sure that CSME saw the HOST_GOES_DOWN
++ * message, it means that it will probably keep reading memory
++ * that we are going to unmap and free, expect IOMMU error
++ * messages.
++ */
++ if (i == SEND_SAP_MAX_WAIT_ITERATION)
++ dev_err(&mei->cldev->dev,
++ "Couldn't get ACK from CSME on HOST_GOES_DOWN message\n");
++ }
+
+ mutex_unlock(&iwl_mei_mutex);
+
+@@ -1976,6 +2005,7 @@ static void iwl_mei_remove(struct mei_cl_device *cldev)
+ */
+ cancel_work_sync(&mei->send_csa_msg_wk);
+ cancel_delayed_work_sync(&mei->csa_throttle_end_wk);
++ cancel_work_sync(&mei->netdev_work);
+
+ /*
+ * If someone waits for the ownership, let him know that we are going
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/net.c b/drivers/net/wireless/intel/iwlwifi/mei/net.c
+index 3472167c83707..eac46d1a397a8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/net.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/net.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * Copyright (C) 2021 Intel Corporation
++ * Copyright (C) 2021-2022 Intel Corporation
+ */
+
+ #include <uapi/linux/if_ether.h>
+@@ -337,10 +337,14 @@ rx_handler_result_t iwl_mei_rx_filter(struct sk_buff *orig_skb,
+ if (!*pass_to_csme)
+ return RX_HANDLER_PASS;
+
+- if (ret == RX_HANDLER_PASS)
++ if (ret == RX_HANDLER_PASS) {
+ skb = skb_copy(orig_skb, GFP_ATOMIC);
+- else
++
++ if (!skb)
++ return RX_HANDLER_PASS;
++ } else {
+ skb = orig_skb;
++ }
+
+ /* CSME wants the MAC header as well, push it back */
+ skb_push(skb, skb->data - skb_mac_header(skb));
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index f041e77af059e..5de34edc51fe9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -1665,6 +1665,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
+ iwl_rfi_send_config_cmd(mvm, NULL);
+ }
+
++ iwl_mvm_mei_device_state(mvm, true);
++
+ IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
+ return 0;
+ error:
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index bf35e130c8765..cc71049bd9b39 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -2201,10 +2201,10 @@ static inline void iwl_mvm_mei_host_disassociated(struct iwl_mvm *mvm)
+ iwl_mei_host_disassociated();
+ }
+
+-static inline void iwl_mvm_mei_device_down(struct iwl_mvm *mvm)
++static inline void iwl_mvm_mei_device_state(struct iwl_mvm *mvm, bool up)
+ {
+ if (mvm->mei_registered)
+- iwl_mei_device_down();
++ iwl_mei_device_state(up);
+ }
+
+ static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm)
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index db43c8a83a319..3fec87fb6b7b6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -1370,7 +1370,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm)
+ iwl_trans_stop_device(mvm->trans);
+ iwl_free_fw_paging(&mvm->fwrt);
+ iwl_fw_dump_conf_clear(&mvm->fwrt);
+- iwl_mvm_mei_device_down(mvm);
++ iwl_mvm_mei_device_state(mvm, false);
+ }
+
+ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index f9e08b339e0c4..0dd35344e64a8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -1171,9 +1171,15 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
+ /* From now on, we cannot access info->control */
+ iwl_mvm_skb_prepare_status(skb, dev_cmd);
+
++ /*
++ * The IV is introduced by the HW for new tx api, and it is not present
++ * in the skb, hence, don't tell iwl_mvm_mei_tx_copy_to_csme about the
++ * IV for those devices.
++ */
+ if (ieee80211_is_data(fc))
+ iwl_mvm_mei_tx_copy_to_csme(mvm, skb,
+- info->control.hw_key ?
++ info->control.hw_key &&
++ !iwl_mvm_has_new_tx_api(mvm) ?
+ info->control.hw_key->iv_len : 0);
+
+ if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
+@@ -1206,6 +1212,7 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+ struct sk_buff_head mpdus_skbs;
+ unsigned int payload_len;
+ int ret;
++ struct sk_buff *orig_skb = skb;
+
+ if (WARN_ON_ONCE(!mvmsta))
+ return -1;
+@@ -1238,8 +1245,17 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+
+ ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+ if (ret) {
++ /* Free skbs created as part of TSO logic that have not yet been dequeued */
+ __skb_queue_purge(&mpdus_skbs);
+- return ret;
++ /* skb here is not necessarily same as skb that entered this method,
++ * so free it explicitly.
++ */
++ if (skb == orig_skb)
++ ieee80211_free_txskb(mvm->hw, skb);
++ else
++ kfree_skb(skb);
++ /* there was error, but we consumed skb one way or another, so return 0 */
++ return 0;
+ }
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 4da77d47b0a67..1f8da524a3056 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -1101,8 +1101,9 @@ static inline bool mt76_is_skb_pktid(u8 pktid)
+ static inline u8 mt76_tx_power_nss_delta(u8 nss)
+ {
+ static const u8 nss_delta[4] = { 0, 6, 9, 12 };
++ u8 idx = nss - 1;
+
+- return nss_delta[nss - 1];
++ return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0;
+ }
+
+ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+index 4b1a9811646fd..0bce0ce51be00 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+@@ -173,60 +173,50 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
+ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ struct mt7915_phy *phy)
+ {
+- u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
++ u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;
+ struct mt76_phy *mphy = phy->mt76;
+- bool ext_phy = phy != &dev->phy;
+
+ mt7915_eeprom_parse_band_config(phy);
+
+- /* read tx/rx mask from eeprom */
++ /* read tx/rx path from eeprom */
+ if (is_mt7915(&dev->mt76)) {
+- nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
+- eeprom[MT_EE_WIFI_CONF]);
++ path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
++ eeprom[MT_EE_WIFI_CONF]);
+ } else {
+- nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
+- eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
++ path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
++ eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
+ }
+
+- if (!nss || nss > 4)
+- nss = 4;
++ if (!path || path > 4)
++ path = 4;
+
+ /* read tx/rx stream */
+- nss_band = nss;
+-
++ nss = path;
+ if (dev->dbdc_support) {
+ if (is_mt7915(&dev->mt76)) {
+- nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
+- eeprom[MT_EE_WIFI_CONF + 3]);
++ path = min_t(u8, path, 2);
++ nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
++ eeprom[MT_EE_WIFI_CONF + 3]);
+ if (phy->band_idx)
+- nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
+- eeprom[MT_EE_WIFI_CONF + 3]);
++ nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
++ eeprom[MT_EE_WIFI_CONF + 3]);
+ } else {
+- nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
+- eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
++ nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
++ eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
+ }
+
+- nss_band_max = is_mt7986(&dev->mt76) ?
+- MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915;
+- } else {
+- nss_band_max = is_mt7986(&dev->mt76) ?
+- MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
++ if (!is_mt7986(&dev->mt76))
++ nss_max = 2;
+ }
+
+- if (!nss_band || nss_band > nss_band_max)
+- nss_band = nss_band_max;
+-
+- if (nss_band > nss) {
+- dev_warn(dev->mt76.dev,
+- "nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
+- nss, nss_band, phy->band_idx, ext_phy);
+- nss = nss_band;
+- }
++ if (!nss)
++ nss = nss_max;
++ nss = min_t(u8, min_t(u8, nss_max, nss), path);
+
+- mphy->chainmask = BIT(nss) - 1;
+- if (ext_phy)
++ mphy->chainmask = BIT(path) - 1;
++ if (phy->band_idx)
+ mphy->chainmask <<= dev->chainshift;
+- mphy->antenna_mask = BIT(nss_band) - 1;
++ mphy->antenna_mask = BIT(nss) - 1;
+ dev->chainmask |= mphy->chainmask;
+ dev->chainshift = hweight8(dev->mphy.chainmask);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+index 7578ac6d0be62..f3e56817d36e9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+@@ -58,11 +58,6 @@ enum mt7915_eeprom_field {
+ #define MT_EE_RATE_DELTA_SIGN BIT(6)
+ #define MT_EE_RATE_DELTA_EN BIT(7)
+
+-#define MT_EE_NSS_MAX_MA7915 4
+-#define MT_EE_NSS_MAX_DBDC_MA7915 2
+-#define MT_EE_NSS_MAX_MA7986 4
+-#define MT_EE_NSS_MAX_DBDC_MA7986 4
+-
+ enum mt7915_adie_sku {
+ MT7976_ONE_ADIE_DBDC = 0x7,
+ MT7975_ONE_ADIE = 0x8,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 49aa5c056063e..853d857b17579 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1146,7 +1146,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
+ u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
+- int offset;
++ int eifs_ofdm = 360, sifs = 10, offset;
+ bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
+
+ if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+@@ -1164,17 +1164,26 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
+ reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
+
++ if (!is_mt7915(&dev->mt76)) {
++ if (!a_band) {
++ mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
++ FIELD_PREP(MT_IFS_EIFS_CCK, 314));
++ eifs_ofdm = 78;
++ } else {
++ eifs_ofdm = 84;
++ }
++ } else if (a_band) {
++ sifs = 16;
++ }
++
+ mt76_wr(dev, MT_TMAC_CDTR(phy->band_idx), cck + reg_offset);
+ mt76_wr(dev, MT_TMAC_ODTR(phy->band_idx), ofdm + reg_offset);
+ mt76_wr(dev, MT_TMAC_ICR0(phy->band_idx),
+- FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
++ FIELD_PREP(MT_IFS_EIFS_OFDM, eifs_ofdm) |
+ FIELD_PREP(MT_IFS_RIFS, 2) |
+- FIELD_PREP(MT_IFS_SIFS, 10) |
++ FIELD_PREP(MT_IFS_SIFS, sifs) |
+ FIELD_PREP(MT_IFS_SLOT, phy->slottime));
+
+- mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
+- FIELD_PREP(MT_IFS_EIFS_CCK, 314));
+-
+ if (phy->slottime < 20 || a_band)
+ val = MT7915_CFEND_RATE_DEFAULT;
+ else
+@@ -1595,7 +1604,7 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)
+
+ aggr0 = phy->band_idx ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
+ if (is_mt7915(&dev->mt76)) {
+- for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
++ for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) {
+ val = mt76_rr(dev, MT_MIB_MB_SDR1(phy->band_idx, (i << 4)));
+ mib->ba_miss_cnt +=
+ FIELD_GET(MT_MIB_BA_MISS_COUNT_MASK, val);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+index d74f609775d3b..7a44a4f88ccb6 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+@@ -65,10 +65,17 @@ static void mt7915_put_hif2(struct mt7915_hif *hif)
+
+ static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)
+ {
++ struct pci_dev *tmp_pdev;
++
+ hif_idx++;
+- if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL) &&
+- !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL))
+- return NULL;
++
++ tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL);
++ if (!tmp_pdev) {
++ tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL);
++ if (!tmp_pdev)
++ return NULL;
++ }
++ pci_dev_put(tmp_pdev);
+
+ writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
+ pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index e8a7a58317822..5b0eba4cb4219 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -394,6 +394,27 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ if (v0 & MT_PRXV_HT_AD_CODE)
+ status->enc_flags |= RX_ENC_FLAG_LDPC;
+
++ ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband,
++ rxv, &mode);
++ if (ret < 0)
++ return ret;
++
++ if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
++ rxd += 6;
++ if ((u8 *)rxd - skb->data >= skb->len)
++ return -EINVAL;
++
++ rxv = rxd;
++ /* Monitor mode would use RCPI described in GROUP 5
++ * instead.
++ */
++ v1 = le32_to_cpu(rxv[0]);
++
++ rxd += 12;
++ if ((u8 *)rxd - skb->data >= skb->len)
++ return -EINVAL;
++ }
++
+ status->chains = mphy->antenna_mask;
+ status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, v1);
+ status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
+@@ -408,17 +429,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ status->signal = max(status->signal,
+ status->chain_signal[i]);
+ }
+-
+- ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband,
+- rxv, &mode);
+- if (ret < 0)
+- return ret;
+-
+- if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
+- rxd += 18;
+- if ((u8 *)rxd - skb->data >= skb->len)
+- return -EINVAL;
+- }
+ }
+
+ amsdu_info = FIELD_GET(MT_RXD4_NORMAL_PAYLOAD_FORMAT, rxd4);
+@@ -842,7 +852,7 @@ void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
+ mib->tx_amsdu_cnt += val;
+ }
+
+- for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
++ for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) {
+ u32 val2;
+
+ val = mt76_rr(dev, MT_TX_AGG_CNT(0, i));
+diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
+index 6b8964c19f50d..446429f4d9442 100644
+--- a/drivers/net/wireless/mediatek/mt76/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/usb.c
+@@ -761,6 +761,9 @@ static void mt76u_status_worker(struct mt76_worker *w)
+ struct mt76_queue *q;
+ int i;
+
++ if (!test_bit(MT76_STATE_RUNNING, &dev->phy.state))
++ return;
++
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ q = dev->phy.q_tx[i];
+ if (!q)
+@@ -780,11 +783,11 @@ static void mt76u_status_worker(struct mt76_worker *w)
+ wake_up(&dev->tx_wait);
+
+ mt76_worker_schedule(&dev->tx_worker);
+-
+- if (dev->drv->tx_status_data &&
+- !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
+- queue_work(dev->wq, &dev->usb.stat_work);
+ }
++
++ if (dev->drv->tx_status_data &&
++ !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
++ queue_work(dev->wq, &dev->usb.stat_work);
+ }
+
+ static void mt76u_tx_status_data(struct work_struct *work)
+diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c
+index 39e54b3787d6a..76d0a778636a4 100644
+--- a/drivers/net/wireless/purelifi/plfxlc/usb.c
++++ b/drivers/net/wireless/purelifi/plfxlc/usb.c
+@@ -247,6 +247,7 @@ error:
+ for (i = 0; i < RX_URBS_COUNT; i++)
+ free_rx_urb(urbs[i]);
+ }
++ kfree(urbs);
+ return r;
+ }
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index 782b089a2e1ba..1ba66b8f70c95 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -1190,7 +1190,7 @@ struct rtl8723bu_c2h {
+ u8 bw;
+ } __packed ra_report;
+ };
+-};
++} __packed;
+
+ struct rtl8xxxu_fileops;
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 08f9d17dce12e..955fcf97b9dc1 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1608,18 +1608,18 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ {
+ struct device *dev = &priv->udev->dev;
+ struct ieee80211_hw *hw = priv->hw;
+- u32 val32, bonding;
++ u32 val32, bonding, sys_cfg;
+ u16 val16;
+
+- val32 = rtl8xxxu_read32(priv, REG_SYS_CFG);
+- priv->chip_cut = (val32 & SYS_CFG_CHIP_VERSION_MASK) >>
++ sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG);
++ priv->chip_cut = (sys_cfg & SYS_CFG_CHIP_VERSION_MASK) >>
+ SYS_CFG_CHIP_VERSION_SHIFT;
+- if (val32 & SYS_CFG_TRP_VAUX_EN) {
++ if (sys_cfg & SYS_CFG_TRP_VAUX_EN) {
+ dev_info(dev, "Unsupported test chip\n");
+ return -ENOTSUPP;
+ }
+
+- if (val32 & SYS_CFG_BT_FUNC) {
++ if (sys_cfg & SYS_CFG_BT_FUNC) {
+ if (priv->chip_cut >= 3) {
+ sprintf(priv->chip_name, "8723BU");
+ priv->rtl_chip = RTL8723B;
+@@ -1641,7 +1641,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ if (val32 & MULTI_GPS_FUNC_EN)
+ priv->has_gps = 1;
+ priv->is_multi_func = 1;
+- } else if (val32 & SYS_CFG_TYPE_ID) {
++ } else if (sys_cfg & SYS_CFG_TYPE_ID) {
+ bonding = rtl8xxxu_read32(priv, REG_HPON_FSM);
+ bonding &= HPON_FSM_BONDING_MASK;
+ if (priv->fops->tx_desc_size ==
+@@ -1692,7 +1692,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ case RTL8188E:
+ case RTL8192E:
+ case RTL8723B:
+- switch (val32 & SYS_CFG_VENDOR_EXT_MASK) {
++ switch (sys_cfg & SYS_CFG_VENDOR_EXT_MASK) {
+ case SYS_CFG_VENDOR_ID_TSMC:
+ sprintf(priv->chip_vendor, "TSMC");
+ break;
+@@ -1709,7 +1709,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ }
+ break;
+ default:
+- if (val32 & SYS_CFG_VENDOR_ID) {
++ if (sys_cfg & SYS_CFG_VENDOR_ID) {
+ sprintf(priv->chip_vendor, "UMC");
+ priv->vendor_umc = 1;
+ } else {
+@@ -4654,7 +4654,6 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ if (sta->deflink.ht_cap.cap &
+ (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
+ sgi = 1;
+- rcu_read_unlock();
+
+ highest_rate = fls(ramask) - 1;
+ if (highest_rate < DESC_RATE_MCS0) {
+@@ -4679,6 +4678,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ else
+ rarpt->txrate.bw = RATE_INFO_BW_20;
+ }
++ rcu_read_unlock();
+ bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ rarpt->bit_rate = bit_rate;
+ rarpt->desc_rate = highest_rate;
+@@ -5575,7 +5575,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ rarpt->txrate.flags = 0;
+ rate = c2h->ra_report.rate;
+ sgi = c2h->ra_report.sgi;
+- bw = c2h->ra_report.bw;
+
+ if (rate < DESC_RATE_MCS0) {
+ rarpt->txrate.legacy =
+@@ -5592,8 +5591,13 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ RATE_INFO_FLAGS_SHORT_GI;
+ }
+
+- if (bw == RATE_INFO_BW_20)
+- rarpt->txrate.bw |= RATE_INFO_BW_20;
++ if (skb->len >= offsetofend(typeof(*c2h), ra_report.bw)) {
++ if (c2h->ra_report.bw == RTL8XXXU_CHANNEL_WIDTH_40)
++ bw = RATE_INFO_BW_40;
++ else
++ bw = RATE_INFO_BW_20;
++ rarpt->txrate.bw = bw;
++ }
+ }
+ bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ rarpt->bit_rate = bit_rate;
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index 8b338e5ce364e..732015228bd30 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -2500,7 +2500,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
+ }
+
+ /* update cam aid mac_id net_type */
+- rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to send h2c cam\n");
+ return ret;
+diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
+index 93124b815825f..1afc14531194a 100644
+--- a/drivers/net/wireless/realtek/rtw89/mac.c
++++ b/drivers/net/wireless/realtek/rtw89/mac.c
+@@ -1387,10 +1387,8 @@ static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg
+ #define INVALID_QT_WCPU U16_MAX
+ #define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \
+ do { \
+- val = ((_min_x) & \
+- B_AX_ ## _module ## _MIN_SIZE_MASK) | \
+- (((_max_x) << 16) & \
+- B_AX_ ## _module ## _MAX_SIZE_MASK); \
++ val = u32_encode_bits(_min_x, B_AX_ ## _module ## _MIN_SIZE_MASK) | \
++ u32_encode_bits(_max_x, B_AX_ ## _module ## _MAX_SIZE_MASK); \
+ rtw89_write32(rtwdev, \
+ R_AX_ ## _module ## _QTA ## _idx ## _CFG, \
+ val); \
+diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
+index 1532c0a6bbc44..2925179f508c9 100644
+--- a/drivers/net/wireless/realtek/rtw89/phy.c
++++ b/drivers/net/wireless/realtek/rtw89/phy.c
+@@ -3045,7 +3045,7 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
+
+ static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page)
+ {
+- if (*ie_page > RTW89_PHYSTS_BITMAP_NUM ||
++ if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM ||
+ *ie_page == RTW89_RSVD_9)
+ return false;
+ else if (*ie_page > RTW89_RSVD_9)
+diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
+index 0f3a80f66b61c..ead4d4e043280 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_core.c
++++ b/drivers/net/wireless/rsi/rsi_91x_core.c
+@@ -466,7 +466,9 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
+ tid, 0);
+ }
+ }
+- if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++
++ if (IEEE80211_SKB_CB(skb)->control.flags &
++ IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
+ q_num = MGMT_SOFT_Q;
+ skb->priority = q_num;
+ }
+diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
+index c61f83a7333b6..c7460fbba0142 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
+@@ -162,12 +162,16 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+ u8 header_size;
+ u8 vap_id = 0;
+ u8 dword_align_bytes;
++ bool tx_eapol;
+ u16 seq_num;
+
+ info = IEEE80211_SKB_CB(skb);
+ vif = info->control.vif;
+ tx_params = (struct skb_info *)info->driver_data;
+
++ tx_eapol = IEEE80211_SKB_CB(skb)->control.flags &
++ IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
++
+ header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
+ if (header_size > skb_headroom(skb)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
+@@ -231,7 +235,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+ }
+ }
+
+- if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++ if (tx_eapol) {
+ rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
+
+ data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
+index d9f6367b9993d..f0cac19005527 100644
+--- a/drivers/nfc/pn533/pn533.c
++++ b/drivers/nfc/pn533/pn533.c
+@@ -1295,6 +1295,8 @@ static int pn533_poll_dep_complete(struct pn533 *dev, void *arg,
+ if (IS_ERR(resp))
+ return PTR_ERR(resp);
+
++ memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+ rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
+
+ rc = rsp->status & PN533_CMD_RET_MASK;
+@@ -1926,6 +1928,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
+
+ dev_dbg(dev->dev, "Creating new target\n");
+
++ memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+ nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+ nfc_target.nfcid1_len = 10;
+ memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index aca50bb937506..3582a28a1dcec 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3043,7 +3043,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
+
+ id = kzalloc(sizeof(*id), GFP_KERNEL);
+ if (!id)
+- return 0;
++ return -ENOMEM;
+
+ c.identify.opcode = nvme_admin_identify;
+ c.identify.cns = NVME_ID_CNS_CS_CTRL;
+@@ -3739,13 +3739,17 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev,
+ memcpy(dhchap_secret, buf, count);
+ nvme_auth_stop(ctrl);
+ if (strcmp(dhchap_secret, opts->dhchap_secret)) {
++ struct nvme_dhchap_key *key, *host_key;
+ int ret;
+
+- ret = nvme_auth_generate_key(dhchap_secret, &ctrl->host_key);
++ ret = nvme_auth_generate_key(dhchap_secret, &key);
+ if (ret)
+ return ret;
+ kfree(opts->dhchap_secret);
+ opts->dhchap_secret = dhchap_secret;
++ host_key = ctrl->host_key;
++ ctrl->host_key = key;
++ nvme_auth_free_key(host_key);
+ /* Key has changed; re-authentication with new key */
+ nvme_auth_reset(ctrl);
+ }
+@@ -3789,13 +3793,17 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev,
+ memcpy(dhchap_secret, buf, count);
+ nvme_auth_stop(ctrl);
+ if (strcmp(dhchap_secret, opts->dhchap_ctrl_secret)) {
++ struct nvme_dhchap_key *key, *ctrl_key;
+ int ret;
+
+- ret = nvme_auth_generate_key(dhchap_secret, &ctrl->ctrl_key);
++ ret = nvme_auth_generate_key(dhchap_secret, &key);
+ if (ret)
+ return ret;
+ kfree(opts->dhchap_ctrl_secret);
+ opts->dhchap_ctrl_secret = dhchap_secret;
++ ctrl_key = ctrl->ctrl_key;
++ ctrl->ctrl_key = key;
++ nvme_auth_free_key(ctrl_key);
+ /* Key has changed; re-authentication with new key */
+ nvme_auth_reset(ctrl);
+ }
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index aecb5853f8da4..683b75a992b3d 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -15,6 +15,7 @@
+
+ #include "nvmet.h"
+
++struct kmem_cache *nvmet_bvec_cache;
+ struct workqueue_struct *buffered_io_wq;
+ struct workqueue_struct *zbd_wq;
+ static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
+@@ -1631,26 +1632,28 @@ void nvmet_subsys_put(struct nvmet_subsys *subsys)
+
+ static int __init nvmet_init(void)
+ {
+- int error;
++ int error = -ENOMEM;
+
+ nvmet_ana_group_enabled[NVMET_DEFAULT_ANA_GRPID] = 1;
+
++ nvmet_bvec_cache = kmem_cache_create("nvmet-bvec",
++ NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec), 0,
++ SLAB_HWCACHE_ALIGN, NULL);
++ if (!nvmet_bvec_cache)
++ return -ENOMEM;
++
+ zbd_wq = alloc_workqueue("nvmet-zbd-wq", WQ_MEM_RECLAIM, 0);
+ if (!zbd_wq)
+- return -ENOMEM;
++ goto out_destroy_bvec_cache;
+
+ buffered_io_wq = alloc_workqueue("nvmet-buffered-io-wq",
+ WQ_MEM_RECLAIM, 0);
+- if (!buffered_io_wq) {
+- error = -ENOMEM;
++ if (!buffered_io_wq)
+ goto out_free_zbd_work_queue;
+- }
+
+ nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
+- if (!nvmet_wq) {
+- error = -ENOMEM;
++ if (!nvmet_wq)
+ goto out_free_buffered_work_queue;
+- }
+
+ error = nvmet_init_discovery();
+ if (error)
+@@ -1669,6 +1672,8 @@ out_free_buffered_work_queue:
+ destroy_workqueue(buffered_io_wq);
+ out_free_zbd_work_queue:
+ destroy_workqueue(zbd_wq);
++out_destroy_bvec_cache:
++ kmem_cache_destroy(nvmet_bvec_cache);
+ return error;
+ }
+
+@@ -1680,6 +1685,7 @@ static void __exit nvmet_exit(void)
+ destroy_workqueue(nvmet_wq);
+ destroy_workqueue(buffered_io_wq);
+ destroy_workqueue(zbd_wq);
++ kmem_cache_destroy(nvmet_bvec_cache);
+
+ BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_entry) != 1024);
+ BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_hdr) != 1024);
+diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
+index 64b47e2a46330..e55ec6fefd7f4 100644
+--- a/drivers/nvme/target/io-cmd-file.c
++++ b/drivers/nvme/target/io-cmd-file.c
+@@ -11,7 +11,6 @@
+ #include <linux/fs.h>
+ #include "nvmet.h"
+
+-#define NVMET_MAX_MPOOL_BVEC 16
+ #define NVMET_MIN_MPOOL_OBJ 16
+
+ void nvmet_file_ns_revalidate(struct nvmet_ns *ns)
+@@ -26,8 +25,6 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
+ flush_workqueue(buffered_io_wq);
+ mempool_destroy(ns->bvec_pool);
+ ns->bvec_pool = NULL;
+- kmem_cache_destroy(ns->bvec_cache);
+- ns->bvec_cache = NULL;
+ fput(ns->file);
+ ns->file = NULL;
+ }
+@@ -59,16 +56,8 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
+ ns->blksize_shift = min_t(u8,
+ file_inode(ns->file)->i_blkbits, 12);
+
+- ns->bvec_cache = kmem_cache_create("nvmet-bvec",
+- NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec),
+- 0, SLAB_HWCACHE_ALIGN, NULL);
+- if (!ns->bvec_cache) {
+- ret = -ENOMEM;
+- goto err;
+- }
+-
+ ns->bvec_pool = mempool_create(NVMET_MIN_MPOOL_OBJ, mempool_alloc_slab,
+- mempool_free_slab, ns->bvec_cache);
++ mempool_free_slab, nvmet_bvec_cache);
+
+ if (!ns->bvec_pool) {
+ ret = -ENOMEM;
+@@ -77,9 +66,10 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
+
+ return ret;
+ err:
++ fput(ns->file);
++ ns->file = NULL;
+ ns->size = 0;
+ ns->blksize_shift = 0;
+- nvmet_file_ns_disable(ns);
+ return ret;
+ }
+
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index dfe3894205aa7..bda1c1f71f394 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -77,7 +77,6 @@ struct nvmet_ns {
+
+ struct completion disable_done;
+ mempool_t *bvec_pool;
+- struct kmem_cache *bvec_cache;
+
+ int use_p2pmem;
+ struct pci_dev *p2p_dev;
+@@ -393,6 +392,8 @@ struct nvmet_req {
+ u64 error_slba;
+ };
+
++#define NVMET_MAX_MPOOL_BVEC 16
++extern struct kmem_cache *nvmet_bvec_cache;
+ extern struct workqueue_struct *buffered_io_wq;
+ extern struct workqueue_struct *zbd_wq;
+ extern struct workqueue_struct *nvmet_wq;
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index bd8ff4df723da..ed4e6c144a681 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -545,7 +545,7 @@ static int find_dup_cset_node_entry(struct overlay_changeset *ovcs,
+
+ fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+ fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+- node_path_match = !strcmp(fn_1, fn_2);
++ node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+ kfree(fn_1);
+ kfree(fn_2);
+ if (node_path_match) {
+@@ -580,7 +580,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
+
+ fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+ fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+- node_path_match = !strcmp(fn_1, fn_2);
++ node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+ kfree(fn_1);
+ kfree(fn_2);
+ if (node_path_match &&
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 6e5debdbc55b9..6ffe95d68ae72 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -942,12 +942,6 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
+ }
+ }
+
+- ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+- if (ret < 0) {
+- dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
+- goto err_phy_off;
+- }
+-
+ if (imx6_pcie->phy) {
+ ret = phy_init(imx6_pcie->phy);
+ if (ret) {
+@@ -955,6 +949,13 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
+ goto err_phy_off;
+ }
+ }
++
++ ret = imx6_pcie_deassert_core_reset(imx6_pcie);
++ if (ret < 0) {
++ dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
++ goto err_phy_off;
++ }
++
+ imx6_setup_phy_mpll(imx6_pcie);
+
+ return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index c6725c519a479..9e4d96e5a3f5a 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -641,7 +641,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
+ if (pci->n_fts[1]) {
+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ val &= ~PORT_LOGIC_N_FTS_MASK;
+- val |= pci->n_fts[pci->link_gen - 1];
++ val |= pci->n_fts[1];
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+ }
+
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index e06e9f4fc50f7..769eedeb8802a 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -719,6 +719,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+ resource_size_t offset[2] = {0};
+ resource_size_t membar2_offset = 0x2000;
+ struct pci_bus *child;
++ struct pci_dev *dev;
+ int ret;
+
+ /*
+@@ -859,8 +860,25 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+
+ pci_scan_child_bus(vmd->bus);
+ vmd_domain_reset(vmd);
+- list_for_each_entry(child, &vmd->bus->children, node)
+- pci_reset_bus(child->self);
++
++ /* When Intel VMD is enabled, the OS does not discover the Root Ports
++ * owned by Intel VMD within the MMCFG space. pci_reset_bus() applies
++ * a reset to the parent of the PCI device supplied as argument. This
++ * is why we pass a child device, so the reset can be triggered at
++ * the Intel bridge level and propagated to all the children in the
++ * hierarchy.
++ */
++ list_for_each_entry(child, &vmd->bus->children, node) {
++ if (!list_empty(&child->devices)) {
++ dev = list_first_entry(&child->devices,
++ struct pci_dev, bus_list);
++ if (pci_reset_bus(dev))
++ pci_warn(dev, "can't reset device: %d\n", ret);
++
++ break;
++ }
++ }
++
+ pci_assign_unassigned_bus_resources(vmd->bus);
+
+ /*
+@@ -980,6 +998,11 @@ static int vmd_resume(struct device *dev)
+ struct vmd_dev *vmd = pci_get_drvdata(pdev);
+ int err, i;
+
++ if (vmd->irq_domain)
++ vmd_set_msi_remapping(vmd, true);
++ else
++ vmd_set_msi_remapping(vmd, false);
++
+ for (i = 0; i < vmd->msix_count; i++) {
+ err = devm_request_irq(dev, vmd->irqs[i].virq,
+ vmd_irq, IRQF_NO_THREAD,
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 36b1801a061b7..55283d2379a6a 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -979,7 +979,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+ if (ret)
+ epf_test->dma_supported = false;
+
+- if (linkup_notifier) {
++ if (linkup_notifier || core_init_notifier) {
+ epf->nb.notifier_call = pci_epf_test_notifier;
+ pci_epc_register_notifier(epc, &epf->nb);
+ } else {
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index 0ea85e1d292ec..fba0179939b8f 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -557,7 +557,7 @@ static int epf_ntb_db_bar_init(struct epf_ntb *ntb)
+ return ret;
+
+ err_alloc_peer_mem:
+- pci_epc_mem_free_addr(ntb->epf->epc, epf_bar->phys_addr, mw_addr, epf_bar->size);
++ pci_epf_free_space(ntb->epf, mw_addr, barno, 0);
+ return -1;
+ }
+
+diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
+index 12ecd0aaa28d6..0050e8f6814ed 100644
+--- a/drivers/pci/irq.c
++++ b/drivers/pci/irq.c
+@@ -44,6 +44,8 @@ int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
+ va_start(ap, fmt);
+ devname = kvasprintf(GFP_KERNEL, fmt, ap);
+ va_end(ap);
++ if (!devname)
++ return -ENOMEM;
+
+ ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
+ irqflags, devname, dev_id);
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index c5286b027f00d..bdcad5e0f057f 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -1890,9 +1890,6 @@ int pci_setup_device(struct pci_dev *dev)
+
+ dev->broken_intx_masking = pci_intx_mask_broken(dev);
+
+- /* Clear errors left from system firmware */
+- pci_write_config_word(dev, PCI_STATUS, 0xffff);
+-
+ switch (dev->hdr_type) { /* header type */
+ case PCI_HEADER_TYPE_NORMAL: /* standard header */
+ if (class == PCI_CLASS_BRIDGE_PCI)
+diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
+index 280a6ae3e27cf..54aa4658fb36e 100644
+--- a/drivers/perf/arm_dmc620_pmu.c
++++ b/drivers/perf/arm_dmc620_pmu.c
+@@ -725,6 +725,8 @@ static struct platform_driver dmc620_pmu_driver = {
+
+ static int __init dmc620_pmu_init(void)
+ {
++ int ret;
++
+ cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ DMC620_DRVNAME,
+ NULL,
+@@ -732,7 +734,11 @@ static int __init dmc620_pmu_init(void)
+ if (cpuhp_state_num < 0)
+ return cpuhp_state_num;
+
+- return platform_driver_register(&dmc620_pmu_driver);
++ ret = platform_driver_register(&dmc620_pmu_driver);
++ if (ret)
++ cpuhp_remove_multi_state(cpuhp_state_num);
++
++ return ret;
+ }
+
+ static void __exit dmc620_pmu_exit(void)
+diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
+index a36698a90d2f2..54b8ba032c787 100644
+--- a/drivers/perf/arm_dsu_pmu.c
++++ b/drivers/perf/arm_dsu_pmu.c
+@@ -858,7 +858,11 @@ static int __init dsu_pmu_init(void)
+ if (ret < 0)
+ return ret;
+ dsu_pmu_cpuhp_state = ret;
+- return platform_driver_register(&dsu_pmu_driver);
++ ret = platform_driver_register(&dsu_pmu_driver);
++ if (ret)
++ cpuhp_remove_multi_state(dsu_pmu_cpuhp_state);
++
++ return ret;
+ }
+
+ static void __exit dsu_pmu_exit(void)
+diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
+index 00d4c45a8017d..25a269d431e45 100644
+--- a/drivers/perf/arm_smmuv3_pmu.c
++++ b/drivers/perf/arm_smmuv3_pmu.c
+@@ -959,6 +959,8 @@ static struct platform_driver smmu_pmu_driver = {
+
+ static int __init arm_smmu_pmu_init(void)
+ {
++ int ret;
++
+ cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ "perf/arm/pmcg:online",
+ NULL,
+@@ -966,7 +968,11 @@ static int __init arm_smmu_pmu_init(void)
+ if (cpuhp_state_num < 0)
+ return cpuhp_state_num;
+
+- return platform_driver_register(&smmu_pmu_driver);
++ ret = platform_driver_register(&smmu_pmu_driver);
++ if (ret)
++ cpuhp_remove_multi_state(cpuhp_state_num);
++
++ return ret;
+ }
+ module_init(arm_smmu_pmu_init);
+
+diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+index 21771708597db..071e63d9a9ac6 100644
+--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
++++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+@@ -693,10 +693,10 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
+ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
+ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
+ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
+- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005),
+- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005),
+- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004),
+- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004),
++ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
++ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
++ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
++ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
+ NULL
+ };
+
+diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
+index 69c3050a4348b..a1166afb37024 100644
+--- a/drivers/perf/marvell_cn10k_tad_pmu.c
++++ b/drivers/perf/marvell_cn10k_tad_pmu.c
+@@ -408,7 +408,11 @@ static int __init tad_pmu_init(void)
+ if (ret < 0)
+ return ret;
+ tad_pmu_cpuhp_state = ret;
+- return platform_driver_register(&tad_pmu_driver);
++ ret = platform_driver_register(&tad_pmu_driver);
++ if (ret)
++ cpuhp_remove_multi_state(tad_pmu_cpuhp_state);
++
++ return ret;
+ }
+
+ static void __exit tad_pmu_exit(void)
+diff --git a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+index d2524b70ea161..3b374b37b965b 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -331,13 +331,12 @@ static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
+
+ pr_debug("%s\n", __func__);
+
+- if (!params->wake_enabled) {
+- USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
+-
++ if (params->wake_enabled) {
+ /* Switch to using slower clock during suspend to save power */
+ USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
+- } else {
+ usb_wake_enable_7216(params, true);
++ } else {
++ USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
+ }
+ }
+
+@@ -425,7 +424,6 @@ void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
+
+ params->family_name = "7216";
+ params->ops = &bcm7216_ops;
+- params->suspend_with_clocks = true;
+ }
+
+ void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
+@@ -435,5 +433,4 @@ void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
+
+ params->family_name = "7211";
+ params->ops = &bcm7211b0_ops;
+- params->suspend_with_clocks = true;
+ }
+diff --git a/drivers/phy/broadcom/phy-brcm-usb-init.h b/drivers/phy/broadcom/phy-brcm-usb-init.h
+index 1ccb5ddab865c..3236e94988428 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -61,7 +61,6 @@ struct brcm_usb_init_params {
+ const struct brcm_usb_init_ops *ops;
+ struct regmap *syscon_piarbctl;
+ bool wake_enabled;
+- bool suspend_with_clocks;
+ };
+
+ void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params);
+diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
+index 2cb3779fcdf82..2bfd78e2d8fd6 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -102,9 +102,9 @@ static int brcm_pm_notifier(struct notifier_block *notifier,
+
+ static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
+ {
+- struct phy *gphy = dev_id;
++ struct device *dev = dev_id;
+
+- pm_wakeup_event(&gphy->dev, 0);
++ pm_wakeup_event(dev, 0);
+
+ return IRQ_HANDLED;
+ }
+@@ -451,7 +451,7 @@ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+ if (priv->wake_irq >= 0) {
+ err = devm_request_irq(dev, priv->wake_irq,
+ brcm_usb_phy_wake_isr, 0,
+- dev_name(dev), gphy);
++ dev_name(dev), dev);
+ if (err < 0)
+ return err;
+ device_set_wakeup_capable(dev, 1);
+@@ -598,7 +598,7 @@ static int brcm_usb_phy_suspend(struct device *dev)
+ * and newer XHCI->2.0-clks/3.0-clks.
+ */
+
+- if (!priv->ini.suspend_with_clocks) {
++ if (!priv->ini.wake_enabled) {
+ if (priv->phys[BRCM_USB_PHY_3_0].inited)
+ clk_disable_unprepare(priv->usb_30_clk);
+ if (priv->phys[BRCM_USB_PHY_2_0].inited ||
+@@ -615,8 +615,10 @@ static int brcm_usb_phy_resume(struct device *dev)
+ {
+ struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+
+- clk_prepare_enable(priv->usb_20_clk);
+- clk_prepare_enable(priv->usb_30_clk);
++ if (!priv->ini.wake_enabled) {
++ clk_prepare_enable(priv->usb_20_clk);
++ clk_prepare_enable(priv->usb_30_clk);
++ }
+ brcm_usb_init_ipp(&priv->ini);
+
+ /*
+diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+index 67712c77d806f..d641b345afa35 100644
+--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
++++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+@@ -826,6 +826,9 @@ mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane)
+ if (ret)
+ return ret;
+
++ /* COMPHY register reset (cleared automatically) */
++ comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST);
++
+ /*
+ * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The
+ * register belong to UTMI module, so it is set in UTMI phy driver.
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+index 2d65e1f56bfc3..51dc4f2de1063 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+@@ -1329,10 +1329,10 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
+ };
+
+ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
+- QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
+- QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
+- QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
+- QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++ QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG4, 0x16),
++ QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG5, 0x22),
++ QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_G3S2_PRE_GAIN, 0x2e),
++ QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_RX_SIGDET_LVL, 0x99),
+ };
+
+ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
+@@ -1564,6 +1564,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
+
+ .start_ctrl = SERDES_START | PCS_START,
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
++ .phy_status = PHYSTATUS,
+
+ .has_pwrdn_delay = true,
+ .pwrdn_delay_min = 995, /* us */
+@@ -2077,12 +2078,6 @@ static int qcom_qmp_phy_pcie_power_on(struct phy *phy)
+ qcom_qmp_phy_pcie_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
+ cfg->pcs_misc_tbl_num_sec);
+
+- /*
+- * Pull out PHY from POWER DOWN state.
+- * This is active low enable signal to power-down PHY.
+- */
+- qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
+-
+ if (cfg->has_pwrdn_delay)
+ usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h
+new file mode 100644
+index 0000000000000..9a5a20daf62cd
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h
+@@ -0,0 +1,14 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (c) 2022, Linaro Ltd.
++ */
++
++#ifndef QCOM_PHY_QMP_PCS_V5_20_H_
++#define QCOM_PHY_QMP_PCS_V5_20_H_
++
++#define QPHY_V5_20_PCS_G3S2_PRE_GAIN 0x170
++#define QPHY_V5_20_PCS_RX_SIGDET_LVL 0x188
++#define QPHY_V5_20_PCS_EQ_CONFIG4 0x1e0
++#define QPHY_V5_20_PCS_EQ_CONFIG5 0x1e4
++
++#endif
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
+index b139c8af5e8b1..1a0c6c3026e37 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
+@@ -37,6 +37,7 @@
+ #include "phy-qcom-qmp-pcs-pcie-v4_20.h"
+
+ #include "phy-qcom-qmp-pcs-v5.h"
++#include "phy-qcom-qmp-pcs-v5_20.h"
+ #include "phy-qcom-qmp-pcs-pcie-v5.h"
+ #include "phy-qcom-qmp-pcs-usb-v5.h"
+ #include "phy-qcom-qmp-pcs-ufs-v5.h"
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+index f26869f1a367b..5cb255455a548 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -316,10 +316,10 @@ static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+- PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 22, 1),
+- PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 20, 1),
+- PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 26, 1),
+- PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 24, 1),
++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1),
++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1),
++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1),
++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+@@ -354,10 +354,10 @@ static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+- PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 22, 1),
+- PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 20, 1),
+- PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 26, 1),
+- PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 24, 1),
++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1),
++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1),
++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1),
++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+@@ -392,10 +392,10 @@ static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+- PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 22, 1),
+- PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 20, 1),
+- PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 26, 1),
+- PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 24, 1),
++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1),
++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1),
++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1),
++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1),
+ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
+index 415d1df8f46a5..365c4b0ca4654 100644
+--- a/drivers/pinctrl/pinconf-generic.c
++++ b/drivers/pinctrl/pinconf-generic.c
+@@ -395,8 +395,10 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
+ for_each_available_child_of_node(np_config, np) {
+ ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
+ &reserved_maps, num_maps, type);
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(np);
+ goto exit;
++ }
+ }
+ return 0;
+
+diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
+index ecab6bf63dc6d..ad4db99094a79 100644
+--- a/drivers/pinctrl/pinctrl-k210.c
++++ b/drivers/pinctrl/pinctrl-k210.c
+@@ -862,8 +862,10 @@ static int k210_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ for_each_available_child_of_node(np_config, np) {
+ ret = k210_pinctrl_dt_subnode_to_map(pctldev, np, map,
+ &reserved_maps, num_maps);
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(np);
+ goto err;
++ }
+ }
+ return 0;
+
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index 105771ff82e62..19a61f697e99c 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -2046,6 +2046,11 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev,
+ return devm_regmap_init_mmio(&pdev->dev, base, ®map_config);
+ }
+
++static void ocelot_destroy_workqueue(void *data)
++{
++ destroy_workqueue(data);
++}
++
+ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ {
+ const struct ocelot_match_data *data;
+@@ -2078,6 +2083,11 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ if (!info->wq)
+ return -ENOMEM;
+
++ ret = devm_add_action_or_reset(dev, ocelot_destroy_workqueue,
++ info->wq);
++ if (ret)
++ return ret;
++
+ info->pincfg_data = &data->pincfg_data;
+
+ reset = devm_reset_control_get_optional_shared(dev, "switch");
+@@ -2125,15 +2135,6 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int ocelot_pinctrl_remove(struct platform_device *pdev)
+-{
+- struct ocelot_pinctrl *info = platform_get_drvdata(pdev);
+-
+- destroy_workqueue(info->wq);
+-
+- return 0;
+-}
+-
+ static struct platform_driver ocelot_pinctrl_driver = {
+ .driver = {
+ .name = "pinctrl-ocelot",
+@@ -2141,7 +2142,6 @@ static struct platform_driver ocelot_pinctrl_driver = {
+ .suppress_bind_attrs = true,
+ },
+ .probe = ocelot_pinctrl_probe,
+- .remove = ocelot_pinctrl_remove,
+ };
+ module_platform_driver(ocelot_pinctrl_driver);
+ MODULE_LICENSE("Dual MIT/GPL");
+diff --git a/drivers/pinctrl/pinctrl-thunderbay.c b/drivers/pinctrl/pinctrl-thunderbay.c
+index 9328b17485cf0..590bbbf619afc 100644
+--- a/drivers/pinctrl/pinctrl-thunderbay.c
++++ b/drivers/pinctrl/pinctrl-thunderbay.c
+@@ -808,7 +808,7 @@ static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct funct
+ funcs[i].num_group_names,
+ funcs[i].data);
+ }
+- kfree(funcs);
++
+ return 0;
+ }
+
+@@ -817,6 +817,7 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
+ struct function_desc *thunderbay_funcs;
+ void *ptr;
+ int pin;
++ int ret;
+
+ /*
+ * Allocate maximum possible number of functions. Assume every pin
+@@ -860,7 +861,10 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
+ return -ENOMEM;
+
+ thunderbay_funcs = ptr;
+- return thunderbay_add_functions(tpc, thunderbay_funcs);
++ ret = thunderbay_add_functions(tpc, thunderbay_funcs);
++
++ kfree(thunderbay_funcs);
++ return ret;
+ }
+
+ static int thunderbay_pinconf_set_tristate(struct thunderbay_pinctrl *tpc,
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index dc5722db20661..a54bf964521fb 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -20,6 +20,7 @@
+ #include <linux/usb/typec_altmode.h>
+ #include <linux/usb/typec_dp.h>
+ #include <linux/usb/typec_mux.h>
++#include <linux/usb/typec_retimer.h>
+ #include <linux/usb/typec_tbt.h>
+ #include <linux/usb/role.h>
+
+@@ -56,6 +57,7 @@ struct cros_typec_port {
+ struct usb_pd_identity c_identity;
+ struct typec_switch *ori_sw;
+ struct typec_mux *mux;
++ struct typec_retimer *retimer;
+ struct usb_role_switch *role_sw;
+
+ /* Variables keeping track of switch state. */
+@@ -144,6 +146,12 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
+ goto mux_err;
+ }
+
++ port->retimer = fwnode_typec_retimer_get(fwnode);
++ if (IS_ERR(port->retimer)) {
++ dev_dbg(dev, "Retimer handle not found.\n");
++ goto retimer_sw_err;
++ }
++
+ port->ori_sw = fwnode_typec_switch_get(fwnode);
+ if (IS_ERR(port->ori_sw)) {
+ dev_dbg(dev, "Orientation switch handle not found.\n");
+@@ -159,12 +167,15 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
+ return 0;
+
+ role_sw_err:
+- usb_role_switch_put(port->role_sw);
+-ori_sw_err:
+ typec_switch_put(port->ori_sw);
+-mux_err:
++ port->ori_sw = NULL;
++ori_sw_err:
++ typec_retimer_put(port->retimer);
++ port->retimer = NULL;
++retimer_sw_err:
+ typec_mux_put(port->mux);
+-
++ port->mux = NULL;
++mux_err:
+ return -ENODEV;
+ }
+
+@@ -207,6 +218,21 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po
+ }
+ }
+
++/*
++ * Map the Type-C Mux state to retimer state and call the retimer set function. We need this
++ * because we re-use the Type-C mux state for retimers.
++ */
++static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_mux_state state)
++{
++ struct typec_retimer_state rstate = {
++ .alt = state.alt,
++ .mode = state.mode,
++ .data = state.data,
++ };
++
++ return typec_retimer_set(retimer, &rstate);
++}
++
+ static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
+ {
+ port->state.alt = NULL;
+@@ -215,6 +241,7 @@ static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
+
+ usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
+ typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
++ cros_typec_retimer_set(port->retimer, port->state);
+
+ return typec_mux_set(port->mux, &port->state);
+ }
+@@ -412,9 +439,14 @@ unregister_ports:
+
+ static int cros_typec_usb_safe_state(struct cros_typec_port *port)
+ {
++ int ret;
+ port->state.mode = TYPEC_STATE_SAFE;
+
+- return typec_mux_set(port->mux, &port->state);
++ ret = cros_typec_retimer_set(port->retimer, port->state);
++ if (!ret)
++ ret = typec_mux_set(port->mux, &port->state);
++
++ return ret;
+ }
+
+ /*
+@@ -511,7 +543,11 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,
+ port->state.data = &dp_data;
+ port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
+
+- return typec_mux_set(port->mux, &port->state);
++ ret = cros_typec_retimer_set(port->retimer, port->state);
++ if (!ret)
++ ret = typec_mux_set(port->mux, &port->state);
++
++ return ret;
+ }
+
+ static int cros_typec_enable_usb4(struct cros_typec_data *typec,
+@@ -600,7 +636,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
+ } else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
+ port->state.alt = NULL;
+ port->state.mode = TYPEC_STATE_USB;
+- ret = typec_mux_set(port->mux, &port->state);
++
++ ret = cros_typec_retimer_set(port->retimer, port->state);
++ if (!ret)
++ ret = typec_mux_set(port->mux, &port->state);
+ } else {
+ dev_dbg(typec->dev,
+ "Unrecognized mode requested, mux flags: %x\n",
+diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
+index 4b5a81c9dc6da..10670b6588e3e 100644
+--- a/drivers/platform/chrome/cros_usbpd_notify.c
++++ b/drivers/platform/chrome/cros_usbpd_notify.c
+@@ -239,7 +239,11 @@ static int __init cros_usbpd_notify_init(void)
+ return ret;
+
+ #ifdef CONFIG_ACPI
+- platform_driver_register(&cros_usbpd_notify_acpi_driver);
++ ret = platform_driver_register(&cros_usbpd_notify_acpi_driver);
++ if (ret) {
++ platform_driver_unregister(&cros_usbpd_notify_plat_driver);
++ return ret;
++ }
+ #endif
+ return 0;
+ }
+diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c
+index 65b4a819f1bdf..c2c9b0d3244cb 100644
+--- a/drivers/platform/mellanox/mlxbf-pmc.c
++++ b/drivers/platform/mellanox/mlxbf-pmc.c
+@@ -358,7 +358,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = {
+ { 0x32, "DDN_DIAG_W_INGRESS" },
+ { 0x33, "DDN_DIAG_C_INGRESS" },
+ { 0x34, "DDN_DIAG_CORE_SENT" },
+- { 0x35, "NDN_DIAG_S_OUT_OF_CRED" },
++ { 0x35, "NDN_DIAG_N_OUT_OF_CRED" },
+ { 0x36, "NDN_DIAG_S_OUT_OF_CRED" },
+ { 0x37, "NDN_DIAG_E_OUT_OF_CRED" },
+ { 0x38, "NDN_DIAG_W_OUT_OF_CRED" },
+diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c
+index eac3e6b4ea113..935562c870c3d 100644
+--- a/drivers/platform/x86/huawei-wmi.c
++++ b/drivers/platform/x86/huawei-wmi.c
+@@ -760,6 +760,9 @@ static int huawei_wmi_input_setup(struct device *dev,
+ const char *guid,
+ struct input_dev **idev)
+ {
++ acpi_status status;
++ int err;
++
+ *idev = devm_input_allocate_device(dev);
+ if (!*idev)
+ return -ENOMEM;
+@@ -769,10 +772,19 @@ static int huawei_wmi_input_setup(struct device *dev,
+ (*idev)->id.bustype = BUS_HOST;
+ (*idev)->dev.parent = dev;
+
+- return sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL) ||
+- input_register_device(*idev) ||
+- wmi_install_notify_handler(guid, huawei_wmi_input_notify,
+- *idev);
++ err = sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL);
++ if (err)
++ return err;
++
++ err = input_register_device(*idev);
++ if (err)
++ return err;
++
++ status = wmi_install_notify_handler(guid, huawei_wmi_input_notify, *idev);
++ if (ACPI_FAILURE(status))
++ return -EIO;
++
++ return 0;
+ }
+
+ static void huawei_wmi_input_exit(struct device *dev, const char *guid)
+diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+index 1cf958983e868..b2342b3d78c72 100644
+--- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c
++++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+@@ -185,7 +185,8 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
+ cfg.init_data = &init_data;
+ cfg.ena_gpiod = int3472->regulator.gpio;
+
+- int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
++ int3472->regulator.rdev = regulator_register(int3472->dev,
++ &int3472->regulator.rdesc,
+ &cfg);
+ if (IS_ERR(int3472->regulator.rdev)) {
+ ret = PTR_ERR(int3472->regulator.rdev);
+diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
+index 7cc9089d1e14f..e7a3e34028178 100644
+--- a/drivers/platform/x86/intel_scu_ipc.c
++++ b/drivers/platform/x86/intel_scu_ipc.c
+@@ -583,7 +583,6 @@ __intel_scu_ipc_register(struct device *parent,
+ scu->dev.parent = parent;
+ scu->dev.class = &intel_scu_ipc_class;
+ scu->dev.release = intel_scu_ipc_release;
+- dev_set_name(&scu->dev, "intel_scu_ipc");
+
+ if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem),
+ "intel_scu_ipc")) {
+@@ -612,6 +611,7 @@ __intel_scu_ipc_register(struct device *parent,
+ * After this point intel_scu_ipc_release() takes care of
+ * releasing the SCU IPC resources once refcount drops to zero.
+ */
++ dev_set_name(&scu->dev, "intel_scu_ipc");
+ err = device_register(&scu->dev);
+ if (err) {
+ put_device(&scu->dev);
+diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c
+index 9a19fbd2f7341..9a457956025a5 100644
+--- a/drivers/platform/x86/mxm-wmi.c
++++ b/drivers/platform/x86/mxm-wmi.c
+@@ -35,13 +35,11 @@ int mxm_wmi_call_mxds(int adapter)
+ .xarg = 1,
+ };
+ struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_status status;
+
+ printk("calling mux switch %d\n", adapter);
+
+- status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+- &output);
++ status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+
+ if (ACPI_FAILURE(status))
+ return status;
+@@ -60,13 +58,11 @@ int mxm_wmi_call_mxmx(int adapter)
+ .xarg = 1,
+ };
+ struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_status status;
+
+ printk("calling mux switch %d\n", adapter);
+
+- status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+- &output);
++ status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+
+ if (ACPI_FAILURE(status))
+ return status;
+diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
+index 4df5aa6a309c3..6a60c5d83383b 100644
+--- a/drivers/pnp/core.c
++++ b/drivers/pnp/core.c
+@@ -148,14 +148,14 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
+ dev->dev.coherent_dma_mask = dev->dma_mask;
+ dev->dev.release = &pnp_release_device;
+
+- dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
+-
+ dev_id = pnp_add_id(dev, pnpid);
+ if (!dev_id) {
+ kfree(dev);
+ return NULL;
+ }
+
++ dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
++
+ return dev;
+ }
+
+diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
+index c19c50442761d..58757a5799f8b 100644
+--- a/drivers/power/supply/ab8500_charger.c
++++ b/drivers/power/supply/ab8500_charger.c
+@@ -3719,7 +3719,14 @@ static int __init ab8500_charger_init(void)
+ if (ret)
+ return ret;
+
+- return platform_driver_register(&ab8500_charger_driver);
++ ret = platform_driver_register(&ab8500_charger_driver);
++ if (ret) {
++ platform_unregister_drivers(ab8500_charger_component_drivers,
++ ARRAY_SIZE(ab8500_charger_component_drivers));
++ return ret;
++ }
++
++ return 0;
+ }
+
+ static void __exit ab8500_charger_exit(void)
+diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
+index 852a6fec4339b..92fab662a51d4 100644
+--- a/drivers/power/supply/bq25890_charger.c
++++ b/drivers/power/supply/bq25890_charger.c
+@@ -1019,6 +1019,36 @@ static const struct regulator_desc bq25890_vbus_desc = {
+ .fixed_uV = 5000000,
+ .n_voltages = 1,
+ };
++
++static int bq25890_register_regulator(struct bq25890_device *bq)
++{
++ struct bq25890_platform_data *pdata = dev_get_platdata(bq->dev);
++ struct regulator_config cfg = {
++ .dev = bq->dev,
++ .driver_data = bq,
++ };
++ struct regulator_dev *reg;
++
++ if (!IS_ERR_OR_NULL(bq->usb_phy))
++ return 0;
++
++ if (pdata)
++ cfg.init_data = pdata->regulator_init_data;
++
++ reg = devm_regulator_register(bq->dev, &bq25890_vbus_desc, &cfg);
++ if (IS_ERR(reg)) {
++ return dev_err_probe(bq->dev, PTR_ERR(reg),
++ "registering vbus regulator");
++ }
++
++ return 0;
++}
++#else
++static inline int
++bq25890_register_regulator(struct bq25890_device *bq)
++{
++ return 0;
++}
+ #endif
+
+ static int bq25890_get_chip_version(struct bq25890_device *bq)
+@@ -1159,8 +1189,14 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
+ return 0;
+ }
+
+-static int bq25890_probe(struct i2c_client *client,
+- const struct i2c_device_id *id)
++static void bq25890_non_devm_cleanup(void *data)
++{
++ struct bq25890_device *bq = data;
++
++ cancel_delayed_work_sync(&bq->pump_express_work);
++}
++
++static int bq25890_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+ struct bq25890_device *bq;
+@@ -1214,27 +1250,24 @@ static int bq25890_probe(struct i2c_client *client,
+
+ /* OTG reporting */
+ bq->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
++
++ /*
++ * This must be before bq25890_power_supply_init(), so that it runs
++ * after devm unregisters the power_supply.
++ */
++ ret = devm_add_action_or_reset(dev, bq25890_non_devm_cleanup, bq);
++ if (ret)
++ return ret;
++
++ ret = bq25890_register_regulator(bq);
++ if (ret)
++ return ret;
++
+ if (!IS_ERR_OR_NULL(bq->usb_phy)) {
+ INIT_WORK(&bq->usb_work, bq25890_usb_work);
+ bq->usb_nb.notifier_call = bq25890_usb_notifier;
+ usb_register_notifier(bq->usb_phy, &bq->usb_nb);
+ }
+-#ifdef CONFIG_REGULATOR
+- else {
+- struct bq25890_platform_data *pdata = dev_get_platdata(dev);
+- struct regulator_config cfg = { };
+- struct regulator_dev *reg;
+-
+- cfg.dev = dev;
+- cfg.driver_data = bq;
+- if (pdata)
+- cfg.init_data = pdata->regulator_init_data;
+-
+- reg = devm_regulator_register(dev, &bq25890_vbus_desc, &cfg);
+- if (IS_ERR(reg))
+- return dev_err_probe(dev, PTR_ERR(reg), "registering regulator");
+- }
+-#endif
+
+ ret = bq25890_power_supply_init(bq);
+ if (ret < 0) {
+@@ -1372,7 +1405,7 @@ static struct i2c_driver bq25890_driver = {
+ .acpi_match_table = ACPI_PTR(bq25890_acpi_match),
+ .pm = &bq25890_pm,
+ },
+- .probe = bq25890_probe,
++ .probe_new = bq25890_probe,
+ .remove = bq25890_remove,
+ .shutdown = bq25890_shutdown,
+ .id_table = bq25890_i2c_ids,
+diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c
+index 728e2a6cc9c31..473522b4326ad 100644
+--- a/drivers/power/supply/cw2015_battery.c
++++ b/drivers/power/supply/cw2015_battery.c
+@@ -21,6 +21,7 @@
+ #include <linux/regmap.h>
+ #include <linux/time.h>
+ #include <linux/workqueue.h>
++#include <linux/devm-helpers.h>
+
+ #define CW2015_SIZE_BATINFO 64
+
+@@ -698,7 +699,11 @@ static int cw_bat_probe(struct i2c_client *client)
+ }
+
+ cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery");
+- INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work);
++ if (!cw_bat->battery_workqueue)
++ return -ENOMEM;
++
++ devm_delayed_work_autocancel(&client->dev,
++ &cw_bat->battery_delay_work, cw_bat_work);
+ queue_delayed_work(cw_bat->battery_workqueue,
+ &cw_bat->battery_delay_work, msecs_to_jiffies(10));
+ return 0;
+@@ -725,15 +730,6 @@ static int __maybe_unused cw_bat_resume(struct device *dev)
+
+ static SIMPLE_DEV_PM_OPS(cw_bat_pm_ops, cw_bat_suspend, cw_bat_resume);
+
+-static int cw_bat_remove(struct i2c_client *client)
+-{
+- struct cw_battery *cw_bat = i2c_get_clientdata(client);
+-
+- cancel_delayed_work_sync(&cw_bat->battery_delay_work);
+- power_supply_put_battery_info(cw_bat->rk_bat, cw_bat->battery);
+- return 0;
+-}
+-
+ static const struct i2c_device_id cw_bat_id_table[] = {
+ { "cw2015", 0 },
+ { }
+@@ -752,7 +748,6 @@ static struct i2c_driver cw_bat_driver = {
+ .pm = &cw_bat_pm_ops,
+ },
+ .probe_new = cw_bat_probe,
+- .remove = cw_bat_remove,
+ .id_table = cw_bat_id_table,
+ };
+
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 4b5fb172fa994..01d1ac79d982e 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -750,6 +750,11 @@ int power_supply_get_battery_info(struct power_supply *psy,
+ int i, tab_len, size;
+
+ propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
++ if (!propname) {
++ power_supply_put_battery_info(psy, info);
++ err = -ENOMEM;
++ goto out_put_node;
++ }
+ list = of_get_property(battery_np, propname, &size);
+ if (!list || !size) {
+ dev_err(&psy->dev, "failed to get %s\n", propname);
+@@ -1387,8 +1392,8 @@ create_triggers_failed:
+ register_cooler_failed:
+ psy_unregister_thermal(psy);
+ register_thermal_failed:
+- device_del(dev);
+ wakeup_init_failed:
++ device_del(dev);
+ device_add_failed:
+ check_supplies_failed:
+ dev_set_name_failed:
+diff --git a/drivers/power/supply/z2_battery.c b/drivers/power/supply/z2_battery.c
+index 7ed4e4bb26eca..fd33cdf9cf12c 100644
+--- a/drivers/power/supply/z2_battery.c
++++ b/drivers/power/supply/z2_battery.c
+@@ -206,10 +206,12 @@ static int z2_batt_probe(struct i2c_client *client,
+
+ charger->charge_gpiod = devm_gpiod_get_optional(&client->dev,
+ NULL, GPIOD_IN);
+- if (IS_ERR(charger->charge_gpiod))
+- return dev_err_probe(&client->dev,
++ if (IS_ERR(charger->charge_gpiod)) {
++ ret = dev_err_probe(&client->dev,
+ PTR_ERR(charger->charge_gpiod),
+ "failed to get charge GPIO\n");
++ goto err;
++ }
+
+ if (charger->charge_gpiod) {
+ gpiod_set_consumer_name(charger->charge_gpiod, "BATT CHRG");
+diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
+index 6901a44dc428d..a337b47dc2f7d 100644
+--- a/drivers/pwm/pwm-mediatek.c
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -296,7 +296,7 @@ static const struct pwm_mediatek_of_data mt6795_pwm_data = {
+ static const struct pwm_mediatek_of_data mt7622_pwm_data = {
+ .num_pwms = 6,
+ .pwm45_fixup = false,
+- .has_ck_26m_sel = false,
++ .has_ck_26m_sel = true,
+ };
+
+ static const struct pwm_mediatek_of_data mt7623_pwm_data = {
+diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
+index c605013e4114c..3fbb4bae93a4e 100644
+--- a/drivers/pwm/pwm-mtk-disp.c
++++ b/drivers/pwm/pwm-mtk-disp.c
+@@ -178,7 +178,7 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ {
+ struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+ u64 rate, period, high_width;
+- u32 clk_div, con0, con1;
++ u32 clk_div, pwm_en, con0, con1;
+ int err;
+
+ err = clk_prepare_enable(mdp->clk_main);
+@@ -197,7 +197,8 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ rate = clk_get_rate(mdp->clk_main);
+ con0 = readl(mdp->base + mdp->data->con0);
+ con1 = readl(mdp->base + mdp->data->con1);
+- state->enabled = !!(con0 & BIT(0));
++ pwm_en = readl(mdp->base + DISP_PWM_EN);
++ state->enabled = !!(pwm_en & mdp->data->enable_mask);
+ clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
+ period = FIELD_GET(PWM_PERIOD_MASK, con1);
+ /*
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 2d4fa5e5fdd46..bb72393134016 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -204,8 +204,11 @@ static int pwm_sifive_clock_notifier(struct notifier_block *nb,
+ struct pwm_sifive_ddata *ddata =
+ container_of(nb, struct pwm_sifive_ddata, notifier);
+
+- if (event == POST_RATE_CHANGE)
++ if (event == POST_RATE_CHANGE) {
++ mutex_lock(&ddata->lock);
+ pwm_sifive_update_clock(ddata, ndata->new_rate);
++ mutex_unlock(&ddata->lock);
++ }
+
+ return NOTIFY_OK;
+ }
+diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
+index dad9978c91861..249dc01932979 100644
+--- a/drivers/pwm/pwm-tegra.c
++++ b/drivers/pwm/pwm-tegra.c
+@@ -145,8 +145,19 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ * source clock rate as required_clk_rate, PWM controller will
+ * be able to configure the requested period.
+ */
+- required_clk_rate =
+- (NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
++ required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
++ period_ns);
++
++ if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
++ /*
++ * required_clk_rate is a lower bound for the input
++ * rate; for lower rates there is no value for PWM_SCALE
++ * that yields a period less than or equal to the
++ * requested period. Hence, for lower rates, double the
++ * required_clk_rate to get a clock rate that can meet
++ * the requested period.
++ */
++ required_clk_rate *= 2;
+
+ err = dev_pm_opp_set_rate(pc->dev, required_clk_rate);
+ if (err < 0)
+diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
+index 2cdc054e53a53..43db495f19861 100644
+--- a/drivers/rapidio/devices/rio_mport_cdev.c
++++ b/drivers/rapidio/devices/rio_mport_cdev.c
+@@ -1804,8 +1804,11 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv,
+ rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+ 0, 0xffff);
+ err = rio_add_device(rdev);
+- if (err)
+- goto cleanup;
++ if (err) {
++ put_device(&rdev->dev);
++ return err;
++ }
++
+ rio_dev_get(rdev);
+
+ return 0;
+@@ -1901,10 +1904,6 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+
+ priv->md = chdev;
+
+- mutex_lock(&chdev->file_mutex);
+- list_add_tail(&priv->list, &chdev->file_list);
+- mutex_unlock(&chdev->file_mutex);
+-
+ INIT_LIST_HEAD(&priv->db_filters);
+ INIT_LIST_HEAD(&priv->pw_filters);
+ spin_lock_init(&priv->fifo_lock);
+@@ -1913,6 +1912,7 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+ sizeof(struct rio_event) * MPORT_EVENT_DEPTH,
+ GFP_KERNEL);
+ if (ret < 0) {
++ put_device(&chdev->dev);
+ dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n");
+ ret = -ENOMEM;
+ goto err_fifo;
+@@ -1923,6 +1923,9 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+ spin_lock_init(&priv->req_lock);
+ mutex_init(&priv->dma_lock);
+ #endif
++ mutex_lock(&chdev->file_mutex);
++ list_add_tail(&priv->list, &chdev->file_list);
++ mutex_unlock(&chdev->file_mutex);
+
+ filp->private_data = priv;
+ goto out;
+diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
+index 19b0c33f4a62a..fdcf742b2adbc 100644
+--- a/drivers/rapidio/rio-scan.c
++++ b/drivers/rapidio/rio-scan.c
+@@ -454,8 +454,12 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
+ 0, 0xffff);
+
+ ret = rio_add_device(rdev);
+- if (ret)
+- goto cleanup;
++ if (ret) {
++ if (rswitch)
++ kfree(rswitch->route_table);
++ put_device(&rdev->dev);
++ return NULL;
++ }
+
+ rio_dev_get(rdev);
+
+diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
+index e74cf09eeff07..9544b8ee0c963 100644
+--- a/drivers/rapidio/rio.c
++++ b/drivers/rapidio/rio.c
+@@ -2186,11 +2186,16 @@ int rio_register_mport(struct rio_mport *port)
+ atomic_set(&port->state, RIO_DEVICE_RUNNING);
+
+ res = device_register(&port->dev);
+- if (res)
++ if (res) {
+ dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
+ port->id, res);
+- else
++ mutex_lock(&rio_mport_list_lock);
++ list_del(&port->node);
++ mutex_unlock(&rio_mport_list_lock);
++ put_device(&port->dev);
++ } else {
+ dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id);
++ }
+
+ return res;
+ }
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index c0f368f1b49f7..6829f7d8e24c8 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -987,7 +987,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
+ /* get input voltage */
+ input_uV = 0;
+ if (rdev->supply)
+- input_uV = regulator_get_voltage(rdev->supply);
++ input_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
+ if (input_uV <= 0)
+ input_uV = rdev->constraints->input_uV;
+ if (input_uV <= 0) {
+@@ -1578,7 +1578,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+ if (rdev->supply_name && !rdev->supply)
+ return -EPROBE_DEFER;
+
+- if (rdev->supply) {
++ /* If supplying regulator has already been enabled,
++ * it's not intended to have use_count increment
++ * when rdev is only boot-on.
++ */
++ if (rdev->supply &&
++ (rdev->constraints->always_on ||
++ !regulator_is_enabled(rdev->supply))) {
+ ret = regulator_enable(rdev->supply);
+ if (ret < 0) {
+ _regulator_put(rdev->supply);
+@@ -1622,6 +1628,7 @@ static int set_supply(struct regulator_dev *rdev,
+
+ rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
+ if (rdev->supply == NULL) {
++ module_put(supply_rdev->owner);
+ err = -ENOMEM;
+ return err;
+ }
+@@ -1795,7 +1802,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+
+ regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
+ if (regulator == NULL) {
+- kfree(supply_name);
++ kfree_const(supply_name);
+ return NULL;
+ }
+
+@@ -1925,6 +1932,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+ node = of_get_regulator(dev, supply);
+ if (node) {
+ r = of_find_regulator_by_node(node);
++ of_node_put(node);
+ if (r)
+ return r;
+
+@@ -5380,6 +5388,7 @@ static struct regulator_coupler generic_regulator_coupler = {
+
+ /**
+ * regulator_register - register regulator
++ * @dev: the device that drive the regulator
+ * @regulator_desc: regulator to register
+ * @cfg: runtime configuration for regulator
+ *
+@@ -5388,7 +5397,8 @@ static struct regulator_coupler generic_regulator_coupler = {
+ * or an ERR_PTR() on error.
+ */
+ struct regulator_dev *
+-regulator_register(const struct regulator_desc *regulator_desc,
++regulator_register(struct device *dev,
++ const struct regulator_desc *regulator_desc,
+ const struct regulator_config *cfg)
+ {
+ const struct regulator_init_data *init_data;
+@@ -5397,7 +5407,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ struct regulator_dev *rdev;
+ bool dangling_cfg_gpiod = false;
+ bool dangling_of_gpiod = false;
+- struct device *dev;
+ int ret, i;
+
+ if (cfg == NULL)
+@@ -5409,8 +5418,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ goto rinse;
+ }
+
+- dev = cfg->dev;
+- WARN_ON(!dev);
++ WARN_ON(!dev || !cfg->dev);
+
+ if (regulator_desc->name == NULL || regulator_desc->ops == NULL) {
+ ret = -EINVAL;
+@@ -5523,7 +5531,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
+
+ /* register with sysfs */
+ rdev->dev.class = ®ulator_class;
+- rdev->dev.parent = dev;
++ rdev->dev.parent = config->dev;
+ dev_set_name(&rdev->dev, "regulator.%lu",
+ (unsigned long) atomic_inc_return(®ulator_no));
+ dev_set_drvdata(&rdev->dev, rdev);
+@@ -5613,6 +5621,7 @@ unset_supplies:
+ regulator_remove_coupling(rdev);
+ mutex_unlock(®ulator_list_mutex);
+ wash:
++ regulator_put(rdev->supply);
+ kfree(rdev->coupling_desc.coupled_rdevs);
+ mutex_lock(®ulator_list_mutex);
+ regulator_ena_gpio_free(rdev);
+diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
+index 32823a87fd409..d94db64cd490c 100644
+--- a/drivers/regulator/devres.c
++++ b/drivers/regulator/devres.c
+@@ -221,7 +221,7 @@ struct regulator_dev *devm_regulator_register(struct device *dev,
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+- rdev = regulator_register(regulator_desc, config);
++ rdev = regulator_register(dev, regulator_desc, config);
+ if (!IS_ERR(rdev)) {
+ *ptr = rdev;
+ devres_add(dev, ptr);
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index e12b681c72e5e..bd0c5d1fd647c 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -505,7 +505,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
+ struct device_node *child;
+ struct regulator_init_data *init_data = NULL;
+
+- child = regulator_of_get_init_node(dev, desc);
++ child = regulator_of_get_init_node(config->dev, desc);
+ if (!child)
+ return NULL;
+
+diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c
+index 639b71eb41ffe..bcf7140f3bc98 100644
+--- a/drivers/regulator/qcom-labibb-regulator.c
++++ b/drivers/regulator/qcom-labibb-regulator.c
+@@ -822,6 +822,7 @@ static int qcom_labibb_regulator_probe(struct platform_device *pdev)
+ if (irq == 0)
+ irq = -EINVAL;
+
++ of_node_put(reg_node);
+ return dev_err_probe(vreg->dev, irq,
+ "Short-circuit irq not found.\n");
+ }
+diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
+index 561de6b2e6e36..5839e47323360 100644
+--- a/drivers/regulator/qcom-rpmh-regulator.c
++++ b/drivers/regulator/qcom-rpmh-regulator.c
+@@ -1188,7 +1188,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
+ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps520, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"),
+- RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps510, "vdd-s3"),
++ RPMH_VREG("smps3", "smp%s3", &pmic5_hfsmps515, "vdd-s3"),
+ RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l2"),
+ RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l1-l2"),
+ RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
+diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c
+index 30ea3bc8ca192..7a454b7b6eab9 100644
+--- a/drivers/regulator/stm32-vrefbuf.c
++++ b/drivers/regulator/stm32-vrefbuf.c
+@@ -210,7 +210,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
+ pdev->dev.of_node,
+ &stm32_vrefbuf_regu);
+
+- rdev = regulator_register(&stm32_vrefbuf_regu, &config);
++ rdev = regulator_register(&pdev->dev, &stm32_vrefbuf_regu, &config);
+ if (IS_ERR(rdev)) {
+ ret = PTR_ERR(rdev);
+ dev_err(&pdev->dev, "register failed with error %d\n", ret);
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 6afd0941e5524..dc6f07ca83410 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -449,6 +449,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
+ }
+
+ ret = of_address_to_resource(node, 0, &r);
++ of_node_put(node);
+ if (ret)
+ return ret;
+
+@@ -556,6 +557,7 @@ static int adsp_probe(struct platform_device *pdev)
+ detach_proxy_pds:
+ adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+ free_rproc:
++ device_init_wakeup(adsp->dev, false);
+ rproc_free(rproc);
+
+ return ret;
+@@ -572,6 +574,8 @@ static int adsp_remove(struct platform_device *pdev)
+ qcom_remove_sysmon_subdev(adsp->sysmon);
+ qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
+ qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
++ adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
++ device_init_wakeup(adsp->dev, false);
+ rproc_free(adsp->rproc);
+
+ return 0;
+diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
+index bb0947f7770ea..ba24d745b2d65 100644
+--- a/drivers/remoteproc/qcom_q6v5_wcss.c
++++ b/drivers/remoteproc/qcom_q6v5_wcss.c
+@@ -351,7 +351,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
+ if (ret) {
+ dev_err(wcss->dev,
+ "xo cbcr enabling timed out (rc:%d)\n", ret);
+- return ret;
++ goto disable_xo_cbcr_clk;
+ }
+
+ writel(0, wcss->reg_base + Q6SS_CGC_OVERRIDE);
+@@ -417,6 +417,7 @@ disable_sleep_cbcr_clk:
+ val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
+ val &= ~Q6SS_CLK_ENABLE;
+ writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
++disable_xo_cbcr_clk:
+ val = readl(wcss->reg_base + Q6SS_XO_CBCR);
+ val &= ~Q6SS_CLK_ENABLE;
+ writel(val, wcss->reg_base + Q6SS_XO_CBCR);
+@@ -827,6 +828,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
+ int ret;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
++ if (!res)
++ return -EINVAL;
++
+ wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!wcss->reg_base)
+diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
+index 57dde2a69b9dd..15af52f8499eb 100644
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -652,7 +652,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+ if (sysmon->shutdown_irq != -ENODATA) {
+ dev_err(sysmon->dev,
+ "failed to retrieve shutdown-ack IRQ\n");
+- return ERR_PTR(sysmon->shutdown_irq);
++ ret = sysmon->shutdown_irq;
++ kfree(sysmon);
++ return ERR_PTR(ret);
+ }
+ } else {
+ ret = devm_request_threaded_irq(sysmon->dev,
+@@ -663,6 +665,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+ if (ret) {
+ dev_err(sysmon->dev,
+ "failed to acquire shutdown-ack IRQ\n");
++ kfree(sysmon);
+ return ERR_PTR(ret);
+ }
+ }
+diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
+index e48223c00c672..e5b7b48cffac0 100644
+--- a/drivers/rtc/class.c
++++ b/drivers/rtc/class.c
+@@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev)
+
+ rtc->id = id;
+ rtc->dev.parent = dev;
+- err = dev_set_name(&rtc->dev, "rtc%d", id);
++ err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
+ if (err)
+ return ERR_PTR(err);
+
+- err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
++ err = dev_set_name(&rtc->dev, "rtc%d", id);
+ if (err)
+ return ERR_PTR(err);
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 58cc2bae2f8a0..00e2ca7374ecf 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
+ return IRQ_NONE;
+ }
+
++#ifdef CONFIG_ACPI
++
++#include <linux/acpi.h>
++
++static u32 rtc_handler(void *context)
++{
++ struct device *dev = context;
++ struct cmos_rtc *cmos = dev_get_drvdata(dev);
++ unsigned char rtc_control = 0;
++ unsigned char rtc_intr;
++ unsigned long flags;
++
++
++ /*
++ * Always update rtc irq when ACPI is used as RTC Alarm.
++ * Or else, ACPI SCI is enabled during suspend/resume only,
++ * update rtc irq in that case.
++ */
++ if (cmos_use_acpi_alarm())
++ cmos_interrupt(0, (void *)cmos->rtc);
++ else {
++ /* Fix me: can we use cmos_interrupt() here as well? */
++ spin_lock_irqsave(&rtc_lock, flags);
++ if (cmos_rtc.suspend_ctrl)
++ rtc_control = CMOS_READ(RTC_CONTROL);
++ if (rtc_control & RTC_AIE) {
++ cmos_rtc.suspend_ctrl &= ~RTC_AIE;
++ CMOS_WRITE(rtc_control, RTC_CONTROL);
++ rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
++ rtc_update_irq(cmos->rtc, 1, rtc_intr);
++ }
++ spin_unlock_irqrestore(&rtc_lock, flags);
++ }
++
++ pm_wakeup_hard_event(dev);
++ acpi_clear_event(ACPI_EVENT_RTC);
++ acpi_disable_event(ACPI_EVENT_RTC, 0);
++ return ACPI_INTERRUPT_HANDLED;
++}
++
++static void acpi_rtc_event_setup(struct device *dev)
++{
++ if (acpi_disabled)
++ return;
++
++ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
++ /*
++ * After the RTC handler is installed, the Fixed_RTC event should
++ * be disabled. Only when the RTC alarm is set will it be enabled.
++ */
++ acpi_clear_event(ACPI_EVENT_RTC);
++ acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void acpi_rtc_event_cleanup(void)
++{
++ if (acpi_disabled)
++ return;
++
++ acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler);
++}
++
++static void rtc_wake_on(struct device *dev)
++{
++ acpi_clear_event(ACPI_EVENT_RTC);
++ acpi_enable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void rtc_wake_off(struct device *dev)
++{
++ acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++#ifdef CONFIG_X86
++/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
++static void use_acpi_alarm_quirks(void)
++{
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++ return;
++
++ if (!is_hpet_enabled())
++ return;
++
++ if (dmi_get_bios_year() < 2015)
++ return;
++
++ use_acpi_alarm = true;
++}
++#else
++static inline void use_acpi_alarm_quirks(void) { }
++#endif
++
++static void acpi_cmos_wake_setup(struct device *dev)
++{
++ if (acpi_disabled)
++ return;
++
++ use_acpi_alarm_quirks();
++
++ cmos_rtc.wake_on = rtc_wake_on;
++ cmos_rtc.wake_off = rtc_wake_off;
++
++ /* ACPI tables bug workaround. */
++ if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
++ dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
++ acpi_gbl_FADT.month_alarm);
++ acpi_gbl_FADT.month_alarm = 0;
++ }
++
++ cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
++ cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
++ cmos_rtc.century = acpi_gbl_FADT.century;
++
++ if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
++ dev_info(dev, "RTC can wake from S4\n");
++
++ /* RTC always wakes from S1/S2/S3, and often S4/STD */
++ device_init_wakeup(dev, 1);
++}
++
++static void cmos_check_acpi_rtc_status(struct device *dev,
++ unsigned char *rtc_control)
++{
++ struct cmos_rtc *cmos = dev_get_drvdata(dev);
++ acpi_event_status rtc_status;
++ acpi_status status;
++
++ if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
++ return;
++
++ status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
++ if (ACPI_FAILURE(status)) {
++ dev_err(dev, "Could not get RTC status\n");
++ } else if (rtc_status & ACPI_EVENT_FLAG_SET) {
++ unsigned char mask;
++ *rtc_control &= ~RTC_AIE;
++ CMOS_WRITE(*rtc_control, RTC_CONTROL);
++ mask = CMOS_READ(RTC_INTR_FLAGS);
++ rtc_update_irq(cmos->rtc, 1, mask);
++ }
++}
++
++#else /* !CONFIG_ACPI */
++
++static inline void acpi_rtc_event_setup(struct device *dev)
++{
++}
++
++static inline void acpi_rtc_event_cleanup(void)
++{
++}
++
++static inline void acpi_cmos_wake_setup(struct device *dev)
++{
++}
++
++static inline void cmos_check_acpi_rtc_status(struct device *dev,
++ unsigned char *rtc_control)
++{
++}
++#endif /* CONFIG_ACPI */
++
+ #ifdef CONFIG_PNP
+ #define INITSECTION
+
+@@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ if (info->address_space)
+ address_space = info->address_space;
+
+- if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
+- cmos_rtc.day_alrm = info->rtc_day_alarm;
+- if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
+- cmos_rtc.mon_alrm = info->rtc_mon_alarm;
+- if (info->rtc_century && info->rtc_century < 128)
+- cmos_rtc.century = info->rtc_century;
++ cmos_rtc.day_alrm = info->rtc_day_alarm;
++ cmos_rtc.mon_alrm = info->rtc_mon_alarm;
++ cmos_rtc.century = info->rtc_century;
+
+ if (info->wake_on && info->wake_off) {
+ cmos_rtc.wake_on = info->wake_on;
+ cmos_rtc.wake_off = info->wake_off;
+ }
++ } else {
++ acpi_cmos_wake_setup(dev);
+ }
+
++ if (cmos_rtc.day_alrm >= 128)
++ cmos_rtc.day_alrm = 0;
++
++ if (cmos_rtc.mon_alrm >= 128)
++ cmos_rtc.mon_alrm = 0;
++
++ if (cmos_rtc.century >= 128)
++ cmos_rtc.century = 0;
++
+ cmos_rtc.dev = dev;
+ dev_set_drvdata(dev, &cmos_rtc);
+
+@@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ nvmem_cfg.size = address_space - NVRAM_OFFSET;
+ devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg);
+
++ /*
++ * Everything has gone well so far, so by default register a handler for
++ * the ACPI RTC fixed event.
++ */
++ if (!info)
++ acpi_rtc_event_setup(dev);
++
+ dev_info(dev, "%s%s, %d bytes nvram%s\n",
+ !is_valid_irq(rtc_irq) ? "no alarms" :
+ cmos_rtc.mon_alrm ? "alarms up to one year" :
+@@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev)
+ hpet_unregister_irq_handler(cmos_interrupt);
+ }
+
++ if (!dev_get_platdata(dev))
++ acpi_rtc_event_cleanup();
++
+ cmos->rtc = NULL;
+
+ ports = cmos->iomem;
+@@ -1122,9 +1302,6 @@ static void cmos_check_wkalrm(struct device *dev)
+ }
+ }
+
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+- unsigned char *rtc_control);
+-
+ static int __maybe_unused cmos_resume(struct device *dev)
+ {
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+@@ -1191,175 +1368,13 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
+ * predate even PNPBIOS should set up platform_bus devices.
+ */
+
+-#ifdef CONFIG_ACPI
+-
+-#include <linux/acpi.h>
+-
+-static u32 rtc_handler(void *context)
+-{
+- struct device *dev = context;
+- struct cmos_rtc *cmos = dev_get_drvdata(dev);
+- unsigned char rtc_control = 0;
+- unsigned char rtc_intr;
+- unsigned long flags;
+-
+-
+- /*
+- * Always update rtc irq when ACPI is used as RTC Alarm.
+- * Or else, ACPI SCI is enabled during suspend/resume only,
+- * update rtc irq in that case.
+- */
+- if (cmos_use_acpi_alarm())
+- cmos_interrupt(0, (void *)cmos->rtc);
+- else {
+- /* Fix me: can we use cmos_interrupt() here as well? */
+- spin_lock_irqsave(&rtc_lock, flags);
+- if (cmos_rtc.suspend_ctrl)
+- rtc_control = CMOS_READ(RTC_CONTROL);
+- if (rtc_control & RTC_AIE) {
+- cmos_rtc.suspend_ctrl &= ~RTC_AIE;
+- CMOS_WRITE(rtc_control, RTC_CONTROL);
+- rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+- rtc_update_irq(cmos->rtc, 1, rtc_intr);
+- }
+- spin_unlock_irqrestore(&rtc_lock, flags);
+- }
+-
+- pm_wakeup_hard_event(dev);
+- acpi_clear_event(ACPI_EVENT_RTC);
+- acpi_disable_event(ACPI_EVENT_RTC, 0);
+- return ACPI_INTERRUPT_HANDLED;
+-}
+-
+-static inline void rtc_wake_setup(struct device *dev)
+-{
+- if (acpi_disabled)
+- return;
+-
+- acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+- /*
+- * After the RTC handler is installed, the Fixed_RTC event should
+- * be disabled. Only when the RTC alarm is set will it be enabled.
+- */
+- acpi_clear_event(ACPI_EVENT_RTC);
+- acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_on(struct device *dev)
+-{
+- acpi_clear_event(ACPI_EVENT_RTC);
+- acpi_enable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_off(struct device *dev)
+-{
+- acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-#ifdef CONFIG_X86
+-/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
+-static void use_acpi_alarm_quirks(void)
+-{
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+- return;
+-
+- if (!is_hpet_enabled())
+- return;
+-
+- if (dmi_get_bios_year() < 2015)
+- return;
+-
+- use_acpi_alarm = true;
+-}
+-#else
+-static inline void use_acpi_alarm_quirks(void) { }
+-#endif
+-
+-/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
+- * its device node and pass extra config data. This helps its driver use
+- * capabilities that the now-obsolete mc146818 didn't have, and informs it
+- * that this board's RTC is wakeup-capable (per ACPI spec).
+- */
+-static struct cmos_rtc_board_info acpi_rtc_info;
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+- if (acpi_disabled)
+- return;
+-
+- use_acpi_alarm_quirks();
+-
+- acpi_rtc_info.wake_on = rtc_wake_on;
+- acpi_rtc_info.wake_off = rtc_wake_off;
+-
+- /* workaround bug in some ACPI tables */
+- if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+- dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
+- acpi_gbl_FADT.month_alarm);
+- acpi_gbl_FADT.month_alarm = 0;
+- }
+-
+- acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
+- acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
+- acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;
+-
+- /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
+- if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+- dev_info(dev, "RTC can wake from S4\n");
+-
+- dev->platform_data = &acpi_rtc_info;
+-
+- /* RTC always wakes from S1/S2/S3, and often S4/STD */
+- device_init_wakeup(dev, 1);
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+- unsigned char *rtc_control)
+-{
+- struct cmos_rtc *cmos = dev_get_drvdata(dev);
+- acpi_event_status rtc_status;
+- acpi_status status;
+-
+- if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
+- return;
+-
+- status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
+- if (ACPI_FAILURE(status)) {
+- dev_err(dev, "Could not get RTC status\n");
+- } else if (rtc_status & ACPI_EVENT_FLAG_SET) {
+- unsigned char mask;
+- *rtc_control &= ~RTC_AIE;
+- CMOS_WRITE(*rtc_control, RTC_CONTROL);
+- mask = CMOS_READ(RTC_INTR_FLAGS);
+- rtc_update_irq(cmos->rtc, 1, mask);
+- }
+-}
+-
+-#else
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+- unsigned char *rtc_control)
+-{
+-}
+-
+-static void rtc_wake_setup(struct device *dev)
+-{
+-}
+-#endif
+-
+ #ifdef CONFIG_PNP
+
+ #include <linux/pnp.h>
+
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+- int irq, ret;
+-
+- cmos_wake_setup(&pnp->dev);
++ int irq;
+
+ if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+ irq = 0;
+@@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ irq = pnp_irq(pnp, 0);
+ }
+
+- ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+- if (ret)
+- return ret;
+-
+- rtc_wake_setup(&pnp->dev);
+-
+- return 0;
++ return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+ }
+
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+ struct resource *resource;
+- int irq, ret;
++ int irq;
+
+ cmos_of_init(pdev);
+- cmos_wake_setup(&pdev->dev);
+
+ if (RTC_IOMAPPED)
+ resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
+@@ -1478,13 +1486,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+ if (irq < 0)
+ irq = -1;
+
+- ret = cmos_do_probe(&pdev->dev, resource, irq);
+- if (ret)
+- return ret;
+-
+- rtc_wake_setup(&pdev->dev);
+-
+- return 0;
++ return cmos_do_probe(&pdev->dev, resource, irq);
+ }
+
+ static int cmos_platform_remove(struct platform_device *pdev)
+diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
+index 5e03834016294..f6d2ad91ff7a9 100644
+--- a/drivers/rtc/rtc-mxc_v2.c
++++ b/drivers/rtc/rtc-mxc_v2.c
+@@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev)
+ }
+
+ pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+- if (IS_ERR(pdata->rtc))
++ if (IS_ERR(pdata->rtc)) {
++ clk_disable_unprepare(pdata->clk);
+ return PTR_ERR(pdata->rtc);
++ }
+
+ pdata->rtc->ops = &mxc_rtc_ops;
+ pdata->rtc->range_max = U32_MAX;
+diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
+index 095891999da11..754e03984f986 100644
+--- a/drivers/rtc/rtc-pcf85063.c
++++ b/drivers/rtc/rtc-pcf85063.c
+@@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+ if (ret)
+ return ret;
+
+- alrm->time.tm_sec = bcd2bin(buf[0]);
+- alrm->time.tm_min = bcd2bin(buf[1]);
+- alrm->time.tm_hour = bcd2bin(buf[2]);
+- alrm->time.tm_mday = bcd2bin(buf[3]);
++ alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f);
++ alrm->time.tm_min = bcd2bin(buf[1] & 0x7f);
++ alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f);
++ alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f);
+
+ ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val);
+ if (ret)
+@@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable)
+ unsigned int buf;
+ int ret;
+
+- ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf);
++ ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf);
+ if (ret < 0)
+ return ret;
+ buf &= PCF85063_REG_CLKO_F_MASK;
+diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
+index 7fb9145c43bd5..fa351ac201587 100644
+--- a/drivers/rtc/rtc-pic32.c
++++ b/drivers/rtc/rtc-pic32.c
+@@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev)
+
+ spin_lock_init(&pdata->alarm_lock);
+
++ pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
++ if (IS_ERR(pdata->rtc))
++ return PTR_ERR(pdata->rtc);
++
+ clk_prepare_enable(pdata->clk);
+
+ pic32_rtc_enable(pdata, 1);
+
+ device_init_wakeup(&pdev->dev, 1);
+
+- pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+- if (IS_ERR(pdata->rtc))
+- return PTR_ERR(pdata->rtc);
+-
+ pdata->rtc->ops = &pic32_rtcops;
+ pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
+diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
+index ac788799c8e3e..0d36bc50197c1 100644
+--- a/drivers/rtc/rtc-rzn1.c
++++ b/drivers/rtc/rtc-rzn1.c
+@@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
+
+- devm_pm_runtime_enable(&pdev->dev);
++ ret = devm_pm_runtime_enable(&pdev->dev);
++ if (ret < 0)
++ return ret;
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
+ return ret;
+diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
+index bd929b0e7d7de..d82acf1af1fae 100644
+--- a/drivers/rtc/rtc-snvs.c
++++ b/drivers/rtc/rtc-snvs.c
+@@ -32,6 +32,14 @@
+ #define SNVS_LPPGDR_INIT 0x41736166
+ #define CNTR_TO_SECS_SH 15
+
++/* The maximum RTC clock cycles that are allowed to pass between two
++ * consecutive clock counter register reads. If the values are corrupted a
++ * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles
++ * we end at 10ms which should be enough for most cases. If it once takes
++ * longer than expected we do a retry.
++ */
++#define MAX_RTC_READ_DIFF_CYCLES 320
++
+ struct snvs_rtc_data {
+ struct rtc_device *rtc;
+ struct regmap *regmap;
+@@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
+ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ {
+ u64 read1, read2;
++ s64 diff;
+ unsigned int timeout = 100;
+
+ /* As expected, the registers might update between the read of the LSB
+@@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ do {
+ read2 = read1;
+ read1 = rtc_read_lpsrt(data);
+- } while (read1 != read2 && --timeout);
++ diff = read1 - read2;
++ } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+ if (!timeout)
+ dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+
+@@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
+ {
+ u32 count1, count2;
++ s32 diff;
+ unsigned int timeout = 100;
+
+ regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+ do {
+ count2 = count1;
+ regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+- } while (count1 != count2 && --timeout);
++ diff = count1 - count2;
++ } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+ if (!timeout) {
+ dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+ return -ETIMEDOUT;
+diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
+index bdb20f63254e2..0f8e4231098ef 100644
+--- a/drivers/rtc/rtc-st-lpc.c
++++ b/drivers/rtc/rtc-st-lpc.c
+@@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev)
+
+ rtc->clkrate = clk_get_rate(rtc->clk);
+ if (!rtc->clkrate) {
++ clk_disable_unprepare(rtc->clk);
+ dev_err(&pdev->dev, "Unable to fetch clock rate\n");
+ return -EINVAL;
+ }
+diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
+index e0fdd54bfeb70..f672c610cb24a 100644
+--- a/drivers/s390/net/ctcm_main.c
++++ b/drivers/s390/net/ctcm_main.c
+@@ -825,16 +825,9 @@ done:
+ /*
+ * Start transmission of a packet.
+ * Called from generic network device layer.
+- *
+- * skb Pointer to buffer containing the packet.
+- * dev Pointer to interface struct.
+- *
+- * returns 0 if packet consumed, !0 if packet rejected.
+- * Note: If we return !0, then the packet is free'd by
+- * the generic network layer.
+ */
+ /* first merge version - leaving both functions separated */
+-static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct ctcm_priv *priv = dev->ml_priv;
+
+@@ -877,7 +870,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ }
+
+ /* unmerged MPC variant of ctcm_tx */
+-static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ int len = 0;
+ struct ctcm_priv *priv = dev->ml_priv;
+diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
+index 84c8981317b46..38f312664ce72 100644
+--- a/drivers/s390/net/lcs.c
++++ b/drivers/s390/net/lcs.c
+@@ -1519,9 +1519,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
+ /*
+ * Packet transmit function called by network stack
+ */
+-static int
+-__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+- struct net_device *dev)
++static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct lcs_header *header;
+ int rc = NETDEV_TX_OK;
+@@ -1582,8 +1581,7 @@ out:
+ return rc;
+ }
+
+-static int
+-lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct lcs_card *card;
+ int rc;
+diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
+index 65aa0a96c21de..66076cada8ae4 100644
+--- a/drivers/s390/net/netiucv.c
++++ b/drivers/s390/net/netiucv.c
+@@ -1248,15 +1248,8 @@ static int netiucv_close(struct net_device *dev)
+ /*
+ * Start transmission of a packet.
+ * Called from generic network device layer.
+- *
+- * @param skb Pointer to buffer containing the packet.
+- * @param dev Pointer to interface struct.
+- *
+- * @return 0 if packet consumed, !0 if packet rejected.
+- * Note: If we return !0, then the packet is free'd by
+- * the generic network layer.
+ */
+-static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct netiucv_priv *privptr = netdev_priv(dev);
+ int rc;
+diff --git a/drivers/scsi/elx/efct/efct_driver.c b/drivers/scsi/elx/efct/efct_driver.c
+index b08fc8839808d..49fd2cfed70c7 100644
+--- a/drivers/scsi/elx/efct/efct_driver.c
++++ b/drivers/scsi/elx/efct/efct_driver.c
+@@ -42,6 +42,7 @@ efct_device_init(void)
+
+ rc = efct_scsi_reg_fc_transport();
+ if (rc) {
++ efct_scsi_tgt_driver_exit();
+ pr_err("failed to register to FC host\n");
+ return rc;
+ }
+diff --git a/drivers/scsi/elx/libefc/efclib.h b/drivers/scsi/elx/libefc/efclib.h
+index dde20891c2dd7..57e3386128127 100644
+--- a/drivers/scsi/elx/libefc/efclib.h
++++ b/drivers/scsi/elx/libefc/efclib.h
+@@ -58,10 +58,12 @@ enum efc_node_send_ls_acc {
+ #define EFC_LINK_STATUS_UP 0
+ #define EFC_LINK_STATUS_DOWN 1
+
++enum efc_sm_event;
++
+ /* State machine context header */
+ struct efc_sm_ctx {
+ void (*current_state)(struct efc_sm_ctx *ctx,
+- u32 evt, void *arg);
++ enum efc_sm_event evt, void *arg);
+
+ const char *description;
+ void *app;
+@@ -365,7 +367,7 @@ struct efc_node {
+ int prev_evt;
+
+ void (*nodedb_state)(struct efc_sm_ctx *ctx,
+- u32 evt, void *arg);
++ enum efc_sm_event evt, void *arg);
+ struct timer_list gidpt_delay_timer;
+ u64 time_last_gidpt_msec;
+
+diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
+index 6ec296321ffc1..38774a272e627 100644
+--- a/drivers/scsi/fcoe/fcoe.c
++++ b/drivers/scsi/fcoe/fcoe.c
+@@ -2491,6 +2491,7 @@ static int __init fcoe_init(void)
+
+ out_free:
+ mutex_unlock(&fcoe_config_mutex);
++ fcoe_transport_detach(&fcoe_sw_transport);
+ out_destroy:
+ destroy_workqueue(fcoe_wq);
+ return rc;
+diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c
+index af658aa38fedf..6260aa5ea6af8 100644
+--- a/drivers/scsi/fcoe/fcoe_sysfs.c
++++ b/drivers/scsi/fcoe/fcoe_sysfs.c
+@@ -830,14 +830,15 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
+
+ dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id);
+ error = device_register(&ctlr->dev);
+- if (error)
+- goto out_del_q2;
++ if (error) {
++ destroy_workqueue(ctlr->devloss_work_q);
++ destroy_workqueue(ctlr->work_q);
++ put_device(&ctlr->dev);
++ return NULL;
++ }
+
+ return ctlr;
+
+-out_del_q2:
+- destroy_workqueue(ctlr->devloss_work_q);
+- ctlr->devloss_work_q = NULL;
+ out_del_q:
+ destroy_workqueue(ctlr->work_q);
+ ctlr->work_q = NULL;
+@@ -1036,16 +1037,16 @@ struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr,
+ fcf->selected = new_fcf->selected;
+
+ error = device_register(&fcf->dev);
+- if (error)
+- goto out_del;
++ if (error) {
++ put_device(&fcf->dev);
++ goto out;
++ }
+
+ fcf->state = FCOE_FCF_STATE_CONNECTED;
+ list_add_tail(&fcf->peers, &ctlr->fcfs);
+
+ return fcf;
+
+-out_del:
+- kfree(fcf);
+ out:
+ return NULL;
+ }
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 33af5b8dede20..f4f9e5abee76d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1701,13 +1701,15 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
+ return rc;
+ }
+
++ /* Remote phy */
+ if (rc)
+ return rc;
+
+- /* Remote phy */
+ if (dev_is_sata(device)) {
+- rc = sas_ata_wait_after_reset(device,
+- HISI_SAS_WAIT_PHYUP_TIMEOUT);
++ struct ata_link *link = &device->sata_dev.ap->link;
++
++ rc = ata_wait_after_reset(link, HISI_SAS_WAIT_PHYUP_TIMEOUT,
++ smp_ata_check_ready_type);
+ } else {
+ msleep(2000);
+ }
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index a47bcce3c9c78..796bc7aa6c8e4 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -8929,7 +8929,7 @@ clean1: /* wq/aer/h */
+ destroy_workqueue(h->monitor_ctlr_wq);
+ h->monitor_ctlr_wq = NULL;
+ }
+- kfree(h);
++ hpda_free_ctlr_info(h);
+ return rc;
+ }
+
+@@ -9790,7 +9790,8 @@ static int hpsa_add_sas_host(struct ctlr_info *h)
+ return 0;
+
+ free_sas_phy:
+- hpsa_free_sas_phy(hpsa_sas_phy);
++ sas_phy_free(hpsa_sas_phy->phy);
++ kfree(hpsa_sas_phy);
+ free_sas_port:
+ hpsa_free_sas_port(hpsa_sas_port);
+ free_sas_node:
+@@ -9826,10 +9827,12 @@ static int hpsa_add_sas_device(struct hpsa_sas_node *hpsa_sas_node,
+
+ rc = hpsa_sas_port_add_rphy(hpsa_sas_port, rphy);
+ if (rc)
+- goto free_sas_port;
++ goto free_sas_rphy;
+
+ return 0;
+
++free_sas_rphy:
++ sas_rphy_free(rphy);
+ free_sas_port:
+ hpsa_free_sas_port(hpsa_sas_port);
+ device->sas_port = NULL;
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index 9d01a3e3c26aa..2022ffb450417 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -10872,11 +10872,19 @@ static struct notifier_block ipr_notifier = {
+ **/
+ static int __init ipr_init(void)
+ {
++ int rc;
++
+ ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
+ IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
+
+ register_reboot_notifier(&ipr_notifier);
+- return pci_register_driver(&ipr_driver);
++ rc = pci_register_driver(&ipr_driver);
++ if (rc) {
++ unregister_reboot_notifier(&ipr_notifier);
++ return rc;
++ }
++
++ return 0;
+ }
+
+ /**
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index d35c9296f7388..2fd55ef9ffca5 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -287,6 +287,31 @@ static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy)
+ return 1;
+ }
+
++int smp_ata_check_ready_type(struct ata_link *link)
++{
++ struct domain_device *dev = link->ap->private_data;
++ struct sas_phy *phy = sas_get_local_phy(dev);
++ struct domain_device *ex_dev = dev->parent;
++ enum sas_device_type type = SAS_PHY_UNUSED;
++ u8 sas_addr[SAS_ADDR_SIZE];
++ int res;
++
++ res = sas_get_phy_attached_dev(ex_dev, phy->number, sas_addr, &type);
++ sas_put_local_phy(phy);
++ if (res)
++ return res;
++
++ switch (type) {
++ case SAS_SATA_PENDING:
++ return 0;
++ case SAS_END_DEVICE:
++ return 1;
++ default:
++ return -ENODEV;
++ }
++}
++EXPORT_SYMBOL_GPL(smp_ata_check_ready_type);
++
+ static int smp_ata_check_ready(struct ata_link *link)
+ {
+ int res;
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 5ce2518301040..63a23251fb1d8 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1693,8 +1693,8 @@ static int sas_get_phy_change_count(struct domain_device *dev,
+ return res;
+ }
+
+-static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+- u8 *sas_addr, enum sas_device_type *type)
++int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
++ u8 *sas_addr, enum sas_device_type *type)
+ {
+ int res;
+ struct smp_disc_resp *disc_resp;
+diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
+index 8d0ad3abc7b5c..a94bd0790b055 100644
+--- a/drivers/scsi/libsas/sas_internal.h
++++ b/drivers/scsi/libsas/sas_internal.h
+@@ -84,6 +84,8 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
+ int sas_ex_phy_discover(struct domain_device *dev, int single);
+ int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
+ struct smp_rps_resp *rps_resp);
++int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
++ u8 *sas_addr, enum sas_device_type *type);
+ int sas_try_ata_reset(struct asd_sas_phy *phy);
+ void sas_hae_reset(struct work_struct *work);
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 03c21167fc854..c4960da4c1c40 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -8076,10 +8076,10 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
+ "IO_cnt", "Info", "BWutil(ms)");
+ }
+
+- /* Needs to be _bh because record is called from timer interrupt
++ /* Needs to be _irq because record is called from timer interrupt
+ * context
+ */
+- spin_lock_bh(ring_lock);
++ spin_lock_irq(ring_lock);
+ while (*head_idx != *tail_idx) {
+ entry = &ring[*head_idx];
+
+@@ -8123,7 +8123,7 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
+ if (cnt >= max_read_entries)
+ break;
+ }
+- spin_unlock_bh(ring_lock);
++ spin_unlock_irq(ring_lock);
+
+ return cnt;
+ }
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+index 0681daee6c149..e5ecd6ada6cdd 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+@@ -829,6 +829,8 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
+ if ((sas_rphy_add(rphy))) {
+ ioc_err(ioc, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
++ sas_rphy_free(rphy);
++ rphy = NULL;
+ }
+
+ if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 3ec6a200942ee..01ca440ce6203 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -5129,17 +5129,17 @@ struct secure_flash_update_block_pk {
+ (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
+ test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
+
+-#define QLA_VHA_MARK_BUSY(__vha, __bail) do { \
+- atomic_inc(&__vha->vref_count); \
+- mb(); \
+- if (__vha->flags.delete_progress) { \
+- atomic_dec(&__vha->vref_count); \
+- wake_up(&__vha->vref_waitq); \
+- __bail = 1; \
+- } else { \
+- __bail = 0; \
+- } \
+-} while (0)
++static inline bool qla_vha_mark_busy(scsi_qla_host_t *vha)
++{
++ atomic_inc(&vha->vref_count);
++ mb();
++ if (vha->flags.delete_progress) {
++ atomic_dec(&vha->vref_count);
++ wake_up(&vha->vref_waitq);
++ return true;
++ }
++ return false;
++}
+
+ #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \
+ atomic_dec(&__vha->vref_count); \
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index e7fe0e52c11d4..97cf9c25adf09 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -110,6 +110,7 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ struct qla_qpair *qpair = sp->qpair;
+ u32 handle;
+ unsigned long flags;
++ int sp_found = 0, cmdsp_found = 0;
+
+ if (sp->cmd_sp)
+ ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+@@ -124,18 +125,21 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+ for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
+ if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
+- sp->cmd_sp))
++ sp->cmd_sp)) {
+ qpair->req->outstanding_cmds[handle] = NULL;
++ cmdsp_found = 1;
++ }
+
+ /* removing the abort */
+ if (qpair->req->outstanding_cmds[handle] == sp) {
+ qpair->req->outstanding_cmds[handle] = NULL;
++ sp_found = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
+- if (sp->cmd_sp) {
++ if (cmdsp_found && sp->cmd_sp) {
+ /*
+ * This done function should take care of
+ * original command ref: INIT
+@@ -143,8 +147,10 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
+ }
+
+- abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
+- sp->done(sp, QLA_OS_TIMER_EXPIRED);
++ if (sp_found) {
++ abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
++ sp->done(sp, QLA_OS_TIMER_EXPIRED);
++ }
+ }
+
+ static void qla24xx_abort_sp_done(srb_t *sp, int res)
+@@ -168,7 +174,6 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ struct srb_iocb *abt_iocb;
+ srb_t *sp;
+ int rval = QLA_FUNCTION_FAILED;
+- uint8_t bail;
+
+ /* ref: INIT for ABTS command */
+ sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
+@@ -176,7 +181,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ if (!sp)
+ return QLA_MEMORY_ALLOC_FAILED;
+
+- QLA_VHA_MARK_BUSY(vha, bail);
++ qla_vha_mark_busy(vha);
+ abt_iocb = &sp->u.iocb_cmd;
+ sp->type = SRB_ABT_CMD;
+ sp->name = "abort";
+@@ -2020,14 +2025,13 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
+ struct srb_iocb *tm_iocb;
+ srb_t *sp;
+ int rval = QLA_FUNCTION_FAILED;
+- uint8_t bail;
+
+ /* ref: INIT */
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+ if (!sp)
+ goto done;
+
+- QLA_VHA_MARK_BUSY(vha, bail);
++ qla_vha_mark_busy(vha);
+ sp->type = SRB_TM_CMD;
+ sp->name = "tmf";
+ qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha),
+diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
+index db17f7f410cdd..5185dc5daf80d 100644
+--- a/drivers/scsi/qla2xxx/qla_inline.h
++++ b/drivers/scsi/qla2xxx/qla_inline.h
+@@ -225,11 +225,9 @@ static inline srb_t *
+ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
+ {
+ srb_t *sp = NULL;
+- uint8_t bail;
+ struct qla_qpair *qpair;
+
+- QLA_VHA_MARK_BUSY(vha, bail);
+- if (unlikely(bail))
++ if (unlikely(qla_vha_mark_busy(vha)))
+ return NULL;
+
+ qpair = vha->hw->base_qpair;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 1c7fb6484db20..5e5d1a6c51d52 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5039,13 +5039,11 @@ struct qla_work_evt *
+ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
+ {
+ struct qla_work_evt *e;
+- uint8_t bail;
+
+ if (test_bit(UNLOADING, &vha->dpc_flags))
+ return NULL;
+
+- QLA_VHA_MARK_BUSY(vha, bail);
+- if (bail)
++ if (qla_vha_mark_busy(vha))
+ return NULL;
+
+ e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 7346098c1c68f..34eb0a9355bca 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -3785,7 +3785,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
+ return illegal_condition_result;
+ }
+- lrdp = kzalloc(lbdof_blen, GFP_ATOMIC);
++ lrdp = kzalloc(lbdof_blen, GFP_ATOMIC | __GFP_NOWARN);
+ if (lrdp == NULL)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ if (sdebug_verbose)
+@@ -4436,7 +4436,7 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
+ if (ret)
+ return ret;
+
+- arr = kcalloc(lb_size, vnum, GFP_ATOMIC);
++ arr = kcalloc(lb_size, vnum, GFP_ATOMIC | __GFP_NOWARN);
+ if (!arr) {
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+ INSUFF_RES_ASCQ);
+@@ -4504,7 +4504,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
+
+ rep_max_zones = (alloc_len - 64) >> ilog2(RZONES_DESC_HD);
+
+- arr = kzalloc(alloc_len, GFP_ATOMIC);
++ arr = kzalloc(alloc_len, GFP_ATOMIC | __GFP_NOWARN);
+ if (!arr) {
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+ INSUFF_RES_ASCQ);
+@@ -7340,7 +7340,10 @@ clean:
+ kfree(sdbg_devinfo->zstate);
+ kfree(sdbg_devinfo);
+ }
+- kfree(sdbg_host);
++ if (sdbg_host->dev.release)
++ put_device(&sdbg_host->dev);
++ else
++ kfree(sdbg_host);
+ pr_warn("%s: failed, errno=%d\n", __func__, -error);
+ return error;
+ }
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 448748e3fba5e..f00212777f82c 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -342,19 +342,11 @@ enum blk_eh_timer_return scsi_timeout(struct request *req)
+
+ if (rtn == BLK_EH_DONE) {
+ /*
+- * Set the command to complete first in order to prevent a real
+- * completion from releasing the command while error handling
+- * is using it. If the command was already completed, then the
+- * lower level driver beat the timeout handler, and it is safe
+- * to return without escalating error recovery.
+- *
+- * If timeout handling lost the race to a real completion, the
+- * block layer may ignore that due to a fake timeout injection,
+- * so return RESET_TIMER to allow error handling another shot
+- * at this command.
++ * If scsi_done() has already set SCMD_STATE_COMPLETE, do not
++ * modify *scmd.
+ */
+ if (test_and_set_bit(SCMD_STATE_COMPLETE, &scmd->state))
+- return BLK_EH_RESET_TIMER;
++ return BLK_EH_DONE;
+ if (scsi_abort_command(scmd) != SUCCESS) {
+ set_host_byte(scmd, DID_TIME_OUT);
+ scsi_eh_scmd_add(scmd);
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index e550b12e525a1..c8235f15728bb 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1130,7 +1130,7 @@ struct pqi_scsi_dev {
+ u8 phy_id;
+ u8 ncq_prio_enable;
+ u8 ncq_prio_support;
+- u8 multi_lun_device_lun_count;
++ u8 lun_count;
+ bool raid_bypass_configured; /* RAID bypass configured */
+ bool raid_bypass_enabled; /* RAID bypass enabled */
+ u32 next_bypass_group[RAID_MAP_MAX_DATA_DISKS_PER_ROW];
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 7a8c2c75acbaf..e011d82172d53 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1610,9 +1610,7 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
+ &id_phys->alternate_paths_phys_connector,
+ sizeof(device->phys_connector));
+ device->bay = id_phys->phys_bay_in_box;
+- device->multi_lun_device_lun_count = id_phys->multi_lun_device_lun_count;
+- if (!device->multi_lun_device_lun_count)
+- device->multi_lun_device_lun_count = 1;
++ device->lun_count = id_phys->multi_lun_device_lun_count;
+ if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) &&
+ id_phys->phy_count)
+ device->phy_id =
+@@ -1746,7 +1744,7 @@ out:
+ return offline;
+ }
+
+-static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
++static int pqi_get_device_info_phys_logical(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device,
+ struct bmic_identify_physical_device *id_phys)
+ {
+@@ -1763,6 +1761,20 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_scsi_dev *device,
++ struct bmic_identify_physical_device *id_phys)
++{
++ int rc;
++
++ rc = pqi_get_device_info_phys_logical(ctrl_info, device, id_phys);
++
++ if (rc == 0 && device->lun_count == 0)
++ device->lun_count = 1;
++
++ return rc;
++}
++
+ static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
+@@ -1897,7 +1909,7 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi
+ int rc;
+ int lun;
+
+- for (lun = 0; lun < device->multi_lun_device_lun_count; lun++) {
++ for (lun = 0; lun < device->lun_count; lun++) {
+ rc = pqi_device_wait_for_pending_io(ctrl_info, device, lun,
+ PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS);
+ if (rc)
+@@ -2076,6 +2088,7 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
+ existing_device->sas_address = new_device->sas_address;
+ existing_device->queue_depth = new_device->queue_depth;
+ existing_device->device_offline = false;
++ existing_device->lun_count = new_device->lun_count;
+
+ if (pqi_is_logical_device(existing_device)) {
+ existing_device->is_external_raid_device = new_device->is_external_raid_device;
+@@ -2108,10 +2121,6 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
+ existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type;
+ memcpy(existing_device->box, new_device->box, sizeof(existing_device->box));
+ memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector));
+-
+- existing_device->multi_lun_device_lun_count = new_device->multi_lun_device_lun_count;
+- if (existing_device->multi_lun_device_lun_count == 0)
+- existing_device->multi_lun_device_lun_count = 1;
+ }
+ }
+
+@@ -6484,6 +6493,12 @@ static void pqi_slave_destroy(struct scsi_device *sdev)
+ return;
+ }
+
++ device->lun_count--;
++ if (device->lun_count > 0) {
++ mutex_unlock(&ctrl_info->scan_mutex);
++ return;
++ }
++
+ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+ list_del(&device->scsi_device_list_entry);
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+@@ -9302,6 +9317,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0x1109)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x110b)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0x8460)
+@@ -9402,6 +9421,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x0072)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0086)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0087)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0088)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0089)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x19e5, 0xd227)
+@@ -9650,6 +9685,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1474)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1475)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1480)
+@@ -9706,6 +9745,14 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14c2)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14c3)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14c4)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x14d0)
+@@ -9942,6 +9989,18 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_LENOVO, 0x0623)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1e93, 0x1000)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1e93, 0x1001)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1e93, 0x1002)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_ANY_ID, PCI_ANY_ID)
+diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c
+index 9b2b5f8c23b9a..8fbf3c1b1311d 100644
+--- a/drivers/scsi/snic/snic_disc.c
++++ b/drivers/scsi/snic/snic_disc.c
+@@ -304,6 +304,9 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
+ ret);
+
+ put_device(&snic->shost->shost_gendev);
++ spin_lock_irqsave(snic->shost->host_lock, flags);
++ list_del(&tgt->list);
++ spin_unlock_irqrestore(snic->shost->host_lock, flags);
+ kfree(tgt);
+ tgt = NULL;
+
+diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c
+index cf1129e9f76b1..d9329b4d8e1b8 100644
+--- a/drivers/soc/apple/rtkit.c
++++ b/drivers/soc/apple/rtkit.c
+@@ -920,8 +920,10 @@ int apple_rtkit_wake(struct apple_rtkit *rtk)
+ }
+ EXPORT_SYMBOL_GPL(apple_rtkit_wake);
+
+-static void apple_rtkit_free(struct apple_rtkit *rtk)
++static void apple_rtkit_free(void *data)
+ {
++ struct apple_rtkit *rtk = data;
++
+ mbox_free_channel(rtk->mbox_chan);
+ destroy_workqueue(rtk->wq);
+
+@@ -944,8 +946,7 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
+ if (IS_ERR(rtk))
+ return rtk;
+
+- ret = devm_add_action_or_reset(dev, (void (*)(void *))apple_rtkit_free,
+- rtk);
++ ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk);
+ if (ret)
+ return ERR_PTR(ret);
+
+diff --git a/drivers/soc/apple/sart.c b/drivers/soc/apple/sart.c
+index 83804b16ad03d..afa1117368997 100644
+--- a/drivers/soc/apple/sart.c
++++ b/drivers/soc/apple/sart.c
+@@ -164,6 +164,11 @@ static int apple_sart_probe(struct platform_device *pdev)
+ return 0;
+ }
+
++static void apple_sart_put_device(void *dev)
++{
++ put_device(dev);
++}
++
+ struct apple_sart *devm_apple_sart_get(struct device *dev)
+ {
+ struct device_node *sart_node;
+@@ -187,7 +192,7 @@ struct apple_sart *devm_apple_sart_get(struct device *dev)
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+- ret = devm_add_action_or_reset(dev, (void (*)(void *))put_device,
++ ret = devm_add_action_or_reset(dev, apple_sart_put_device,
+ &sart_pdev->dev);
+ if (ret)
+ return ERR_PTR(ret);
+diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
+index 9734f1091c695..4b2046c37e6f6 100644
+--- a/drivers/soc/mediatek/mtk-pm-domains.c
++++ b/drivers/soc/mediatek/mtk-pm-domains.c
+@@ -275,9 +275,9 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
+ clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
+
+ /* subsys power off */
+- regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
++ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
+
+diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
+index b4046f393575e..cd44f17dad3d0 100644
+--- a/drivers/soc/qcom/apr.c
++++ b/drivers/soc/qcom/apr.c
+@@ -454,11 +454,19 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+ adev->dev.driver = NULL;
+
+ spin_lock(&apr->svcs_lock);
+- idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
++ ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
+ spin_unlock(&apr->svcs_lock);
++ if (ret < 0) {
++ dev_err(dev, "idr_alloc failed: %d\n", ret);
++ goto out;
++ }
+
+- of_property_read_string_index(np, "qcom,protection-domain",
+- 1, &adev->service_path);
++ ret = of_property_read_string_index(np, "qcom,protection-domain",
++ 1, &adev->service_path);
++ if (ret < 0) {
++ dev_err(dev, "Failed to read second value of qcom,protection-domain\n");
++ goto out;
++ }
+
+ dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev));
+
+@@ -468,6 +476,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+ put_device(&adev->dev);
+ }
+
++out:
+ return ret;
+ }
+
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 38d7296315a25..5942417c7c20d 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -781,7 +781,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+ if (ret)
+ goto err;
+
+- drv_data->ecc_irq = platform_get_irq(pdev, 0);
++ drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+ if (drv_data->ecc_irq >= 0) {
+ llcc_edac = platform_device_register_data(&pdev->dev,
+ "qcom_llcc_edac", -1, drv_data,
+diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
+index 92af7d1b6f5bd..8fb76908be704 100644
+--- a/drivers/soc/ti/knav_qmss_queue.c
++++ b/drivers/soc/ti/knav_qmss_queue.c
+@@ -67,7 +67,7 @@ static DEFINE_MUTEX(knav_dev_lock);
+ * Newest followed by older ones. Search is done from start of the array
+ * until a firmware file is found.
+ */
+-const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
++static const char * const knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
+
+ static bool device_ready;
+ bool knav_qmss_device_ready(void)
+@@ -1785,6 +1785,7 @@ static int knav_queue_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0) {
++ pm_runtime_disable(&pdev->dev);
+ dev_err(dev, "Failed to enable QMSS\n");
+ return ret;
+ }
+diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
+index ad2bb72e640c8..6a389a6444f36 100644
+--- a/drivers/soc/ti/smartreflex.c
++++ b/drivers/soc/ti/smartreflex.c
+@@ -932,6 +932,7 @@ static int omap_sr_probe(struct platform_device *pdev)
+ err_debugfs:
+ debugfs_remove_recursive(sr_info->dbg_dir);
+ err_list_del:
++ pm_runtime_disable(&pdev->dev);
+ list_del(&sr_info->node);
+ clk_unprepare(sr_info->fck);
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 4b12c4964a664..9c8c7948044ed 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -268,9 +268,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
+ if (output)
+ return gpiod_direction_output(spi_gpio->mosi, 1);
+
+- ret = gpiod_direction_input(spi_gpio->mosi);
+- if (ret)
+- return ret;
++ /*
++ * Only change MOSI to an input if using 3WIRE mode.
++ * Otherwise, MOSI could be left floating if there is
++ * no pull resistor connected to the I/O pin, or could
++ * be left logic high if there is a pull-up. Transmitting
++ * logic high when only clocking MISO data in can put some
++ * SPI devices in to a bad state.
++ */
++ if (spi->mode & SPI_3WIRE) {
++ ret = gpiod_direction_input(spi_gpio->mosi);
++ if (ret)
++ return ret;
++ }
+ /*
+ * Send a turnaround high impedance cycle when switching
+ * from output to input. Theoretically there should be
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index a7cc96aeb5903..d6aff909fc365 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1187,6 +1187,11 @@ static int mtk_spi_probe(struct platform_device *pdev)
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+
++ if (mdata->dev_comp->ipm_design)
++ dma_set_max_seg_size(dev, SZ_16M);
++ else
++ dma_set_max_seg_size(dev, SZ_256K);
++
+ ret = devm_request_irq(dev, irq, mtk_spi_interrupt,
+ IRQF_TRIGGER_NONE, dev_name(dev), master);
+ if (ret)
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index b2775d82d2d7b..6313e7d0cdf87 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -377,12 +377,23 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ switch (cmd) {
+ /* read requests */
+ case SPI_IOC_RD_MODE:
+- retval = put_user(spi->mode & SPI_MODE_MASK,
+- (__u8 __user *)arg);
+- break;
+ case SPI_IOC_RD_MODE32:
+- retval = put_user(spi->mode & SPI_MODE_MASK,
+- (__u32 __user *)arg);
++ tmp = spi->mode;
++
++ {
++ struct spi_controller *ctlr = spi->controller;
++
++ if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
++ ctlr->cs_gpiods[spi->chip_select])
++ tmp &= ~SPI_CS_HIGH;
++ }
++
++ if (cmd == SPI_IOC_RD_MODE)
++ retval = put_user(tmp & SPI_MODE_MASK,
++ (__u8 __user *)arg);
++ else
++ retval = put_user(tmp & SPI_MODE_MASK,
++ (__u32 __user *)arg);
+ break;
+ case SPI_IOC_RD_LSB_FIRST:
+ retval = put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0,
+diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
+index a0553c24cce4b..7eee2f8dca47e 100644
+--- a/drivers/staging/media/imx/imx7-media-csi.c
++++ b/drivers/staging/media/imx/imx7-media-csi.c
+@@ -521,9 +521,9 @@ static void imx7_csi_configure(struct imx7_csi *csi)
+ cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
+
+ cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK |
+- BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN |
+- BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
+- BIT_DEINTERLACE_EN);
++ BIT_DATA_FROM_MIPI | BIT_MIPI_DOUBLE_CMPNT |
++ BIT_BASEADDR_CHG_ERR_EN | BIT_BASEADDR_SWITCH_SEL |
++ BIT_BASEADDR_SWITCH_EN | BIT_DEINTERLACE_EN);
+
+ if (out_pix->field == V4L2_FIELD_INTERLACED) {
+ cr18 |= BIT_DEINTERLACE_EN;
+diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c
+index d8c1c0db15c70..cfae99b40ccb4 100644
+--- a/drivers/staging/media/rkvdec/rkvdec-vp9.c
++++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c
+@@ -84,6 +84,8 @@ struct rkvdec_vp9_probs {
+ struct rkvdec_vp9_inter_frame_probs inter;
+ struct rkvdec_vp9_intra_only_frame_probs intra_only;
+ };
++ /* 128 bit alignment */
++ u8 padding1[11];
+ };
+
+ /* Data structure describing auxiliary buffer format. */
+@@ -1006,6 +1008,7 @@ static int rkvdec_vp9_start(struct rkvdec_ctx *ctx)
+
+ ctx->priv = vp9_ctx;
+
++ BUILD_BUG_ON(sizeof(priv_tbl->probs) % 16); /* ensure probs size is 128-bit aligned */
+ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+ &vp9_ctx->priv_tbl.dma, GFP_KERNEL);
+ if (!priv_tbl) {
+diff --git a/drivers/staging/media/stkwebcam/Kconfig b/drivers/staging/media/stkwebcam/Kconfig
+index 4450403dff41f..7234498e634ac 100644
+--- a/drivers/staging/media/stkwebcam/Kconfig
++++ b/drivers/staging/media/stkwebcam/Kconfig
+@@ -2,7 +2,7 @@
+ config VIDEO_STKWEBCAM
+ tristate "USB Syntek DC1125 Camera support (DEPRECATED)"
+ depends on VIDEO_DEV
+- depends on USB
++ depends on MEDIA_USB_SUPPORT && MEDIA_CAMERA_SUPPORT
+ help
+ Say Y here if you want to use this type of camera.
+ Supported devices are typically found in some Asus laptops,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 095b8464f37a0..a07fd28e1fcfd 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -242,6 +242,18 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
+ }
+ }
+
++static u32 cedrus_h265_show_bits(struct cedrus_dev *dev, int num)
++{
++ cedrus_write(dev, VE_DEC_H265_TRIGGER,
++ VE_DEC_H265_TRIGGER_SHOW_BITS |
++ VE_DEC_H265_TRIGGER_TYPE_N_BITS(num));
++
++ cedrus_wait_for(dev, VE_DEC_H265_STATUS,
++ VE_DEC_H265_STATUS_VLD_BUSY);
++
++ return cedrus_read(dev, VE_DEC_H265_BITS_READ);
++}
++
+ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
+ struct cedrus_run *run)
+ {
+@@ -406,7 +418,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ u32 num_entry_point_offsets;
+ u32 output_pic_list_index;
+ u32 pic_order_cnt[2];
+- u8 *padding;
++ u8 padding;
+ int count;
+ u32 reg;
+
+@@ -520,21 +532,22 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ if (slice_params->data_byte_offset == 0)
+ return -EOPNOTSUPP;
+
+- padding = (u8 *)vb2_plane_vaddr(&run->src->vb2_buf, 0) +
+- slice_params->data_byte_offset - 1;
++ cedrus_h265_skip_bits(dev, (slice_params->data_byte_offset - 1) * 8);
++
++ padding = cedrus_h265_show_bits(dev, 8);
+
+ /* at least one bit must be set in that byte */
+- if (*padding == 0)
++ if (padding == 0)
+ return -EINVAL;
+
+ for (count = 0; count < 8; count++)
+- if (*padding & (1 << count))
++ if (padding & (1 << count))
+ break;
+
+ /* Include the one bit. */
+ count++;
+
+- cedrus_h265_skip_bits(dev, slice_params->data_byte_offset * 8 - count);
++ cedrus_h265_skip_bits(dev, 8 - count);
+
+ /* Bitstream parameters. */
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+index d81f7513ade0d..655c05b389cf5 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+@@ -505,6 +505,8 @@
+ #define VE_DEC_H265_LOW_ADDR_ENTRY_POINTS_BUF(a) \
+ SHIFT_AND_MASK_BITS(a, 7, 0)
+
++#define VE_DEC_H265_BITS_READ (VE_ENGINE_DEC_H265 + 0xdc)
++
+ #define VE_DEC_H265_SRAM_OFFSET (VE_ENGINE_DEC_H265 + 0xe0)
+
+ #define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0 0x00
+diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c
+index d5c6c5e296215..1993c3993b3d6 100644
+--- a/drivers/staging/r8188eu/core/rtw_led.c
++++ b/drivers/staging/r8188eu/core/rtw_led.c
+@@ -34,40 +34,19 @@ static void ResetLedStatus(struct led_priv *pLed)
+
+ static void SwLedOn(struct adapter *padapter, struct led_priv *pLed)
+ {
+- u8 LedCfg;
+- int res;
+-
+- if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
+- return;
+-
+- res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+- if (res)
++ if (padapter->bDriverStopped)
+ return;
+
+- rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */
++ rtw_write8(padapter, REG_LEDCFG2, BIT(5)); /* SW control led0 on. */
+ pLed->bLedOn = true;
+ }
+
+ static void SwLedOff(struct adapter *padapter, struct led_priv *pLed)
+ {
+- u8 LedCfg;
+- int res;
+-
+- if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
+- goto exit;
+-
+- res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+- if (res)
+- goto exit;
+-
+- LedCfg &= 0x90; /* Set to software control. */
+- rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
+- res = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+- if (res)
++ if (padapter->bDriverStopped)
+ goto exit;
+
+- LedCfg &= 0xFE;
+- rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
++ rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3));
+ exit:
+ pLed->bLedOn = false;
+ }
+diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+index 10550bd2c16db..abfd14bfd5fb8 100644
+--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
++++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+@@ -273,7 +273,7 @@ static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
+ err = -1;
+ break;
+ }
+- msleep(1);
++ mdelay(1);
+ }
+
+ return err;
+diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
+index abe5c153f74e8..b0ef9da43bc4e 100644
+--- a/drivers/staging/rtl8192e/rtllib_rx.c
++++ b/drivers/staging/rtl8192e/rtllib_rx.c
+@@ -1489,9 +1489,9 @@ static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
+ hdrlen += 4;
+ }
+
+- rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+ ieee->stats.rx_packets++;
+ ieee->stats.rx_bytes += skb->len;
++ rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+
+ return 1;
+ }
+diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+index b58e75932ecd5..3686b3c599ce7 100644
+--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
++++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+@@ -951,9 +951,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ #endif
+
+ if (ieee->iw_mode == IW_MODE_MONITOR) {
++ unsigned int len = skb->len;
++
+ ieee80211_monitor_rx(ieee, skb, rx_stats);
+ stats->rx_packets++;
+- stats->rx_bytes += skb->len;
++ stats->rx_bytes += len;
+ return 1;
+ }
+
+diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c
+index dd646b0c531d4..1ee432c223e2b 100644
+--- a/drivers/staging/vme_user/vme_fake.c
++++ b/drivers/staging/vme_user/vme_fake.c
+@@ -1073,6 +1073,8 @@ static int __init fake_init(void)
+
+ /* We need a fake parent device */
+ vme_root = __root_device_register("vme", THIS_MODULE);
++ if (IS_ERR(vme_root))
++ return PTR_ERR(vme_root);
+
+ /* If we want to support more than one bridge at some point, we need to
+ * dynamically allocate this so we get one per device.
+diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c
+index 9564762132415..b741514e938bd 100644
+--- a/drivers/staging/vme_user/vme_tsi148.c
++++ b/drivers/staging/vme_user/vme_tsi148.c
+@@ -1765,6 +1765,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
+ return 0;
+
+ err_dma:
++ list_del(&entry->list);
+ err_dest:
+ err_source:
+ err_align:
+diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
+index f2919319ad383..ff49c8f3fe241 100644
+--- a/drivers/target/iscsi/iscsi_target_nego.c
++++ b/drivers/target/iscsi/iscsi_target_nego.c
+@@ -1018,6 +1018,13 @@ static int iscsi_target_handle_csg_one(struct iscsit_conn *conn, struct iscsi_lo
+ return 0;
+ }
+
++/*
++ * RETURN VALUE:
++ *
++ * 1 = Login successful
++ * -1 = Login failed
++ * 0 = More PDU exchanges required
++ */
+ static int iscsi_target_do_login(struct iscsit_conn *conn, struct iscsi_login *login)
+ {
+ int pdu_count = 0;
+@@ -1363,12 +1370,13 @@ int iscsi_target_start_negotiation(
+ ret = -1;
+
+ if (ret < 0) {
+- cancel_delayed_work_sync(&conn->login_work);
+ iscsi_target_restore_sock_callbacks(conn);
+ iscsi_remove_failed_auth_entry(conn);
+ }
+- if (ret != 0)
++ if (ret != 0) {
++ cancel_delayed_work_sync(&conn->login_work);
+ iscsi_target_nego_release(conn);
++ }
+
+ return ret;
+ }
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
+index af666bd9e8d4d..c5cd873c6e016 100644
+--- a/drivers/thermal/imx8mm_thermal.c
++++ b/drivers/thermal/imx8mm_thermal.c
+@@ -65,8 +65,14 @@ static int imx8mm_tmu_get_temp(void *data, int *temp)
+ u32 val;
+
+ val = readl_relaxed(tmu->base + TRITSR) & TRITSR_TEMP0_VAL_MASK;
++
++ /*
++ * Do not validate against the V bit (bit 31) due to errata
++ * ERR051272: TMU: Bit 31 of registers TMU_TSCR/TMU_TRITSR/TMU_TRATSR invalid
++ */
++
+ *temp = val * 1000;
+- if (*temp < VER1_TEMP_LOW_LIMIT)
++ if (*temp < VER1_TEMP_LOW_LIMIT || *temp > VER2_TEMP_HIGH_LIMIT)
+ return -EAGAIN;
+
+ return 0;
+diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c
+index 115a44eb4fbfb..4eb4926bbdc78 100644
+--- a/drivers/thermal/k3_j72xx_bandgap.c
++++ b/drivers/thermal/k3_j72xx_bandgap.c
+@@ -439,7 +439,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
+ workaround_needed = false;
+
+ dev_dbg(bgp->dev, "Work around %sneeded\n",
+- workaround_needed ? "not " : "");
++ workaround_needed ? "" : "not ");
+
+ if (!workaround_needed)
+ init_table(5, ref_table, golden_factors);
+diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c
+index d3d9b9fa49e81..4122a51e98741 100644
+--- a/drivers/thermal/qcom/lmh.c
++++ b/drivers/thermal/qcom/lmh.c
+@@ -45,7 +45,7 @@ static irqreturn_t lmh_handle_irq(int hw_irq, void *data)
+ if (irq)
+ generic_handle_irq(irq);
+
+- return 0;
++ return IRQ_HANDLED;
+ }
+
+ static void lmh_enable_interrupt(struct irq_data *d)
+diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+index 770f82cc9bca8..247b39d57fa7c 100644
+--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
++++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+@@ -252,7 +252,8 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
+ disable_s2_shutdown = true;
+ else
+ dev_warn(chip->dev,
+- "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n");
++ "No ADC is configured and critical temperature %d mC is above the maximum stage 2 threshold of %ld mC! Configuring stage 2 shutdown at %ld mC.\n",
++ temp, stage2_threshold_max, stage2_threshold_max);
+ }
+
+ skip:
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 50d50cec77740..15fb5fa1b0f2c 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -903,10 +903,6 @@ __thermal_cooling_device_register(struct device_node *np,
+ cdev->id = ret;
+ id = ret;
+
+- ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
+- if (ret)
+- goto out_ida_remove;
+-
+ cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
+ if (!cdev->type) {
+ ret = -ENOMEM;
+@@ -921,6 +917,11 @@ __thermal_cooling_device_register(struct device_node *np,
+ cdev->device.class = &thermal_class;
+ cdev->devdata = devdata;
+ thermal_cooling_device_setup_sysfs(cdev);
++ ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
++ if (ret) {
++ thermal_cooling_device_destroy_sysfs(cdev);
++ goto out_kfree_type;
++ }
+ ret = device_register(&cdev->device);
+ if (ret)
+ goto out_kfree_type;
+@@ -1241,10 +1242,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ tz->id = id;
+ strlcpy(tz->type, type, sizeof(tz->type));
+
+- result = dev_set_name(&tz->device, "thermal_zone%d", tz->id);
+- if (result)
+- goto remove_id;
+-
+ if (!ops->critical)
+ ops->critical = thermal_zone_device_critical;
+
+@@ -1267,6 +1264,11 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ /* A new thermal zone needs to be updated anyway. */
+ atomic_set(&tz->need_update, 1);
+
++ result = dev_set_name(&tz->device, "thermal_zone%d", tz->id);
++ if (result) {
++ thermal_zone_destroy_device_groups(tz);
++ goto remove_id;
++ }
+ result = device_register(&tz->device);
+ if (result)
+ goto release_device;
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
+index 8efdc271eb75f..5e0ffd6c47892 100644
+--- a/drivers/tty/serial/8250/8250_bcm7271.c
++++ b/drivers/tty/serial/8250/8250_bcm7271.c
+@@ -1212,9 +1212,17 @@ static struct platform_driver brcmuart_platform_driver = {
+
+ static int __init brcmuart_init(void)
+ {
++ int ret;
++
+ brcmuart_debugfs_root = debugfs_create_dir(
+ brcmuart_platform_driver.driver.name, NULL);
+- return platform_driver_register(&brcmuart_platform_driver);
++ ret = platform_driver_register(&brcmuart_platform_driver);
++ if (ret) {
++ debugfs_remove_recursive(brcmuart_debugfs_root);
++ return ret;
++ }
++
++ return 0;
+ }
+ module_init(brcmuart_init);
+
+diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
+index 8b749ed557c67..191d737ea5632 100644
+--- a/drivers/tty/serial/altera_uart.c
++++ b/drivers/tty/serial/altera_uart.c
+@@ -199,9 +199,8 @@ static void altera_uart_set_termios(struct uart_port *port,
+ */
+ }
+
+-static void altera_uart_rx_chars(struct altera_uart *pp)
++static void altera_uart_rx_chars(struct uart_port *port)
+ {
+- struct uart_port *port = &pp->port;
+ unsigned char ch, flag;
+ unsigned short status;
+
+@@ -246,9 +245,8 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
+ tty_flip_buffer_push(&port->state->port);
+ }
+
+-static void altera_uart_tx_chars(struct altera_uart *pp)
++static void altera_uart_tx_chars(struct uart_port *port)
+ {
+- struct uart_port *port = &pp->port;
+ struct circ_buf *xmit = &port->state->xmit;
+
+ if (port->x_char) {
+@@ -272,26 +270,25 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+- if (xmit->head == xmit->tail) {
+- pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
+- altera_uart_update_ctrl_reg(pp);
+- }
++ if (uart_circ_empty(xmit))
++ altera_uart_stop_tx(port);
+ }
+
+ static irqreturn_t altera_uart_interrupt(int irq, void *data)
+ {
+ struct uart_port *port = data;
+ struct altera_uart *pp = container_of(port, struct altera_uart, port);
++ unsigned long flags;
+ unsigned int isr;
+
+ isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
+
+- spin_lock(&port->lock);
++ spin_lock_irqsave(&port->lock, flags);
+ if (isr & ALTERA_UART_STATUS_RRDY_MSK)
+- altera_uart_rx_chars(pp);
++ altera_uart_rx_chars(port);
+ if (isr & ALTERA_UART_STATUS_TRDY_MSK)
+- altera_uart_tx_chars(pp);
+- spin_unlock(&port->lock);
++ altera_uart_tx_chars(port);
++ spin_unlock_irqrestore(&port->lock, flags);
+
+ return IRQ_RETVAL(isr);
+ }
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 15f0e4d88c5a0..c211a1e92db7f 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1045,6 +1045,9 @@ static void pl011_dma_rx_callback(void *data)
+ */
+ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
+ {
++ if (!uap->using_rx_dma)
++ return;
++
+ /* FIXME. Just disable the DMA enable */
+ uap->dmacr &= ~UART011_RXDMAE;
+ pl011_write(uap->dmacr, uap, REG_DMACR);
+@@ -1828,8 +1831,17 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+ static void pl011_unthrottle_rx(struct uart_port *port)
+ {
+ struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
++ unsigned long flags;
+
+- pl011_enable_interrupts(uap);
++ spin_lock_irqsave(&uap->port.lock, flags);
++
++ uap->im = UART011_RTIM;
++ if (!pl011_dma_rx_running(uap))
++ uap->im |= UART011_RXIM;
++
++ pl011_write(uap->im, uap, REG_IMSC);
++
++ spin_unlock_irqrestore(&uap->port.lock, flags);
+ }
+
+ static int pl011_startup(struct uart_port *port)
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index 8a9065e4a903b..ec501c3ce033b 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -694,6 +694,7 @@ static void pch_request_dma(struct uart_port *port)
+ if (!chan) {
+ dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
+ __func__);
++ pci_dev_put(dma_dev);
+ return;
+ }
+ priv->chan_tx = chan;
+@@ -710,6 +711,7 @@ static void pch_request_dma(struct uart_port *port)
+ __func__);
+ dma_release_channel(priv->chan_tx);
+ priv->chan_tx = NULL;
++ pci_dev_put(dma_dev);
+ return;
+ }
+
+@@ -717,6 +719,8 @@ static void pch_request_dma(struct uart_port *port)
+ priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
+ &priv->rx_buf_dma, GFP_KERNEL);
+ priv->chan_rx = chan;
++
++ pci_dev_put(dma_dev);
+ }
+
+ static void pch_dma_rx_complete(void *arg)
+diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
+index a5748e41483ba..ab549b79fde90 100644
+--- a/drivers/tty/serial/serial-tegra.c
++++ b/drivers/tty/serial/serial-tegra.c
+@@ -619,8 +619,9 @@ static void tegra_uart_stop_tx(struct uart_port *u)
+ if (tup->tx_in_progress != TEGRA_UART_TX_DMA)
+ return;
+
+- dmaengine_terminate_all(tup->tx_dma_chan);
++ dmaengine_pause(tup->tx_dma_chan);
+ dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state);
++ dmaengine_terminate_all(tup->tx_dma_chan);
+ count = tup->tx_bytes_requested - state.residue;
+ async_tx_ack(tup->tx_dma_desc);
+ uart_xmit_advance(&tup->uport, count);
+@@ -763,8 +764,9 @@ static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup)
+ return;
+ }
+
+- dmaengine_terminate_all(tup->rx_dma_chan);
++ dmaengine_pause(tup->rx_dma_chan);
+ dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
++ dmaengine_terminate_all(tup->rx_dma_chan);
+
+ tegra_uart_rx_buffer_push(tup, state.residue);
+ tup->rx_dma_active = false;
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 9a875558f5ef6..1f8aad186908f 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -1681,22 +1681,10 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
+ if (!stm32port->info)
+ return -EINVAL;
+
+- ret = stm32_usart_init_port(stm32port, pdev);
+- if (ret)
+- return ret;
+-
+- if (stm32port->wakeup_src) {
+- device_set_wakeup_capable(&pdev->dev, true);
+- ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
+- if (ret)
+- goto err_deinit_port;
+- }
+-
+ stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx");
+- if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) {
+- ret = -EPROBE_DEFER;
+- goto err_wakeirq;
+- }
++ if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++
+ /* Fall back in interrupt mode for any non-deferral error */
+ if (IS_ERR(stm32port->rx_ch))
+ stm32port->rx_ch = NULL;
+@@ -1710,6 +1698,17 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
+ if (IS_ERR(stm32port->tx_ch))
+ stm32port->tx_ch = NULL;
+
++ ret = stm32_usart_init_port(stm32port, pdev);
++ if (ret)
++ goto err_dma_tx;
++
++ if (stm32port->wakeup_src) {
++ device_set_wakeup_capable(&pdev->dev, true);
++ ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
++ if (ret)
++ goto err_deinit_port;
++ }
++
+ if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) {
+ /* Fall back in interrupt mode */
+ dma_release_channel(stm32port->rx_ch);
+@@ -1746,19 +1745,11 @@ err_port:
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
+- if (stm32port->tx_ch) {
++ if (stm32port->tx_ch)
+ stm32_usart_of_dma_tx_remove(stm32port, pdev);
+- dma_release_channel(stm32port->tx_ch);
+- }
+-
+ if (stm32port->rx_ch)
+ stm32_usart_of_dma_rx_remove(stm32port, pdev);
+
+-err_dma_rx:
+- if (stm32port->rx_ch)
+- dma_release_channel(stm32port->rx_ch);
+-
+-err_wakeirq:
+ if (stm32port->wakeup_src)
+ dev_pm_clear_wake_irq(&pdev->dev);
+
+@@ -1768,6 +1759,14 @@ err_deinit_port:
+
+ stm32_usart_deinit_port(stm32port);
+
++err_dma_tx:
++ if (stm32port->tx_ch)
++ dma_release_channel(stm32port->tx_ch);
++
++err_dma_rx:
++ if (stm32port->rx_ch)
++ dma_release_channel(stm32port->rx_ch);
++
+ return ret;
+ }
+
+diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
+index 6ea52293d9f35..7c10715dace88 100644
+--- a/drivers/tty/serial/sunsab.c
++++ b/drivers/tty/serial/sunsab.c
+@@ -1137,7 +1137,13 @@ static int __init sunsab_init(void)
+ }
+ }
+
+- return platform_driver_register(&sab_driver);
++ err = platform_driver_register(&sab_driver);
++ if (err) {
++ kfree(sunsab_ports);
++ sunsab_ports = NULL;
++ }
++
++ return err;
+ }
+
+ static void __exit sunsab_exit(void)
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index a202d7d5240d8..bda89f988859e 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -5378,6 +5378,26 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
+ }
+ }
+
++/* Any value that is not an existing queue number is fine for this constant. */
++enum {
++ UFSHCD_POLL_FROM_INTERRUPT_CONTEXT = -1
++};
++
++static void ufshcd_clear_polled(struct ufs_hba *hba,
++ unsigned long *completed_reqs)
++{
++ int tag;
++
++ for_each_set_bit(tag, completed_reqs, hba->nutrs) {
++ struct scsi_cmnd *cmd = hba->lrb[tag].cmd;
++
++ if (!cmd)
++ continue;
++ if (scsi_cmd_to_rq(cmd)->cmd_flags & REQ_POLLED)
++ __clear_bit(tag, completed_reqs);
++ }
++}
++
+ /*
+ * Returns > 0 if one or more commands have been completed or 0 if no
+ * requests have been completed.
+@@ -5394,13 +5414,17 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
+ WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
+ "completed: %#lx; outstanding: %#lx\n", completed_reqs,
+ hba->outstanding_reqs);
++ if (queue_num == UFSHCD_POLL_FROM_INTERRUPT_CONTEXT) {
++ /* Do not complete polled requests from interrupt context. */
++ ufshcd_clear_polled(hba, &completed_reqs);
++ }
+ hba->outstanding_reqs &= ~completed_reqs;
+ spin_unlock_irqrestore(&hba->outstanding_lock, flags);
+
+ if (completed_reqs)
+ __ufshcd_transfer_req_compl(hba, completed_reqs);
+
+- return completed_reqs;
++ return completed_reqs != 0;
+ }
+
+ /**
+@@ -5431,7 +5455,7 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba)
+ * Ignore the ufshcd_poll() return value and return IRQ_HANDLED since we
+ * do not want polling to trigger spurious interrupt complaints.
+ */
+- ufshcd_poll(hba->host, 0);
++ ufshcd_poll(hba->host, UFSHCD_POLL_FROM_INTERRUPT_CONTEXT);
+
+ return IRQ_HANDLED;
+ }
+@@ -8741,8 +8765,6 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
+ struct scsi_device *sdp;
+ unsigned long flags;
+ int ret, retries;
+- unsigned long deadline;
+- int32_t remaining;
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ sdp = hba->ufs_device_wlun;
+@@ -8775,14 +8797,9 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
+ * callbacks hence set the RQF_PM flag so that it doesn't resume the
+ * already suspended childs.
+ */
+- deadline = jiffies + 10 * HZ;
+ for (retries = 3; retries > 0; --retries) {
+- ret = -ETIMEDOUT;
+- remaining = deadline - jiffies;
+- if (remaining <= 0)
+- break;
+ ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
+- remaining / HZ, 0, 0, RQF_PM, NULL);
++ HZ, 0, 0, RQF_PM, NULL);
+ if (!scsi_status_is_check_condition(ret) ||
+ !scsi_sense_valid(&sshdr) ||
+ sshdr.sense_key != UNIT_ATTENTION)
+diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
+index 1106f33764047..792c3e9c9ce53 100644
+--- a/drivers/uio/uio_dmem_genirq.c
++++ b/drivers/uio/uio_dmem_genirq.c
+@@ -110,8 +110,10 @@ static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info)
+ * remember the state so we can allow user space to enable it later.
+ */
+
++ spin_lock(&priv->lock);
+ if (!test_and_set_bit(0, &priv->flags))
+ disable_irq_nosync(irq);
++ spin_unlock(&priv->lock);
+
+ return IRQ_HANDLED;
+ }
+@@ -125,20 +127,19 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+ * in the interrupt controller, but keep track of the
+ * state to prevent per-irq depth damage.
+ *
+- * Serialize this operation to support multiple tasks.
++ * Serialize this operation to support multiple tasks and concurrency
++ * with irq handler on SMP systems.
+ */
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (irq_on) {
+ if (test_and_clear_bit(0, &priv->flags))
+ enable_irq(dev_info->irq);
+- spin_unlock_irqrestore(&priv->lock, flags);
+ } else {
+- if (!test_and_set_bit(0, &priv->flags)) {
+- spin_unlock_irqrestore(&priv->lock, flags);
+- disable_irq(dev_info->irq);
+- }
++ if (!test_and_set_bit(0, &priv->flags))
++ disable_irq_nosync(dev_info->irq);
+ }
++ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+ }
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 2f29431f612e0..b23e543b3a3d5 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -2006,10 +2006,11 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+
+ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ {
+- u32 field, length_field, remainder;
++ u32 field, length_field, zlp = 0;
+ struct cdnsp_ep *pep = preq->pep;
+ struct cdnsp_ring *ep_ring;
+ int num_trbs;
++ u32 maxp;
+ int ret;
+
+ ep_ring = cdnsp_request_to_transfer_ring(pdev, preq);
+@@ -2019,26 +2020,33 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ /* 1 TRB for data, 1 for status */
+ num_trbs = (pdev->three_stage_setup) ? 2 : 1;
+
++ maxp = usb_endpoint_maxp(pep->endpoint.desc);
++
++ if (preq->request.zero && preq->request.length &&
++ (preq->request.length % maxp == 0)) {
++ num_trbs++;
++ zlp = 1;
++ }
++
+ ret = cdnsp_prepare_transfer(pdev, preq, num_trbs);
+ if (ret)
+ return ret;
+
+ /* If there's data, queue data TRBs */
+- if (pdev->ep0_expect_in)
+- field = TRB_TYPE(TRB_DATA) | TRB_IOC;
+- else
+- field = TRB_ISP | TRB_TYPE(TRB_DATA) | TRB_IOC;
+-
+ if (preq->request.length > 0) {
+- remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
+- preq->request.length, preq, 1, 0);
++ field = TRB_TYPE(TRB_DATA);
+
+- length_field = TRB_LEN(preq->request.length) |
+- TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
++ if (zlp)
++ field |= TRB_CHAIN;
++ else
++ field |= TRB_IOC | (pdev->ep0_expect_in ? 0 : TRB_ISP);
+
+ if (pdev->ep0_expect_in)
+ field |= TRB_DIR_IN;
+
++ length_field = TRB_LEN(preq->request.length) |
++ TRB_TD_SIZE(zlp) | TRB_INTR_TARGET(0);
++
+ cdnsp_queue_trb(pdev, ep_ring, true,
+ lower_32_bits(preq->request.dma),
+ upper_32_bits(preq->request.dma), length_field,
+@@ -2046,6 +2054,20 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ TRB_SETUPID(pdev->setup_id) |
+ pdev->setup_speed);
+
++ if (zlp) {
++ field = TRB_TYPE(TRB_NORMAL) | TRB_IOC;
++
++ if (!pdev->ep0_expect_in)
++ field = TRB_ISP;
++
++ cdnsp_queue_trb(pdev, ep_ring, true,
++ lower_32_bits(preq->request.dma),
++ upper_32_bits(preq->request.dma), 0,
++ field | ep_ring->cycle_state |
++ TRB_SETUPID(pdev->setup_id) |
++ pdev->setup_speed);
++ }
++
+ pdev->ep0_stage = CDNSP_DATA_STAGE;
+ }
+
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 94b305bbd621b..4bd9d799f1b97 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -3140,8 +3140,12 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
+ GFP_KERNEL,
+ DMA_ATTR_WRITE_COMBINE);
+
+- if (IS_ERR(local_mem))
++ if (IS_ERR_OR_NULL(local_mem)) {
++ if (!local_mem)
++ return -ENOMEM;
++
+ return PTR_ERR(local_mem);
++ }
+
+ /*
+ * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 038140b1de37b..07780148ebedb 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -122,21 +122,25 @@ static void __dwc3_set_mode(struct work_struct *work)
+ unsigned long flags;
+ int ret;
+ u32 reg;
++ u32 desired_dr_role;
+
+ mutex_lock(&dwc->mutex);
++ spin_lock_irqsave(&dwc->lock, flags);
++ desired_dr_role = dwc->desired_dr_role;
++ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ pm_runtime_get_sync(dwc->dev);
+
+ if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
+ dwc3_otg_update(dwc, 0);
+
+- if (!dwc->desired_dr_role)
++ if (!desired_dr_role)
+ goto out;
+
+- if (dwc->desired_dr_role == dwc->current_dr_role)
++ if (desired_dr_role == dwc->current_dr_role)
+ goto out;
+
+- if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
++ if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
+ goto out;
+
+ switch (dwc->current_dr_role) {
+@@ -164,7 +168,7 @@ static void __dwc3_set_mode(struct work_struct *work)
+ */
+ if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
+ DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
+- dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
++ desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg |= DWC3_GCTL_CORESOFTRESET;
+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+@@ -184,11 +188,11 @@ static void __dwc3_set_mode(struct work_struct *work)
+
+ spin_lock_irqsave(&dwc->lock, flags);
+
+- dwc3_set_prtcap(dwc, dwc->desired_dr_role);
++ dwc3_set_prtcap(dwc, desired_dr_role);
+
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+- switch (dwc->desired_dr_role) {
++ switch (desired_dr_role) {
+ case DWC3_GCTL_PRTCAP_HOST:
+ ret = dwc3_host_init(dwc);
+ if (ret) {
+@@ -1096,8 +1100,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
+
+ if (!dwc->ulpi_ready) {
+ ret = dwc3_core_ulpi_init(dwc);
+- if (ret)
++ if (ret) {
++ if (ret == -ETIMEDOUT) {
++ dwc3_core_soft_reset(dwc);
++ ret = -EPROBE_DEFER;
++ }
+ goto err0;
++ }
+ dwc->ulpi_ready = true;
+ }
+
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index ca0a7d9eaa34e..6be6009f911e1 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -71,7 +71,7 @@ struct f_hidg {
+ wait_queue_head_t write_queue;
+ struct usb_request *req;
+
+- int minor;
++ struct device dev;
+ struct cdev cdev;
+ struct usb_function func;
+
+@@ -84,6 +84,14 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f)
+ return container_of(f, struct f_hidg, func);
+ }
+
++static void hidg_release(struct device *dev)
++{
++ struct f_hidg *hidg = container_of(dev, struct f_hidg, dev);
++
++ kfree(hidg->set_report_buf);
++ kfree(hidg);
++}
++
+ /*-------------------------------------------------------------------------*/
+ /* Static descriptors */
+
+@@ -904,9 +912,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+ struct usb_ep *ep;
+ struct f_hidg *hidg = func_to_hidg(f);
+ struct usb_string *us;
+- struct device *device;
+ int status;
+- dev_t dev;
+
+ /* maybe allocate device-global string IDs, and patch descriptors */
+ us = usb_gstrings_attach(c->cdev, ct_func_strings,
+@@ -999,21 +1005,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+
+ /* create char device */
+ cdev_init(&hidg->cdev, &f_hidg_fops);
+- dev = MKDEV(major, hidg->minor);
+- status = cdev_add(&hidg->cdev, dev, 1);
++ status = cdev_device_add(&hidg->cdev, &hidg->dev);
+ if (status)
+ goto fail_free_descs;
+
+- device = device_create(hidg_class, NULL, dev, NULL,
+- "%s%d", "hidg", hidg->minor);
+- if (IS_ERR(device)) {
+- status = PTR_ERR(device);
+- goto del;
+- }
+-
+ return 0;
+-del:
+- cdev_del(&hidg->cdev);
+ fail_free_descs:
+ usb_free_all_descriptors(f);
+ fail:
+@@ -1244,9 +1240,7 @@ static void hidg_free(struct usb_function *f)
+
+ hidg = func_to_hidg(f);
+ opts = container_of(f->fi, struct f_hid_opts, func_inst);
+- kfree(hidg->report_desc);
+- kfree(hidg->set_report_buf);
+- kfree(hidg);
++ put_device(&hidg->dev);
+ mutex_lock(&opts->lock);
+ --opts->refcnt;
+ mutex_unlock(&opts->lock);
+@@ -1256,8 +1250,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+ struct f_hidg *hidg = func_to_hidg(f);
+
+- device_destroy(hidg_class, MKDEV(major, hidg->minor));
+- cdev_del(&hidg->cdev);
++ cdev_device_del(&hidg->cdev, &hidg->dev);
+
+ usb_free_all_descriptors(f);
+ }
+@@ -1266,6 +1259,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+ {
+ struct f_hidg *hidg;
+ struct f_hid_opts *opts;
++ int ret;
+
+ /* allocate and initialize one new instance */
+ hidg = kzalloc(sizeof(*hidg), GFP_KERNEL);
+@@ -1277,17 +1271,28 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+ mutex_lock(&opts->lock);
+ ++opts->refcnt;
+
+- hidg->minor = opts->minor;
++ device_initialize(&hidg->dev);
++ hidg->dev.release = hidg_release;
++ hidg->dev.class = hidg_class;
++ hidg->dev.devt = MKDEV(major, opts->minor);
++ ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
++ if (ret) {
++ --opts->refcnt;
++ mutex_unlock(&opts->lock);
++ return ERR_PTR(ret);
++ }
++
+ hidg->bInterfaceSubClass = opts->subclass;
+ hidg->bInterfaceProtocol = opts->protocol;
+ hidg->report_length = opts->report_length;
+ hidg->report_desc_length = opts->report_desc_length;
+ if (opts->report_desc) {
+- hidg->report_desc = kmemdup(opts->report_desc,
+- opts->report_desc_length,
+- GFP_KERNEL);
++ hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc,
++ opts->report_desc_length,
++ GFP_KERNEL);
+ if (!hidg->report_desc) {
+- kfree(hidg);
++ put_device(&hidg->dev);
++ --opts->refcnt;
+ mutex_unlock(&opts->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index c63c0c2cf649d..bf9878e1a72a8 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -734,13 +734,13 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
+ }
+
+ ret = gadget->ops->pullup(gadget, 0);
+- if (!ret) {
++ if (!ret)
+ gadget->connected = 0;
+- mutex_lock(&udc_lock);
+- if (gadget->udc->driver)
+- gadget->udc->driver->disconnect(gadget);
+- mutex_unlock(&udc_lock);
+- }
++
++ mutex_lock(&udc_lock);
++ if (gadget->udc->driver)
++ gadget->udc->driver->disconnect(gadget);
++ mutex_unlock(&udc_lock);
+
+ out:
+ trace_usb_gadget_disconnect(gadget, ret);
+diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c
+index fdca28e72a3b4..d0e051beb3af9 100644
+--- a/drivers/usb/gadget/udc/fotg210-udc.c
++++ b/drivers/usb/gadget/udc/fotg210-udc.c
+@@ -629,10 +629,10 @@ static void fotg210_request_error(struct fotg210_udc *fotg210)
+ static void fotg210_set_address(struct fotg210_udc *fotg210,
+ struct usb_ctrlrequest *ctrl)
+ {
+- if (ctrl->wValue >= 0x0100) {
++ if (le16_to_cpu(ctrl->wValue) >= 0x0100) {
+ fotg210_request_error(fotg210);
+ } else {
+- fotg210_set_dev_addr(fotg210, ctrl->wValue);
++ fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue));
+ fotg210_set_cxdone(fotg210);
+ }
+ }
+@@ -713,17 +713,17 @@ static void fotg210_get_status(struct fotg210_udc *fotg210,
+
+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+- fotg210->ep0_data = 1 << USB_DEVICE_SELF_POWERED;
++ fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED);
+ break;
+ case USB_RECIP_INTERFACE:
+- fotg210->ep0_data = 0;
++ fotg210->ep0_data = cpu_to_le16(0);
+ break;
+ case USB_RECIP_ENDPOINT:
+ epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
+ if (epnum)
+ fotg210->ep0_data =
+- fotg210_is_epnstall(fotg210->ep[epnum])
+- << USB_ENDPOINT_HALT;
++ cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum])
++ << USB_ENDPOINT_HALT);
+ else
+ fotg210_request_error(fotg210);
+ break;
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 01705e559c422..c61fc19ef1154 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -639,7 +639,6 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+
+ dealloc_usb3_hcd:
+ usb_remove_hcd(xhci->shared_hcd);
+- xhci->shared_hcd = NULL;
+
+ dealloc_usb2_hcd:
+ usb_remove_hcd(hcd);
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index ad81e9a508b14..343709af4c16f 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2458,7 +2458,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+
+ switch (trb_comp_code) {
+ case COMP_SUCCESS:
+- ep_ring->err_count = 0;
++ ep->err_count = 0;
+ /* handle success with untransferred data as short packet */
+ if (ep_trb != td->last_trb || remaining) {
+ xhci_warn(xhci, "WARN Successful completion on short TX\n");
+@@ -2484,7 +2484,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+ break;
+ case COMP_USB_TRANSACTION_ERROR:
+ if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
+- (ep_ring->err_count++ > MAX_SOFT_RETRY) ||
++ (ep->err_count++ > MAX_SOFT_RETRY) ||
+ le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
+ break;
+
+@@ -2565,8 +2565,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ case COMP_USB_TRANSACTION_ERROR:
+ case COMP_INVALID_STREAM_TYPE_ERROR:
+ case COMP_INVALID_STREAM_ID_ERROR:
+- xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
+- EP_SOFT_RESET);
++ xhci_dbg(xhci, "Stream transaction error ep %u no id\n",
++ ep_index);
++ if (ep->err_count++ > MAX_SOFT_RETRY)
++ xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
++ EP_HARD_RESET);
++ else
++ xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
++ EP_SOFT_RESET);
+ goto cleanup;
+ case COMP_RING_UNDERRUN:
+ case COMP_RING_OVERRUN:
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index a6daf37ff4bf7..38941554ec55c 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -933,6 +933,7 @@ struct xhci_virt_ep {
+ * have to restore the device state to the previous state
+ */
+ struct xhci_ring *new_ring;
++ unsigned int err_count;
+ unsigned int ep_state;
+ #define SET_DEQ_PENDING (1 << 0)
+ #define EP_HALTED (1 << 1) /* For stall handling */
+@@ -1627,7 +1628,6 @@ struct xhci_ring {
+ * if we own the TRB (if we are the consumer). See section 4.9.1.
+ */
+ u32 cycle_state;
+- unsigned int err_count;
+ unsigned int stream_id;
+ unsigned int num_segs;
+ unsigned int num_trbs_free;
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index 6704a62a16659..ba20272d22215 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1628,8 +1628,6 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+ {
+ struct musb *musb = gadget_to_musb(gadget);
+
+- if (!musb->xceiv->set_power)
+- return -EOPNOTSUPP;
+ return usb_phy_set_power(musb->xceiv, mA);
+ }
+
+diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
+index f571a65ae6ee2..476f55d1fec30 100644
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -15,6 +15,7 @@
+ #include <linux/list.h>
+ #include <linux/io.h>
+ #include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/pm_runtime.h>
+@@ -310,6 +311,7 @@ static int omap2430_probe(struct platform_device *pdev)
+ struct device_node *control_node;
+ struct platform_device *control_pdev;
+ int ret = -ENOMEM, val;
++ bool populate_irqs = false;
+
+ if (!np)
+ return -ENODEV;
+@@ -328,6 +330,18 @@ static int omap2430_probe(struct platform_device *pdev)
+ musb->dev.dma_mask = &omap2430_dmamask;
+ musb->dev.coherent_dma_mask = omap2430_dmamask;
+
++ /*
++ * Legacy SoCs using omap_device get confused if node is moved
++ * because of interconnect properties mixed into the node.
++ */
++ if (of_get_property(np, "ti,hwmods", NULL)) {
++ dev_warn(&pdev->dev, "please update to probe with ti-sysc\n");
++ populate_irqs = true;
++ } else {
++ device_set_of_node_from_dev(&musb->dev, &pdev->dev);
++ }
++ of_node_put(np);
++
+ glue->dev = &pdev->dev;
+ glue->musb = musb;
+ glue->status = MUSB_UNKNOWN;
+@@ -389,6 +403,46 @@ static int omap2430_probe(struct platform_device *pdev)
+ goto err2;
+ }
+
++ if (populate_irqs) {
++ struct resource musb_res[3];
++ struct resource *res;
++ int i = 0;
++
++ memset(musb_res, 0, sizeof(*musb_res) * ARRAY_SIZE(musb_res));
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res)
++ goto err2;
++
++ musb_res[i].start = res->start;
++ musb_res[i].end = res->end;
++ musb_res[i].flags = res->flags;
++ musb_res[i].name = res->name;
++ i++;
++
++ ret = of_irq_get_byname(np, "mc");
++ if (ret > 0) {
++ musb_res[i].start = ret;
++ musb_res[i].flags = IORESOURCE_IRQ;
++ musb_res[i].name = "mc";
++ i++;
++ }
++
++ ret = of_irq_get_byname(np, "dma");
++ if (ret > 0) {
++ musb_res[i].start = ret;
++ musb_res[i].flags = IORESOURCE_IRQ;
++ musb_res[i].name = "dma";
++ i++;
++ }
++
++ ret = platform_device_add_resources(musb, musb_res, i);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to add IRQ resources\n");
++ goto err2;
++ }
++ }
++
+ ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform_data\n");
+diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
+index dfaed7eee94fc..32e6d19f7011a 100644
+--- a/drivers/usb/roles/class.c
++++ b/drivers/usb/roles/class.c
+@@ -106,10 +106,13 @@ usb_role_switch_is_parent(struct fwnode_handle *fwnode)
+ struct fwnode_handle *parent = fwnode_get_parent(fwnode);
+ struct device *dev;
+
+- if (!parent || !fwnode_property_present(parent, "usb-role-switch"))
++ if (!fwnode_property_present(parent, "usb-role-switch")) {
++ fwnode_handle_put(parent);
+ return NULL;
++ }
+
+ dev = class_find_device_by_fwnode(role_class, parent);
++ fwnode_handle_put(parent);
+ return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
+ }
+
+diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
+index 747be69e5e699..5e912dd29b4c9 100644
+--- a/drivers/usb/storage/alauda.c
++++ b/drivers/usb/storage/alauda.c
+@@ -438,6 +438,8 @@ static int alauda_init_media(struct us_data *us)
+ + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+ MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+ MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
++ if (MEDIA_INFO(us).pba_to_lba == NULL || MEDIA_INFO(us).lba_to_pba == NULL)
++ return USB_STOR_TRANSPORT_ERROR;
+
+ if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
+index 26ea2fdec17dc..31c2a3130cadb 100644
+--- a/drivers/usb/typec/bus.c
++++ b/drivers/usb/typec/bus.c
+@@ -134,7 +134,7 @@ int typec_altmode_exit(struct typec_altmode *adev)
+ if (!adev || !adev->active)
+ return 0;
+
+- if (!pdev->ops || !pdev->ops->enter)
++ if (!pdev->ops || !pdev->ops->exit)
+ return -EOPNOTSUPP;
+
+ /* Moving to USB Safe State */
+diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
+index 812784702d539..592bd4c854822 100644
+--- a/drivers/usb/typec/tcpm/tcpci.c
++++ b/drivers/usb/typec/tcpm/tcpci.c
+@@ -816,8 +816,10 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
+ return ERR_PTR(err);
+
+ tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
+- if (IS_ERR(tcpci->port))
++ if (IS_ERR(tcpci->port)) {
++ fwnode_handle_put(tcpci->tcpc.fwnode);
+ return ERR_CAST(tcpci->port);
++ }
+
+ return tcpci;
+ }
+@@ -826,6 +828,7 @@ EXPORT_SYMBOL_GPL(tcpci_register_port);
+ void tcpci_unregister_port(struct tcpci *tcpci)
+ {
+ tcpm_unregister_port(tcpci->port);
++ fwnode_handle_put(tcpci->tcpc.fwnode);
+ }
+ EXPORT_SYMBOL_GPL(tcpci_unregister_port);
+
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index 92e35e62e78c2..513ac7e141a4b 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -814,20 +814,19 @@ static int tps6598x_probe(struct i2c_client *client)
+
+ ret = devm_tps6598_psy_register(tps);
+ if (ret)
+- return ret;
++ goto err_role_put;
+
+ tps->port = typec_register_port(&client->dev, &typec_cap);
+ if (IS_ERR(tps->port)) {
+ ret = PTR_ERR(tps->port);
+ goto err_role_put;
+ }
+- fwnode_handle_put(fwnode);
+
+ if (status & TPS_STATUS_PLUG_PRESENT) {
+ ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status);
+ if (ret < 0) {
+ dev_err(tps->dev, "failed to read power status: %d\n", ret);
+- goto err_role_put;
++ goto err_unregister_port;
+ }
+ ret = tps6598x_connect(tps, status);
+ if (ret)
+@@ -840,14 +839,16 @@ static int tps6598x_probe(struct i2c_client *client)
+ dev_name(&client->dev), tps);
+ if (ret) {
+ tps6598x_disconnect(tps, 0);
+- typec_unregister_port(tps->port);
+- goto err_role_put;
++ goto err_unregister_port;
+ }
+
+ i2c_set_clientdata(client, tps);
++ fwnode_handle_put(fwnode);
+
+ return 0;
+
++err_unregister_port:
++ typec_unregister_port(tps->port);
+ err_role_put:
+ usb_role_switch_put(tps->role_sw);
+ err_fwnode_put:
+diff --git a/drivers/usb/typec/wusb3801.c b/drivers/usb/typec/wusb3801.c
+index e63509f8b01ed..8e38f5d2ec896 100644
+--- a/drivers/usb/typec/wusb3801.c
++++ b/drivers/usb/typec/wusb3801.c
+@@ -364,7 +364,7 @@ static int wusb3801_probe(struct i2c_client *client)
+ /* Initialize the hardware with the devicetree settings. */
+ ret = wusb3801_hw_init(wusb3801);
+ if (ret)
+- return ret;
++ goto err_put_connector;
+
+ wusb3801->cap.revision = USB_TYPEC_REV_1_2;
+ wusb3801->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO;
+diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
+index 256f55b84e70a..a8d374205a0e0 100644
+--- a/drivers/vfio/platform/vfio_platform_common.c
++++ b/drivers/vfio/platform/vfio_platform_common.c
+@@ -72,12 +72,11 @@ static int vfio_platform_acpi_call_reset(struct vfio_platform_device *vdev,
+ const char **extra_dbg)
+ {
+ #ifdef CONFIG_ACPI
+- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct device *dev = vdev->device;
+ acpi_handle handle = ACPI_HANDLE(dev);
+ acpi_status acpi_ret;
+
+- acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, &buffer);
++ acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, NULL);
+ if (ACPI_FAILURE(acpi_ret)) {
+ if (extra_dbg)
+ *extra_dbg = acpi_format_exception(acpi_ret);
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index cfc55273dc5d1..974e862cd20d6 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -601,6 +601,7 @@ config FB_TGA
+ config FB_UVESA
+ tristate "Userspace VESA VGA graphics support"
+ depends on FB && CONNECTOR
++ depends on !UML
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+@@ -2217,7 +2218,6 @@ config FB_SSD1307
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_DEFERRED_IO
+- select PWM
+ select FB_BACKLIGHT
+ help
+ This driver implements support for the Solomon SSD1307
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index c0143d38df83a..14a7d404062c3 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2450,7 +2450,8 @@ err_out:
+
+ if (userfont) {
+ p->userfont = old_userfont;
+- REFCOUNT(data)--;
++ if (--REFCOUNT(data) == 0)
++ kfree(data - FONT_EXTRA_WORDS * sizeof(int));
+ }
+
+ vc->vc_font.width = old_width;
+diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
+index 2398b3d48fedf..305f1587bd898 100644
+--- a/drivers/video/fbdev/ep93xx-fb.c
++++ b/drivers/video/fbdev/ep93xx-fb.c
+@@ -552,12 +552,14 @@ static int ep93xxfb_probe(struct platform_device *pdev)
+
+ err = register_framebuffer(info);
+ if (err)
+- goto failed_check;
++ goto failed_framebuffer;
+
+ dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
+ info->var.xres, info->var.yres, info->var.bits_per_pixel);
+ return 0;
+
++failed_framebuffer:
++ clk_disable_unprepare(fbi->clk);
+ failed_check:
+ if (fbi->mach_info->teardown)
+ fbi->mach_info->teardown(pdev);
+diff --git a/drivers/video/fbdev/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig
+index ac9c860592aaf..85bc14b6faf64 100644
+--- a/drivers/video/fbdev/geode/Kconfig
++++ b/drivers/video/fbdev/geode/Kconfig
+@@ -5,6 +5,7 @@
+ config FB_GEODE
+ bool "AMD Geode family framebuffer support"
+ depends on FB && PCI && (X86_32 || (X86 && COMPILE_TEST))
++ depends on !UML
+ help
+ Say 'Y' here to allow you to select framebuffer drivers for
+ the AMD Geode family of processors.
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index b58b445bb529b..0839ba7d3a345 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -779,12 +779,18 @@ static void hvfb_ondemand_refresh_throttle(struct hvfb_par *par,
+ static int hvfb_on_panic(struct notifier_block *nb,
+ unsigned long e, void *p)
+ {
++ struct hv_device *hdev;
+ struct hvfb_par *par;
+ struct fb_info *info;
+
+ par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
+- par->synchronous_fb = true;
+ info = par->info;
++ hdev = device_to_hv_device(info->device);
++
++ if (hv_ringbuffer_spinlock_busy(hdev->channel))
++ return NOTIFY_DONE;
++
++ par->synchronous_fb = true;
+ if (par->need_docopy)
+ hvfb_docopy(par, 0, dio_fb_size);
+ synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
+diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
+index 8fd79deb1e2ae..94f1f33f88f99 100644
+--- a/drivers/video/fbdev/pm2fb.c
++++ b/drivers/video/fbdev/pm2fb.c
+@@ -1528,8 +1528,10 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ }
+
+ info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
+- if (!info)
+- return -ENOMEM;
++ if (!info) {
++ err = -ENOMEM;
++ goto err_exit_disable;
++ }
+ default_par = info->par;
+
+ switch (pdev->device) {
+@@ -1710,6 +1712,8 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+ err_exit_neither:
+ framebuffer_release(info);
++ err_exit_disable:
++ pci_disable_device(pdev);
+ return retval;
+ }
+
+@@ -1734,6 +1738,7 @@ static void pm2fb_remove(struct pci_dev *pdev)
+ fb_dealloc_cmap(&info->cmap);
+ kfree(info->pixmap.addr);
+ framebuffer_release(info);
++ pci_disable_device(pdev);
+ }
+
+ static const struct pci_device_id pm2fb_id_table[] = {
+diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
+index 4df6772802d78..1f3b7e013568c 100644
+--- a/drivers/video/fbdev/uvesafb.c
++++ b/drivers/video/fbdev/uvesafb.c
+@@ -1758,6 +1758,7 @@ static int uvesafb_probe(struct platform_device *dev)
+ out_unmap:
+ iounmap(info->screen_base);
+ out_mem:
++ arch_phys_wc_del(par->mtrr_handle);
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ out_reg:
+ release_region(0x3c0, 32);
+diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
+index ff61605b8764f..a543643ce014d 100644
+--- a/drivers/video/fbdev/vermilion/vermilion.c
++++ b/drivers/video/fbdev/vermilion/vermilion.c
+@@ -277,8 +277,10 @@ static int vmlfb_get_gpu(struct vml_par *par)
+
+ mutex_unlock(&vml_mutex);
+
+- if (pci_enable_device(par->gpu) < 0)
++ if (pci_enable_device(par->gpu) < 0) {
++ pci_dev_put(par->gpu);
+ return -ENODEV;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/video/fbdev/via/via-core.c b/drivers/video/fbdev/via/via-core.c
+index 89d75079b7307..0363b478fa3ef 100644
+--- a/drivers/video/fbdev/via/via-core.c
++++ b/drivers/video/fbdev/via/via-core.c
+@@ -725,7 +725,14 @@ static int __init via_core_init(void)
+ return ret;
+ viafb_i2c_init();
+ viafb_gpio_init();
+- return pci_register_driver(&via_driver);
++ ret = pci_register_driver(&via_driver);
++ if (ret) {
++ viafb_gpio_exit();
++ viafb_i2c_exit();
++ return ret;
++ }
++
++ return 0;
+ }
+
+ static void __exit via_core_exit(void)
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index 1ea6d2e5b2187..99d6062afe72f 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -800,3 +800,4 @@ MODULE_AUTHOR("Brijesh Singh <brijesh.singh@amd.com>");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION("1.0.0");
+ MODULE_DESCRIPTION("AMD SEV Guest Driver");
++MODULE_ALIAS("platform:sev-guest");
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index 34693f11385f6..e937b4dd28be7 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -423,14 +423,18 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
+ return time_left;
+ }
+
+-static void iTCO_wdt_set_running(struct iTCO_wdt_private *p)
++/* Returns true if the watchdog was running */
++static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p)
+ {
+ u16 val;
+
+- /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is * enabled */
++ /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */
+ val = inw(TCO1_CNT(p));
+- if (!(val & BIT(11)))
++ if (!(val & BIT(11))) {
+ set_bit(WDOG_HW_RUNNING, &p->wddev.status);
++ return true;
++ }
++ return false;
+ }
+
+ /*
+@@ -518,9 +522,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
+ return -ENODEV; /* Cannot reset NO_REBOOT bit */
+ }
+
+- /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+- p->update_no_reboot_bit(p->no_reboot_priv, true);
+-
+ if (turn_SMI_watchdog_clear_off >= p->iTCO_version) {
+ /*
+ * Bit 13: TCO_EN -> 0
+@@ -572,7 +573,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
+ watchdog_set_drvdata(&p->wddev, p);
+ platform_set_drvdata(pdev, p);
+
+- iTCO_wdt_set_running(p);
++ if (!iTCO_wdt_set_running(p)) {
++ /*
++ * If the watchdog was not running set NO_REBOOT now to
++ * prevent later reboots.
++ */
++ p->update_no_reboot_bit(p->no_reboot_priv, true);
++ }
+
+ /* Check that the heartbeat value is within it's range;
+ if not reset to the default */
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
+index e88e8f6f0a334..719c5d1dda274 100644
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -760,7 +760,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
+ goto out;
+ }
+
+- pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL);
++ pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL | __GFP_NOWARN);
+ if (!pfns) {
+ rc = -ENOMEM;
+ goto out;
+diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c
+index 3ac5fcf98d0d6..daaf3810cc925 100644
+--- a/fs/afs/fs_probe.c
++++ b/fs/afs/fs_probe.c
+@@ -366,12 +366,15 @@ void afs_fs_probe_dispatcher(struct work_struct *work)
+ unsigned long nowj, timer_at, poll_at;
+ bool first_pass = true, set_timer = false;
+
+- if (!net->live)
++ if (!net->live) {
++ afs_dec_servers_outstanding(net);
+ return;
++ }
+
+ _enter("");
+
+ if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) {
++ afs_dec_servers_outstanding(net);
+ _leave(" [none]");
+ return;
+ }
+diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
+index e1eae7ea823ae..bb202ad369d53 100644
+--- a/fs/binfmt_misc.c
++++ b/fs/binfmt_misc.c
+@@ -44,10 +44,10 @@ static LIST_HEAD(entries);
+ static int enabled = 1;
+
+ enum {Enabled, Magic};
+-#define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
+-#define MISC_FMT_OPEN_BINARY (1 << 30)
+-#define MISC_FMT_CREDENTIALS (1 << 29)
+-#define MISC_FMT_OPEN_FILE (1 << 28)
++#define MISC_FMT_PRESERVE_ARGV0 (1UL << 31)
++#define MISC_FMT_OPEN_BINARY (1UL << 30)
++#define MISC_FMT_CREDENTIALS (1UL << 29)
++#define MISC_FMT_OPEN_FILE (1UL << 28)
+
+ typedef struct {
+ struct list_head list;
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index db7c6d22190de..3f6c355356044 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -880,7 +880,10 @@ next_slot:
+ args->start - extent_offset,
+ 0, false);
+ ret = btrfs_inc_extent_ref(trans, &ref);
+- BUG_ON(ret); /* -ENOMEM */
++ if (ret) {
++ btrfs_abort_transaction(trans, ret);
++ break;
++ }
+ }
+ key.offset = args->start;
+ }
+@@ -967,7 +970,10 @@ delete_extent_item:
+ key.offset - extent_offset, 0,
+ false);
+ ret = btrfs_free_extent(trans, &ref);
+- BUG_ON(ret); /* -ENOMEM */
++ if (ret) {
++ btrfs_abort_transaction(trans, ret);
++ break;
++ }
+ args->bytes_found += extent_end - key.offset;
+ }
+
+diff --git a/fs/char_dev.c b/fs/char_dev.c
+index ba0ded7842a77..3f667292608c0 100644
+--- a/fs/char_dev.c
++++ b/fs/char_dev.c
+@@ -547,7 +547,7 @@ int cdev_device_add(struct cdev *cdev, struct device *dev)
+ }
+
+ rc = device_add(dev);
+- if (rc)
++ if (rc && dev->devt)
+ cdev_del(cdev);
+
+ return rc;
+diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
+index 46f5718754f94..d848bc0aac274 100644
+--- a/fs/cifs/cifsencrypt.c
++++ b/fs/cifs/cifsencrypt.c
+@@ -679,7 +679,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
+ unlock:
+ cifs_server_unlock(ses->server);
+ setup_ntlmv2_rsp_ret:
+- kfree(tiblob);
++ kfree_sensitive(tiblob);
+
+ return rc;
+ }
+@@ -753,14 +753,14 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
+ server->secmech.ccmaesdecrypt = NULL;
+ }
+
+- kfree(server->secmech.sdesccmacaes);
++ kfree_sensitive(server->secmech.sdesccmacaes);
+ server->secmech.sdesccmacaes = NULL;
+- kfree(server->secmech.sdeschmacsha256);
++ kfree_sensitive(server->secmech.sdeschmacsha256);
+ server->secmech.sdeschmacsha256 = NULL;
+- kfree(server->secmech.sdeschmacmd5);
++ kfree_sensitive(server->secmech.sdeschmacmd5);
+ server->secmech.sdeschmacmd5 = NULL;
+- kfree(server->secmech.sdescmd5);
++ kfree_sensitive(server->secmech.sdescmd5);
+ server->secmech.sdescmd5 = NULL;
+- kfree(server->secmech.sdescsha512);
++ kfree_sensitive(server->secmech.sdescsha512);
+ server->secmech.sdescsha512 = NULL;
+ }
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index ccad85feb24e8..712a431614480 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -396,6 +396,7 @@ cifs_alloc_inode(struct super_block *sb)
+ cifs_inode->epoch = 0;
+ spin_lock_init(&cifs_inode->open_file_lock);
+ generate_random_uuid(cifs_inode->lease_key);
++ cifs_inode->symlink_target = NULL;
+
+ /*
+ * Can not set i_flags here - they get immediately overwritten to zero
+@@ -412,7 +413,11 @@ cifs_alloc_inode(struct super_block *sb)
+ static void
+ cifs_free_inode(struct inode *inode)
+ {
+- kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
++ struct cifsInodeInfo *cinode = CIFS_I(inode);
++
++ if (S_ISLNK(inode->i_mode))
++ kfree(cinode->symlink_target);
++ kmem_cache_free(cifs_inode_cachep, cinode);
+ }
+
+ static void
+@@ -1138,6 +1143,30 @@ const struct inode_operations cifs_file_inode_ops = {
+ .fiemap = cifs_fiemap,
+ };
+
++const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
++ struct delayed_call *done)
++{
++ char *target_path;
++
++ target_path = kmalloc(PATH_MAX, GFP_KERNEL);
++ if (!target_path)
++ return ERR_PTR(-ENOMEM);
++
++ spin_lock(&inode->i_lock);
++ if (likely(CIFS_I(inode)->symlink_target)) {
++ strscpy(target_path, CIFS_I(inode)->symlink_target, PATH_MAX);
++ } else {
++ kfree(target_path);
++ target_path = ERR_PTR(-EOPNOTSUPP);
++ }
++ spin_unlock(&inode->i_lock);
++
++ if (!IS_ERR(target_path))
++ set_delayed_call(done, kfree_link, target_path);
++
++ return target_path;
++}
++
+ const struct inode_operations cifs_symlink_inode_ops = {
+ .get_link = cifs_get_link,
+ .permission = cifs_permission,
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index ae7f571a7dba2..b52dca800eac5 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -13,6 +13,8 @@
+ #include <linux/in6.h>
+ #include <linux/inet.h>
+ #include <linux/slab.h>
++#include <linux/scatterlist.h>
++#include <linux/mm.h>
+ #include <linux/mempool.h>
+ #include <linux/workqueue.h>
+ #include <linux/utsname.h>
+@@ -195,6 +197,19 @@ struct cifs_cred {
+ struct cifs_ace *aces;
+ };
+
++struct cifs_open_info_data {
++ char *symlink_target;
++ union {
++ struct smb2_file_all_info fi;
++ struct smb311_posix_qinfo posix_fi;
++ };
++};
++
++static inline void cifs_free_open_info(struct cifs_open_info_data *data)
++{
++ kfree(data->symlink_target);
++}
++
+ /*
+ *****************************************************************
+ * Except the CIFS PDUs themselves all the
+@@ -317,20 +332,20 @@ struct smb_version_operations {
+ int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
+ struct cifs_sb_info *, const char *);
+ /* query path data from the server */
+- int (*query_path_info)(const unsigned int, struct cifs_tcon *,
+- struct cifs_sb_info *, const char *,
+- FILE_ALL_INFO *, bool *, bool *);
++ int (*query_path_info)(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ /* query file data from the server */
+- int (*query_file_info)(const unsigned int, struct cifs_tcon *,
+- struct cifs_fid *, FILE_ALL_INFO *);
++ int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data);
+ /* query reparse tag from srv to determine which type of special file */
+ int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, const char *path,
+ __u32 *reparse_tag);
+ /* get server index number */
+- int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
+- struct cifs_sb_info *, const char *,
+- u64 *uniqueid, FILE_ALL_INFO *);
++ int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid,
++ struct cifs_open_info_data *data);
+ /* set size by path */
+ int (*set_path_size)(const unsigned int, struct cifs_tcon *,
+ const char *, __u64, struct cifs_sb_info *, bool);
+@@ -379,8 +394,8 @@ struct smb_version_operations {
+ struct cifs_sb_info *, const char *,
+ char **, bool);
+ /* open a file for non-posix mounts */
+- int (*open)(const unsigned int, struct cifs_open_parms *,
+- __u32 *, FILE_ALL_INFO *);
++ int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
++ void *buf);
+ /* set fid protocol-specific info */
+ void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
+ /* close a file */
+@@ -1133,6 +1148,7 @@ struct cifs_fattr {
+ struct timespec64 cf_mtime;
+ struct timespec64 cf_ctime;
+ u32 cf_cifstag;
++ char *cf_symlink_target;
+ };
+
+ /*
+@@ -1395,6 +1411,7 @@ struct cifsFileInfo {
+ struct work_struct put; /* work for the final part of _put */
+ struct delayed_work deferred;
+ bool deferred_close_scheduled; /* Flag to indicate close is scheduled */
++ char *symlink_target;
+ };
+
+ struct cifs_io_parms {
+@@ -1553,6 +1570,7 @@ struct cifsInodeInfo {
+ struct list_head deferred_closes; /* list of deferred closes */
+ spinlock_t deferred_lock; /* protection on deferred list */
+ bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */
++ char *symlink_target;
+ };
+
+ static inline struct cifsInodeInfo *
+@@ -2121,4 +2139,80 @@ static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
+ return sizeof(ses->workstation_name);
+ }
+
++static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const FILE_ALL_INFO *src)
++{
++ memcpy(dst, src, (size_t)((u8 *)&src->AccessFlags - (u8 *)src));
++ dst->AccessFlags = src->AccessFlags;
++ dst->CurrentByteOffset = src->CurrentByteOffset;
++ dst->Mode = src->Mode;
++ dst->AlignmentRequirement = src->AlignmentRequirement;
++ dst->FileNameLength = src->FileNameLength;
++}
++
++static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
++ int num_rqst,
++ const u8 *sig)
++{
++ unsigned int len, skip;
++ unsigned int nents = 0;
++ unsigned long addr;
++ int i, j;
++
++ /* Assumes the first rqst has a transform header as the first iov.
++ * I.e.
++ * rqst[0].rq_iov[0] is transform header
++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++ */
++ for (i = 0; i < num_rqst; i++) {
++ /*
++ * The first rqst has a transform header where the
++ * first 20 bytes are not part of the encrypted blob.
++ */
++ for (j = 0; j < rqst[i].rq_nvec; j++) {
++ struct kvec *iov = &rqst[i].rq_iov[j];
++
++ skip = (i == 0) && (j == 0) ? 20 : 0;
++ addr = (unsigned long)iov->iov_base + skip;
++ if (unlikely(is_vmalloc_addr((void *)addr))) {
++ len = iov->iov_len - skip;
++ nents += DIV_ROUND_UP(offset_in_page(addr) + len,
++ PAGE_SIZE);
++ } else {
++ nents++;
++ }
++ }
++ nents += rqst[i].rq_npages;
++ }
++ nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
++ return nents;
++}
++
++/* We can not use the normal sg_set_buf() as we will sometimes pass a
++ * stack object as buf.
++ */
++static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
++ const void *buf,
++ unsigned int buflen)
++{
++ unsigned long addr = (unsigned long)buf;
++ unsigned int off = offset_in_page(addr);
++
++ addr &= PAGE_MASK;
++ if (unlikely(is_vmalloc_addr((void *)addr))) {
++ do {
++ unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
++
++ sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
++
++ off = 0;
++ addr += PAGE_SIZE;
++ buflen -= len;
++ } while (buflen);
++ } else {
++ sg_set_page(sg++, virt_to_page(addr), buflen, off);
++ }
++ return sg;
++}
++
+ #endif /* _CIFS_GLOB_H */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 71386978858eb..edf6f18ec8b73 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -182,10 +182,9 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile,
+ extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
+
+ extern void cifs_down_write(struct rw_semaphore *sem);
+-extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid,
+- struct file *file,
+- struct tcon_link *tlink,
+- __u32 oplock);
++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
++ struct tcon_link *tlink, __u32 oplock,
++ const char *symlink_target);
+ extern int cifs_posix_open(const char *full_path, struct inode **inode,
+ struct super_block *sb, int mode,
+ unsigned int f_flags, __u32 *oplock, __u16 *netfid,
+@@ -200,9 +199,9 @@ extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
+ extern struct inode *cifs_iget(struct super_block *sb,
+ struct cifs_fattr *fattr);
+
+-extern int cifs_get_inode_info(struct inode **inode, const char *full_path,
+- FILE_ALL_INFO *data, struct super_block *sb,
+- int xid, const struct cifs_fid *fid);
++int cifs_get_inode_info(struct inode **inode, const char *full_path,
++ struct cifs_open_info_data *data, struct super_block *sb, int xid,
++ const struct cifs_fid *fid);
+ extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path,
+ struct super_block *sb, unsigned int xid);
+ extern int cifs_get_inode_info_unix(struct inode **pinode,
+@@ -602,8 +601,8 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
+ struct sdesc **sdesc);
+ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
+
+-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+- unsigned int *len, unsigned int *offset);
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++ unsigned int *len, unsigned int *offset);
+ struct cifs_chan *
+ cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
+ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 317ca1be9c4c0..816161f51b29d 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -311,7 +311,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
+ }
+ server->sequence_number = 0;
+ server->session_estab = false;
+- kfree(server->session_key.response);
++ kfree_sensitive(server->session_key.response);
+ server->session_key.response = NULL;
+ server->session_key.len = 0;
+ server->lstrp = jiffies;
+@@ -1580,7 +1580,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+
+ cifs_crypto_secmech_release(server);
+
+- kfree(server->session_key.response);
++ kfree_sensitive(server->session_key.response);
+ server->session_key.response = NULL;
+ server->session_key.len = 0;
+ kfree(server->hostname);
+@@ -4141,7 +4141,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
+ if (ses->auth_key.response) {
+ cifs_dbg(FYI, "Free previous auth_key.response = %p\n",
+ ses->auth_key.response);
+- kfree(ses->auth_key.response);
++ kfree_sensitive(ses->auth_key.response);
+ ses->auth_key.response = NULL;
+ ses->auth_key.len = 0;
+ }
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 05c78a18ade07..c85816cf2d9b3 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -165,10 +165,9 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
+
+ /* Inode operations in similar order to how they appear in Linux file fs.h */
+
+-static int
+-cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+- struct tcon_link *tlink, unsigned oflags, umode_t mode,
+- __u32 *oplock, struct cifs_fid *fid)
++static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
++ struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock,
++ struct cifs_fid *fid, struct cifs_open_info_data *buf)
+ {
+ int rc = -ENOENT;
+ int create_options = CREATE_NOT_DIR;
+@@ -177,7 +176,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+ struct cifs_tcon *tcon = tlink_tcon(tlink);
+ const char *full_path;
+ void *page = alloc_dentry_path();
+- FILE_ALL_INFO *buf = NULL;
+ struct inode *newinode = NULL;
+ int disposition;
+ struct TCP_Server_Info *server = tcon->ses->server;
+@@ -290,12 +288,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+ goto out;
+ }
+
+- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+- if (buf == NULL) {
+- rc = -ENOMEM;
+- goto out;
+- }
+-
+ /*
+ * if we're not using unix extensions, see if we need to set
+ * ATTR_READONLY on the create call
+@@ -364,8 +356,7 @@ cifs_create_get_file_info:
+ {
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+ /* TODO: Add support for calling POSIX query info here, but passing in fid */
+- rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
+- xid, fid);
++ rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid);
+ if (newinode) {
+ if (server->ops->set_lease_key)
+ server->ops->set_lease_key(newinode, fid);
+@@ -402,7 +393,6 @@ cifs_create_set_dentry:
+ d_add(direntry, newinode);
+
+ out:
+- kfree(buf);
+ free_dentry_path(page);
+ return rc;
+
+@@ -427,6 +417,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ struct cifs_pending_open open;
+ __u32 oplock;
+ struct cifsFileInfo *file_info;
++ struct cifs_open_info_data buf = {};
+
+ if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
+ return -EIO;
+@@ -484,8 +475,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ cifs_add_pending_open(&fid, tlink, &open);
+
+ rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+- &oplock, &fid);
+-
++ &oplock, &fid, &buf);
+ if (rc) {
+ cifs_del_pending_open(&open);
+ goto out;
+@@ -510,7 +500,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ file->f_op = &cifs_file_direct_ops;
+ }
+
+- file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
++ file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target);
+ if (file_info == NULL) {
+ if (server->ops->close)
+ server->ops->close(xid, tcon, &fid);
+@@ -526,6 +516,7 @@ out:
+ cifs_put_tlink(tlink);
+ out_free_xid:
+ free_xid(xid);
++ cifs_free_open_info(&buf);
+ return rc;
+ }
+
+@@ -547,6 +538,7 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ struct TCP_Server_Info *server;
+ struct cifs_fid fid;
+ __u32 oplock;
++ struct cifs_open_info_data buf = {};
+
+ cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
+ inode, direntry, direntry);
+@@ -567,11 +559,11 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ if (server->ops->new_lease_key)
+ server->ops->new_lease_key(&fid);
+
+- rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+- &oplock, &fid);
++ rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf);
+ if (!rc && server->ops->close)
+ server->ops->close(xid, tcon, &fid);
+
++ cifs_free_open_info(&buf);
+ cifs_put_tlink(tlink);
+ out_free_xid:
+ free_xid(xid);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 5c045dd697846..391fd2580dabb 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -209,16 +209,14 @@ posix_open_ret:
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+
+-static int
+-cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
+- struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock,
+- struct cifs_fid *fid, unsigned int xid)
++static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
++ struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock,
++ struct cifs_fid *fid, unsigned int xid, struct cifs_open_info_data *buf)
+ {
+ int rc;
+ int desired_access;
+ int disposition;
+ int create_options = CREATE_NOT_DIR;
+- FILE_ALL_INFO *buf;
+ struct TCP_Server_Info *server = tcon->ses->server;
+ struct cifs_open_parms oparms;
+
+@@ -255,10 +253,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+
+ /* BB pass O_SYNC flag through on file attributes .. BB */
+
+- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+- if (!buf)
+- return -ENOMEM;
+-
+ /* O_SYNC also has bit for O_DSYNC so following check picks up either */
+ if (f_flags & O_SYNC)
+ create_options |= CREATE_WRITE_THROUGH;
+@@ -276,9 +270,8 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+ oparms.reconnect = false;
+
+ rc = server->ops->open(xid, &oparms, oplock, buf);
+-
+ if (rc)
+- goto out;
++ return rc;
+
+ /* TODO: Add support for calling posix query info but with passing in fid */
+ if (tcon->unix_ext)
+@@ -294,8 +287,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+ rc = -EOPENSTALE;
+ }
+
+-out:
+- kfree(buf);
+ return rc;
+ }
+
+@@ -325,9 +316,9 @@ cifs_down_write(struct rw_semaphore *sem)
+
+ static void cifsFileInfo_put_work(struct work_struct *work);
+
+-struct cifsFileInfo *
+-cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+- struct tcon_link *tlink, __u32 oplock)
++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
++ struct tcon_link *tlink, __u32 oplock,
++ const char *symlink_target)
+ {
+ struct dentry *dentry = file_dentry(file);
+ struct inode *inode = d_inode(dentry);
+@@ -347,6 +338,15 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ return NULL;
+ }
+
++ if (symlink_target) {
++ cfile->symlink_target = kstrdup(symlink_target, GFP_KERNEL);
++ if (!cfile->symlink_target) {
++ kfree(fdlocks);
++ kfree(cfile);
++ return NULL;
++ }
++ }
++
+ INIT_LIST_HEAD(&fdlocks->locks);
+ fdlocks->cfile = cfile;
+ cfile->llist = fdlocks;
+@@ -440,6 +440,7 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file)
+ cifs_put_tlink(cifs_file->tlink);
+ dput(cifs_file->dentry);
+ cifs_sb_deactive(sb);
++ kfree(cifs_file->symlink_target);
+ kfree(cifs_file);
+ }
+
+@@ -572,6 +573,7 @@ int cifs_open(struct inode *inode, struct file *file)
+ bool posix_open_ok = false;
+ struct cifs_fid fid;
+ struct cifs_pending_open open;
++ struct cifs_open_info_data data = {};
+
+ xid = get_xid();
+
+@@ -662,15 +664,15 @@ int cifs_open(struct inode *inode, struct file *file)
+ if (server->ops->get_lease_key)
+ server->ops->get_lease_key(inode, &fid);
+
+- rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
+- file->f_flags, &oplock, &fid, xid);
++ rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid,
++ xid, &data);
+ if (rc) {
+ cifs_del_pending_open(&open);
+ goto out;
+ }
+ }
+
+- cfile = cifs_new_fileinfo(&fid, file, tlink, oplock);
++ cfile = cifs_new_fileinfo(&fid, file, tlink, oplock, data.symlink_target);
+ if (cfile == NULL) {
+ if (server->ops->close)
+ server->ops->close(xid, tcon, &fid);
+@@ -712,6 +714,7 @@ out:
+ free_dentry_path(page);
+ free_xid(xid);
+ cifs_put_tlink(tlink);
++ cifs_free_open_info(&data);
+ return rc;
+ }
+
+diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
+index 0e13dec86b252..45119597c7655 100644
+--- a/fs/cifs/fs_context.c
++++ b/fs/cifs/fs_context.c
+@@ -791,6 +791,13 @@ do { \
+ cifs_sb->ctx->field = NULL; \
+ } while (0)
+
++#define STEAL_STRING_SENSITIVE(cifs_sb, ctx, field) \
++do { \
++ kfree_sensitive(ctx->field); \
++ ctx->field = cifs_sb->ctx->field; \
++ cifs_sb->ctx->field = NULL; \
++} while (0)
++
+ static int smb3_reconfigure(struct fs_context *fc)
+ {
+ struct smb3_fs_context *ctx = smb3_fc2context(fc);
+@@ -811,7 +818,7 @@ 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);
+- STEAL_STRING(cifs_sb, ctx, password);
++ STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
+ STEAL_STRING(cifs_sb, ctx, domainname);
+ STEAL_STRING(cifs_sb, ctx, nodename);
+ STEAL_STRING(cifs_sb, ctx, iocharset);
+@@ -1162,7 +1169,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
+ }
+ break;
+ case Opt_pass:
+- kfree(ctx->password);
++ kfree_sensitive(ctx->password);
+ ctx->password = NULL;
+ if (strlen(param->string) == 0)
+ break;
+@@ -1470,6 +1477,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
+ return 0;
+
+ cifs_parse_mount_err:
++ kfree_sensitive(ctx->password);
+ return -EINVAL;
+ }
+
+diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
+index bac08c20f559b..b4555f6e327f1 100644
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -210,6 +210,12 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
+ */
+ inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
+ }
++
++ if (S_ISLNK(fattr->cf_mode)) {
++ kfree(cifs_i->symlink_target);
++ cifs_i->symlink_target = fattr->cf_symlink_target;
++ fattr->cf_symlink_target = NULL;
++ }
+ spin_unlock(&inode->i_lock);
+
+ if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
+@@ -347,13 +353,22 @@ cifs_get_file_info_unix(struct file *filp)
+ int rc;
+ unsigned int xid;
+ FILE_UNIX_BASIC_INFO find_data;
+- struct cifs_fattr fattr;
++ struct cifs_fattr fattr = {};
+ struct inode *inode = file_inode(filp);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifsFileInfo *cfile = filp->private_data;
+ struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+
+ xid = get_xid();
++
++ if (cfile->symlink_target) {
++ fattr.cf_symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++ if (!fattr.cf_symlink_target) {
++ rc = -ENOMEM;
++ goto cifs_gfiunix_out;
++ }
++ }
++
+ rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data);
+ if (!rc) {
+ cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+@@ -378,6 +393,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ FILE_UNIX_BASIC_INFO find_data;
+ struct cifs_fattr fattr;
+ struct cifs_tcon *tcon;
++ struct TCP_Server_Info *server;
+ struct tcon_link *tlink;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+
+@@ -387,10 +403,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ if (IS_ERR(tlink))
+ return PTR_ERR(tlink);
+ tcon = tlink_tcon(tlink);
++ server = tcon->ses->server;
+
+ /* could have done a find first instead but this returns more info */
+ rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
+ cifs_sb->local_nls, cifs_remap(cifs_sb));
++ cifs_dbg(FYI, "%s: query path info: rc = %d\n", __func__, rc);
+ cifs_put_tlink(tlink);
+
+ if (!rc) {
+@@ -410,6 +428,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
+ }
+
++ if (S_ISLNK(fattr.cf_mode) && !fattr.cf_symlink_target) {
++ if (!server->ops->query_symlink)
++ return -EOPNOTSUPP;
++ rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
++ &fattr.cf_symlink_target, false);
++ if (rc) {
++ cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc);
++ goto cgiiu_exit;
++ }
++ }
++
+ if (*pinode == NULL) {
+ /* get new inode */
+ cifs_fill_uniqueid(sb, &fattr);
+@@ -432,6 +461,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ }
+
+ cgiiu_exit:
++ kfree(fattr.cf_symlink_target);
+ return rc;
+ }
+ #else
+@@ -601,10 +631,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
+ }
+
+ /* Fill a cifs_fattr struct with info from POSIX info struct */
+-static void
+-smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *info,
+- struct super_block *sb, bool adjust_tz, bool symlink)
++static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data,
++ struct super_block *sb, bool adjust_tz, bool symlink)
+ {
++ struct smb311_posix_qinfo *info = &data->posix_fi;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+
+@@ -639,6 +669,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
+ if (symlink) {
+ fattr->cf_mode |= S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
++ fattr->cf_symlink_target = data->symlink_target;
++ data->symlink_target = NULL;
+ } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+ fattr->cf_mode |= S_IFDIR;
+ fattr->cf_dtype = DT_DIR;
+@@ -655,13 +687,11 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
+ fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
+ }
+
+-
+-/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
+-static void
+-cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+- struct super_block *sb, bool adjust_tz,
+- bool symlink, u32 reparse_tag)
++static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data,
++ struct super_block *sb, bool adjust_tz, bool symlink,
++ u32 reparse_tag)
+ {
++ struct smb2_file_all_info *info = &data->fi;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+
+@@ -703,7 +733,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+ } else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) {
+ fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
+ fattr->cf_dtype = DT_BLK;
+- } else if (symlink) { /* TODO add more reparse tag checks */
++ } else if (symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK ||
++ reparse_tag == IO_REPARSE_TAG_NFS) {
+ fattr->cf_mode = S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
+ } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+@@ -735,6 +766,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+ }
+ }
+
++ if (S_ISLNK(fattr->cf_mode)) {
++ fattr->cf_symlink_target = data->symlink_target;
++ data->symlink_target = NULL;
++ }
++
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+ }
+@@ -744,23 +780,28 @@ cifs_get_file_info(struct file *filp)
+ {
+ int rc;
+ unsigned int xid;
+- FILE_ALL_INFO find_data;
++ struct cifs_open_info_data data = {};
+ struct cifs_fattr fattr;
+ struct inode *inode = file_inode(filp);
+ struct cifsFileInfo *cfile = filp->private_data;
+ struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ struct TCP_Server_Info *server = tcon->ses->server;
++ bool symlink = false;
++ u32 tag = 0;
+
+ if (!server->ops->query_file_info)
+ return -ENOSYS;
+
+ xid = get_xid();
+- rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data);
++ rc = server->ops->query_file_info(xid, tcon, cfile, &data);
+ switch (rc) {
+ case 0:
+ /* TODO: add support to query reparse tag */
+- cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false,
+- false, 0 /* no reparse tag */);
++ if (data.symlink_target) {
++ symlink = true;
++ tag = IO_REPARSE_TAG_SYMLINK;
++ }
++ cifs_open_info_to_fattr(&fattr, &data, inode->i_sb, false, symlink, tag);
+ break;
+ case -EREMOTE:
+ cifs_create_dfs_fattr(&fattr, inode->i_sb);
+@@ -789,6 +830,7 @@ cifs_get_file_info(struct file *filp)
+ /* if filetype is different, return error */
+ rc = cifs_fattr_to_inode(inode, &fattr);
+ cgfi_exit:
++ cifs_free_open_info(&data);
+ free_xid(xid);
+ return rc;
+ }
+@@ -860,14 +902,9 @@ cifs_backup_query_path_info(int xid,
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+
+-static void
+-cifs_set_fattr_ino(int xid,
+- struct cifs_tcon *tcon,
+- struct super_block *sb,
+- struct inode **inode,
+- const char *full_path,
+- FILE_ALL_INFO *data,
+- struct cifs_fattr *fattr)
++static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb,
++ struct inode **inode, const char *full_path,
++ struct cifs_open_info_data *data, struct cifs_fattr *fattr)
+ {
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct TCP_Server_Info *server = tcon->ses->server;
+@@ -885,11 +922,8 @@ cifs_set_fattr_ino(int xid,
+ * If we have an inode pass a NULL tcon to ensure we don't
+ * make a round trip to the server. This only works for SMB2+.
+ */
+- rc = server->ops->get_srv_inum(xid,
+- *inode ? NULL : tcon,
+- cifs_sb, full_path,
+- &fattr->cf_uniqueid,
+- data);
++ rc = server->ops->get_srv_inum(xid, *inode ? NULL : tcon, cifs_sb, full_path,
++ &fattr->cf_uniqueid, data);
+ if (rc) {
+ /*
+ * If that fails reuse existing ino or generate one
+@@ -923,14 +957,10 @@ static inline bool is_inode_cache_good(struct inode *ino)
+ return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0;
+ }
+
+-int
+-cifs_get_inode_info(struct inode **inode,
+- const char *full_path,
+- FILE_ALL_INFO *in_data,
+- struct super_block *sb, int xid,
+- const struct cifs_fid *fid)
++int cifs_get_inode_info(struct inode **inode, const char *full_path,
++ struct cifs_open_info_data *data, struct super_block *sb, int xid,
++ const struct cifs_fid *fid)
+ {
+-
+ struct cifs_tcon *tcon;
+ struct TCP_Server_Info *server;
+ struct tcon_link *tlink;
+@@ -938,8 +968,7 @@ cifs_get_inode_info(struct inode **inode,
+ bool adjust_tz = false;
+ struct cifs_fattr fattr = {0};
+ bool is_reparse_point = false;
+- FILE_ALL_INFO *data = in_data;
+- FILE_ALL_INFO *tmp_data = NULL;
++ struct cifs_open_info_data tmp_data = {};
+ void *smb1_backup_rsp_buf = NULL;
+ int rc = 0;
+ int tmprc = 0;
+@@ -960,21 +989,15 @@ cifs_get_inode_info(struct inode **inode,
+ cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
+ goto out;
+ }
+- tmp_data = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+- if (!tmp_data) {
+- rc = -ENOMEM;
+- goto out;
+- }
+- rc = server->ops->query_path_info(xid, tcon, cifs_sb,
+- full_path, tmp_data,
+- &adjust_tz, &is_reparse_point);
++ rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data,
++ &adjust_tz, &is_reparse_point);
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ if (rc == -ENOENT && is_tcon_dfs(tcon))
+ rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon,
+ cifs_sb,
+ full_path);
+ #endif
+- data = tmp_data;
++ data = &tmp_data;
+ }
+
+ /*
+@@ -988,14 +1011,24 @@ cifs_get_inode_info(struct inode **inode,
+ * since we have to check if its reparse tag matches a known
+ * special file type e.g. symlink or fifo or char etc.
+ */
+- if ((le32_to_cpu(data->Attributes) & ATTR_REPARSE) &&
+- server->ops->query_reparse_tag) {
+- rc = server->ops->query_reparse_tag(xid, tcon, cifs_sb,
+- full_path, &reparse_tag);
+- cifs_dbg(FYI, "reparse tag 0x%x\n", reparse_tag);
++ if (is_reparse_point && data->symlink_target) {
++ reparse_tag = IO_REPARSE_TAG_SYMLINK;
++ } else if ((le32_to_cpu(data->fi.Attributes) & ATTR_REPARSE) &&
++ server->ops->query_reparse_tag) {
++ tmprc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path,
++ &reparse_tag);
++ if (tmprc)
++ cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc);
++ if (server->ops->query_symlink) {
++ tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
++ &data->symlink_target,
++ is_reparse_point);
++ if (tmprc)
++ cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", __func__,
++ tmprc);
++ }
+ }
+- cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz,
+- is_reparse_point, reparse_tag);
++ cifs_open_info_to_fattr(&fattr, data, sb, adjust_tz, is_reparse_point, reparse_tag);
+ break;
+ case -EREMOTE:
+ /* DFS link, no metadata available on this server */
+@@ -1014,18 +1047,20 @@ cifs_get_inode_info(struct inode **inode,
+ */
+ if (backup_cred(cifs_sb) && is_smb1_server(server)) {
+ /* for easier reading */
++ FILE_ALL_INFO *fi;
+ FILE_DIRECTORY_INFO *fdi;
+ SEARCH_ID_FULL_DIR_INFO *si;
+
+ rc = cifs_backup_query_path_info(xid, tcon, sb,
+ full_path,
+ &smb1_backup_rsp_buf,
+- &data);
++ &fi);
+ if (rc)
+ goto out;
+
+- fdi = (FILE_DIRECTORY_INFO *)data;
+- si = (SEARCH_ID_FULL_DIR_INFO *)data;
++ move_cifs_info_to_smb2(&data->fi, fi);
++ fdi = (FILE_DIRECTORY_INFO *)fi;
++ si = (SEARCH_ID_FULL_DIR_INFO *)fi;
+
+ cifs_dir_info_to_fattr(&fattr, fdi, cifs_sb);
+ fattr.cf_uniqueid = le64_to_cpu(si->UniqueId);
+@@ -1123,7 +1158,8 @@ handle_mnt_opt:
+ out:
+ cifs_buf_release(smb1_backup_rsp_buf);
+ cifs_put_tlink(tlink);
+- kfree(tmp_data);
++ cifs_free_open_info(&tmp_data);
++ kfree(fattr.cf_symlink_target);
+ return rc;
+ }
+
+@@ -1138,7 +1174,7 @@ smb311_posix_get_inode_info(struct inode **inode,
+ bool adjust_tz = false;
+ struct cifs_fattr fattr = {0};
+ bool symlink = false;
+- struct smb311_posix_qinfo *data = NULL;
++ struct cifs_open_info_data data = {};
+ int rc = 0;
+ int tmprc = 0;
+
+@@ -1155,15 +1191,9 @@ smb311_posix_get_inode_info(struct inode **inode,
+ cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
+ goto out;
+ }
+- data = kmalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL);
+- if (!data) {
+- rc = -ENOMEM;
+- goto out;
+- }
+
+- rc = smb311_posix_query_path_info(xid, tcon, cifs_sb,
+- full_path, data,
+- &adjust_tz, &symlink);
++ rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz,
++ &symlink);
+
+ /*
+ * 2. Convert it to internal cifs metadata (fattr)
+@@ -1171,7 +1201,7 @@ smb311_posix_get_inode_info(struct inode **inode,
+
+ switch (rc) {
+ case 0:
+- smb311_posix_info_to_fattr(&fattr, data, sb, adjust_tz, symlink);
++ smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink);
+ break;
+ case -EREMOTE:
+ /* DFS link, no metadata available on this server */
+@@ -1228,7 +1258,8 @@ smb311_posix_get_inode_info(struct inode **inode,
+ }
+ out:
+ cifs_put_tlink(tlink);
+- kfree(data);
++ cifs_free_open_info(&data);
++ kfree(fattr.cf_symlink_target);
+ return rc;
+ }
+
+diff --git a/fs/cifs/link.c b/fs/cifs/link.c
+index 6803cb27eecc3..8042dbdd182bc 100644
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -202,40 +202,6 @@ out:
+ return rc;
+ }
+
+-static int
+-query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const unsigned char *path,
+- char **symlinkinfo)
+-{
+- int rc;
+- u8 *buf = NULL;
+- unsigned int link_len = 0;
+- unsigned int bytes_read = 0;
+-
+- buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
+- if (!buf)
+- return -ENOMEM;
+-
+- if (tcon->ses->server->ops->query_mf_symlink)
+- rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon,
+- cifs_sb, path, buf, &bytes_read);
+- else
+- rc = -ENOSYS;
+-
+- if (rc)
+- goto out;
+-
+- if (bytes_read == 0) { /* not a symlink */
+- rc = -EINVAL;
+- goto out;
+- }
+-
+- rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo);
+-out:
+- kfree(buf);
+- return rc;
+-}
+-
+ int
+ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+@@ -245,6 +211,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ u8 *buf = NULL;
+ unsigned int link_len = 0;
+ unsigned int bytes_read = 0;
++ char *symlink = NULL;
+
+ if (!couldbe_mf_symlink(fattr))
+ /* it's not a symlink */
+@@ -266,7 +233,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ if (bytes_read == 0) /* not a symlink */
+ goto out;
+
+- rc = parse_mf_symlink(buf, bytes_read, &link_len, NULL);
++ rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink);
+ if (rc == -EINVAL) {
+ /* it's not a symlink */
+ rc = 0;
+@@ -281,6 +248,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ fattr->cf_mode &= ~S_IFMT;
+ fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
+ fattr->cf_dtype = DT_LNK;
++ fattr->cf_symlink_target = symlink;
+ out:
+ kfree(buf);
+ return rc;
+@@ -600,75 +568,6 @@ cifs_hl_exit:
+ return rc;
+ }
+
+-const char *
+-cifs_get_link(struct dentry *direntry, struct inode *inode,
+- struct delayed_call *done)
+-{
+- int rc = -ENOMEM;
+- unsigned int xid;
+- const char *full_path;
+- void *page;
+- char *target_path = NULL;
+- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+- struct tcon_link *tlink = NULL;
+- struct cifs_tcon *tcon;
+- struct TCP_Server_Info *server;
+-
+- if (!direntry)
+- return ERR_PTR(-ECHILD);
+-
+- xid = get_xid();
+-
+- tlink = cifs_sb_tlink(cifs_sb);
+- if (IS_ERR(tlink)) {
+- free_xid(xid);
+- return ERR_CAST(tlink);
+- }
+- tcon = tlink_tcon(tlink);
+- server = tcon->ses->server;
+-
+- page = alloc_dentry_path();
+- full_path = build_path_from_dentry(direntry, page);
+- if (IS_ERR(full_path)) {
+- free_xid(xid);
+- cifs_put_tlink(tlink);
+- free_dentry_path(page);
+- return ERR_CAST(full_path);
+- }
+-
+- cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, inode);
+-
+- rc = -EACCES;
+- /*
+- * First try Minshall+French Symlinks, if configured
+- * and fallback to UNIX Extensions Symlinks.
+- */
+- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+- rc = query_mf_symlink(xid, tcon, cifs_sb, full_path,
+- &target_path);
+-
+- if (rc != 0 && server->ops->query_symlink) {
+- struct cifsInodeInfo *cifsi = CIFS_I(inode);
+- bool reparse_point = false;
+-
+- if (cifsi->cifsAttrs & ATTR_REPARSE)
+- reparse_point = true;
+-
+- rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
+- &target_path, reparse_point);
+- }
+-
+- free_dentry_path(page);
+- free_xid(xid);
+- cifs_put_tlink(tlink);
+- if (rc != 0) {
+- kfree(target_path);
+- return ERR_PTR(rc);
+- }
+- set_delayed_call(done, kfree_link, target_path);
+- return target_path;
+-}
+-
+ int
+ cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
+ struct dentry *direntry, const char *symname)
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 35085fa866367..1efb5ca9fd804 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -1123,7 +1123,7 @@ cifs_alloc_hash(const char *name,
+ void
+ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
+ {
+- kfree(*sdesc);
++ kfree_sensitive(*sdesc);
+ *sdesc = NULL;
+ if (*shash)
+ crypto_free_shash(*shash);
+@@ -1137,8 +1137,8 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
+ * @len: Where to store the length for this page:
+ * @offset: Where to store the offset for this page
+ */
+-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+- unsigned int *len, unsigned int *offset)
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++ unsigned int *len, unsigned int *offset)
+ {
+ *len = rqst->rq_pagesz;
+ *offset = (page == 0) ? rqst->rq_offset : 0;
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 8e060c00c9690..6a78bcc51e816 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -994,6 +994,8 @@ static int cifs_filldir(char *find_entry, struct file *file,
+ cifs_unix_basic_to_fattr(&fattr,
+ &((FILE_UNIX_INFO *)find_entry)->basic,
+ cifs_sb);
++ if (S_ISLNK(fattr.cf_mode))
++ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+ break;
+ case SMB_FIND_FILE_INFO_STANDARD:
+ cifs_std_info_to_fattr(&fattr,
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 6a85136da27ce..5d93154572c01 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -1214,10 +1214,18 @@ out_free_smb_buf:
+ static void
+ sess_free_buffer(struct sess_data *sess_data)
+ {
++ struct kvec *iov = sess_data->iov;
+
+- free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
++ /*
++ * Zero the session data before freeing, as it might contain sensitive info (keys, etc).
++ * Note that iov[1] is already freed by caller.
++ */
++ if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
++ memzero_explicit(iov[0].iov_base, iov[0].iov_len);
++
++ free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
+ sess_data->buf0_type = CIFS_NO_BUFFER;
+- kfree(sess_data->iov[2].iov_base);
++ kfree_sensitive(iov[2].iov_base);
+ }
+
+ static int
+@@ -1375,7 +1383,7 @@ out:
+ sess_data->result = rc;
+ sess_data->func = NULL;
+ sess_free_buffer(sess_data);
+- kfree(ses->auth_key.response);
++ kfree_sensitive(ses->auth_key.response);
+ ses->auth_key.response = NULL;
+ }
+
+@@ -1514,7 +1522,7 @@ out:
+ sess_data->result = rc;
+ sess_data->func = NULL;
+ sess_free_buffer(sess_data);
+- kfree(ses->auth_key.response);
++ kfree_sensitive(ses->auth_key.response);
+ ses->auth_key.response = NULL;
+ }
+
+@@ -1649,7 +1657,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
+ rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
+
+ out_free_ntlmsspblob:
+- kfree(ntlmsspblob);
++ kfree_sensitive(ntlmsspblob);
+ out:
+ sess_free_buffer(sess_data);
+
+@@ -1659,9 +1667,9 @@ out:
+ }
+
+ /* Else error. Cleanup */
+- kfree(ses->auth_key.response);
++ kfree_sensitive(ses->auth_key.response);
+ ses->auth_key.response = NULL;
+- kfree(ses->ntlmssp);
++ kfree_sensitive(ses->ntlmssp);
+ ses->ntlmssp = NULL;
+
+ sess_data->func = NULL;
+@@ -1760,7 +1768,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
+ }
+
+ out_free_ntlmsspblob:
+- kfree(ntlmsspblob);
++ kfree_sensitive(ntlmsspblob);
+ out:
+ sess_free_buffer(sess_data);
+
+@@ -1768,9 +1776,9 @@ out:
+ rc = sess_establish_session(sess_data);
+
+ /* Cleanup */
+- kfree(ses->auth_key.response);
++ kfree_sensitive(ses->auth_key.response);
+ ses->auth_key.response = NULL;
+- kfree(ses->ntlmssp);
++ kfree_sensitive(ses->ntlmssp);
+ ses->ntlmssp = NULL;
+
+ sess_data->func = NULL;
+@@ -1846,7 +1854,7 @@ int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
+ rc = sess_data->result;
+
+ out:
+- kfree(sess_data);
++ kfree_sensitive(sess_data);
+ return rc;
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
+index f36b2d2d40ca3..50480751e521c 100644
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -542,31 +542,32 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
+ return rc;
+ }
+
+-static int
+-cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- FILE_ALL_INFO *data, bool *adjustTZ, bool *symlink)
++static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjustTZ, bool *symlink)
+ {
+ int rc;
++ FILE_ALL_INFO fi = {};
+
+ *symlink = false;
+
+ /* could do find first instead but this returns more info */
+- rc = CIFSSMBQPathInfo(xid, tcon, full_path, data, 0 /* not legacy */,
+- cifs_sb->local_nls, cifs_remap(cifs_sb));
++ rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, cifs_sb->local_nls,
++ cifs_remap(cifs_sb));
+ /*
+ * BB optimize code so we do not make the above call when server claims
+ * no NT SMB support and the above call failed at least once - set flag
+ * in tcon or mount.
+ */
+ if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
+- rc = SMBQueryInformation(xid, tcon, full_path, data,
+- cifs_sb->local_nls,
++ rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls,
+ cifs_remap(cifs_sb));
++ if (!rc)
++ move_cifs_info_to_smb2(&data->fi, &fi);
+ *adjustTZ = true;
+ }
+
+- if (!rc && (le32_to_cpu(data->Attributes) & ATTR_REPARSE)) {
++ if (!rc && (le32_to_cpu(fi.Attributes) & ATTR_REPARSE)) {
+ int tmprc;
+ int oplock = 0;
+ struct cifs_fid fid;
+@@ -592,10 +593,9 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ return rc;
+ }
+
+-static int
+-cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- u64 *uniqueid, FILE_ALL_INFO *data)
++static int cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ u64 *uniqueid, struct cifs_open_info_data *unused)
+ {
+ /*
+ * We can not use the IndexNumber field by default from Windows or
+@@ -613,11 +613,22 @@ cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+ cifs_remap(cifs_sb));
+ }
+
+-static int
+-cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_fid *fid, FILE_ALL_INFO *data)
++static int cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data)
+ {
+- return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
++ int rc;
++ FILE_ALL_INFO fi = {};
++
++ if (cfile->symlink_target) {
++ data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++ if (!data->symlink_target)
++ return -ENOMEM;
++ }
++
++ rc = CIFSSMBQFileInfo(xid, tcon, cfile->fid.netfid, &fi);
++ if (!rc)
++ move_cifs_info_to_smb2(&data->fi, &fi);
++ return rc;
+ }
+
+ static void
+@@ -702,19 +713,20 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
+ cifsInode->cifsAttrs = dosattrs;
+ }
+
+-static int
+-cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+- __u32 *oplock, FILE_ALL_INFO *buf)
++static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
++ void *buf)
+ {
++ FILE_ALL_INFO *fi = buf;
++
+ if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
+ return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
+ oparms->disposition,
+ oparms->desired_access,
+ oparms->create_options,
+- &oparms->fid->netfid, oplock, buf,
++ &oparms->fid->netfid, oplock, fi,
+ oparms->cifs_sb->local_nls,
+ cifs_remap(oparms->cifs_sb));
+- return CIFS_open(xid, oparms, oplock, buf);
++ return CIFS_open(xid, oparms, oplock, fi);
+ }
+
+ static void
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index 9dfd2dd612c25..4992b43616a7a 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -20,40 +20,125 @@
+ #include "cifs_unicode.h"
+ #include "fscache.h"
+ #include "smb2proto.h"
++#include "smb2status.h"
+
+-int
+-smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+- __u32 *oplock, FILE_ALL_INFO *buf)
++static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
++{
++ struct smb2_err_rsp *err = iov->iov_base;
++ struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL);
++ u32 len;
++
++ if (err->ErrorContextCount) {
++ struct smb2_error_context_rsp *p, *end;
++
++ len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
++ ErrorContextData) +
++ sizeof(struct smb2_symlink_err_rsp));
++ if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err))
++ return ERR_PTR(-EINVAL);
++
++ p = (struct smb2_error_context_rsp *)err->ErrorData;
++ end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len);
++ do {
++ if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) {
++ sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData;
++ break;
++ }
++ cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n",
++ __func__, le32_to_cpu(p->ErrorId));
++
++ len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8);
++ p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len);
++ } while (p < end);
++ } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) &&
++ iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) {
++ sym = (struct smb2_symlink_err_rsp *)err->ErrorData;
++ }
++
++ if (!IS_ERR(sym) && (le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
++ le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK))
++ sym = ERR_PTR(-EINVAL);
++
++ return sym;
++}
++
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, 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;
++
++ sym = symlink_data(iov);
++ if (IS_ERR(sym))
++ return PTR_ERR(sym);
++
++ sub_len = le16_to_cpu(sym->SubstituteNameLength);
++ sub_offs = le16_to_cpu(sym->SubstituteNameOffset);
++ print_len = le16_to_cpu(sym->PrintNameLength);
++ print_offs = le16_to_cpu(sym->PrintNameOffset);
++
++ if (iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offs + sub_len ||
++ 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;
++}
++
++int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf)
+ {
+ int rc;
+ __le16 *smb2_path;
+- struct smb2_file_all_info *smb2_data = NULL;
+ __u8 smb2_oplock;
++ struct cifs_open_info_data *data = buf;
++ struct smb2_file_all_info file_info = {};
++ struct smb2_file_all_info *smb2_data = data ? &file_info : NULL;
++ struct kvec err_iov = {};
++ int err_buftype = CIFS_NO_BUFFER;
+ struct cifs_fid *fid = oparms->fid;
+ struct network_resiliency_req nr_ioctl_req;
+
+ smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
+- if (smb2_path == NULL) {
+- rc = -ENOMEM;
+- goto out;
+- }
+-
+- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+- GFP_KERNEL);
+- if (smb2_data == NULL) {
+- rc = -ENOMEM;
+- goto out;
+- }
++ if (smb2_path == NULL)
++ return -ENOMEM;
+
+ oparms->desired_access |= FILE_READ_ATTRIBUTES;
+ smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
+
+- rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL,
+- NULL, NULL);
++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
++ &err_buftype);
++ if (rc && data) {
++ struct smb2_hdr *hdr = err_iov.iov_base;
++
++ if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER))
++ rc = -ENOMEM;
++ else if (hdr->Status == STATUS_STOPPED_ON_SYMLINK && oparms->cifs_sb) {
++ rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
++ &data->symlink_target);
++ if (!rc) {
++ memset(smb2_data, 0, sizeof(*smb2_data));
++ oparms->create_options |= OPEN_REPARSE_POINT;
++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data,
++ NULL, NULL, NULL);
++ oparms->create_options &= ~OPEN_REPARSE_POINT;
++ }
++ }
++ }
++
+ if (rc)
+ goto out;
+
+-
+ if (oparms->tcon->use_resilient) {
+ /* default timeout is 0, servers pick default (120 seconds) */
+ nr_ioctl_req.Timeout =
+@@ -73,7 +158,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ rc = 0;
+ }
+
+- if (buf) {
++ if (smb2_data) {
+ /* if open response does not have IndexNumber field - get it */
+ if (smb2_data->IndexNumber == 0) {
+ rc = SMB2_get_srv_num(xid, oparms->tcon,
+@@ -89,12 +174,12 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ rc = 0;
+ }
+ }
+- move_smb2_info_to_cifs(buf, smb2_data);
++ memcpy(&data->fi, smb2_data, sizeof(data->fi));
+ }
+
+ *oplock = smb2_oplock;
+ out:
+- kfree(smb2_data);
++ free_rsp_buf(err_buftype, err_iov.iov_base);
+ kfree(smb2_path);
+ return rc;
+ }
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index b83f59051b26f..fc5776e7a7824 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -24,6 +24,7 @@
+ #include "smb2pdu.h"
+ #include "smb2proto.h"
+ #include "cached_dir.h"
++#include "smb2status.h"
+
+ static void
+ free_set_inf_compound(struct smb_rqst *rqst)
+@@ -50,13 +51,15 @@ struct cop_vars {
+ /*
+ * note: If cfile is passed, the reference to it is dropped here.
+ * So make sure that you do not reuse cfile after return from this func.
++ *
++ * If passing @err_iov and @err_buftype, ensure to make them both large enough (>= 3) to hold all
++ * error responses. Caller is also responsible for freeing them up.
+ */
+-static int
+-smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- __u32 desired_access, __u32 create_disposition,
+- __u32 create_options, umode_t mode, void *ptr, int command,
+- struct cifsFileInfo *cfile)
++static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ __u32 desired_access, __u32 create_disposition, __u32 create_options,
++ umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile,
++ struct kvec *err_iov, int *err_buftype)
+ {
+ struct cop_vars *vars = NULL;
+ struct kvec *rsp_iov;
+@@ -70,6 +73,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ int num_rqst = 0;
+ int resp_buftype[3];
+ struct smb2_query_info_rsp *qi_rsp = NULL;
++ struct cifs_open_info_data *idata;
+ int flags = 0;
+ __u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0};
+ unsigned int size[2];
+@@ -385,14 +389,19 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+
+ switch (command) {
+ case SMB2_OP_QUERY_INFO:
++ idata = ptr;
++ if (rc == 0 && cfile && cfile->symlink_target) {
++ idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++ if (!idata->symlink_target)
++ rc = -ENOMEM;
++ }
+ if (rc == 0) {
+ qi_rsp = (struct smb2_query_info_rsp *)
+ rsp_iov[1].iov_base;
+ rc = smb2_validate_and_copy_iov(
+ le16_to_cpu(qi_rsp->OutputBufferOffset),
+ le32_to_cpu(qi_rsp->OutputBufferLength),
+- &rsp_iov[1], sizeof(struct smb2_file_all_info),
+- ptr);
++ &rsp_iov[1], sizeof(idata->fi), (char *)&idata->fi);
+ }
+ if (rqst[1].rq_iov)
+ SMB2_query_info_free(&rqst[1]);
+@@ -406,13 +415,20 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ tcon->tid);
+ break;
+ case SMB2_OP_POSIX_QUERY_INFO:
++ idata = ptr;
++ if (rc == 0 && cfile && cfile->symlink_target) {
++ idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++ if (!idata->symlink_target)
++ rc = -ENOMEM;
++ }
+ if (rc == 0) {
+ qi_rsp = (struct smb2_query_info_rsp *)
+ rsp_iov[1].iov_base;
+ rc = smb2_validate_and_copy_iov(
+ le16_to_cpu(qi_rsp->OutputBufferOffset),
+ le32_to_cpu(qi_rsp->OutputBufferLength),
+- &rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr);
++ &rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */,
++ (char *)&idata->posix_fi);
+ }
+ if (rqst[1].rq_iov)
+ SMB2_query_info_free(&rqst[1]);
+@@ -477,42 +493,33 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ free_set_inf_compound(rqst);
+ break;
+ }
+- free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
+- free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
+- free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
++
++ if (rc && err_iov && err_buftype) {
++ memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov));
++ memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype));
++ } else {
++ free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
++ free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
++ free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
++ }
+ kfree(vars);
+ return rc;
+ }
+
+-void
+-move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src)
+-{
+- memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src);
+- dst->CurrentByteOffset = src->CurrentByteOffset;
+- dst->Mode = src->Mode;
+- dst->AlignmentRequirement = src->AlignmentRequirement;
+- dst->IndexNumber1 = 0; /* we don't use it */
+-}
+-
+-int
+-smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse)
++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse)
+ {
+ int rc;
+- struct smb2_file_all_info *smb2_data;
+ __u32 create_options = 0;
+ struct cifsFileInfo *cfile;
+ struct cached_fid *cfid = NULL;
++ struct kvec err_iov[3] = {};
++ int err_buftype[3] = {};
+
+ *adjust_tz = false;
+ *reparse = false;
+
+- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+- GFP_KERNEL);
+- if (smb2_data == NULL)
+- return -ENOMEM;
+-
+ if (strcmp(full_path, ""))
+ rc = -ENOENT;
+ else
+@@ -520,63 +527,58 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ /* If it is a root and its handle is cached then use it */
+ if (!rc) {
+ if (cfid->file_all_info_is_valid) {
+- move_smb2_info_to_cifs(data,
+- &cfid->file_all_info);
++ memcpy(&data->fi, &cfid->file_all_info, sizeof(data->fi));
+ } else {
+- rc = SMB2_query_info(xid, tcon,
+- cfid->fid.persistent_fid,
+- cfid->fid.volatile_fid, smb2_data);
+- if (!rc)
+- move_smb2_info_to_cifs(data, smb2_data);
++ rc = SMB2_query_info(xid, tcon, cfid->fid.persistent_fid,
++ cfid->fid.volatile_fid, &data->fi);
+ }
+ close_cached_dir(cfid);
+- goto out;
++ return rc;
+ }
+
+ cifs_get_readable_path(tcon, full_path, &cfile);
+- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+- FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
+- ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN,
++ create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile,
++ err_iov, err_buftype);
+ if (rc == -EOPNOTSUPP) {
++ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER &&
++ ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE &&
++ ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) {
++ rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target);
++ if (rc)
++ goto out;
++ }
+ *reparse = true;
+ create_options |= OPEN_REPARSE_POINT;
+
+ /* Failed on a symbolic link - query a reparse point info */
+ cifs_get_readable_path(tcon, full_path, &cfile);
+- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+- FILE_READ_ATTRIBUTES, FILE_OPEN,
+- create_options, ACL_NO_MODE,
+- smb2_data, SMB2_OP_QUERY_INFO, cfile);
++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES,
++ FILE_OPEN, create_options, ACL_NO_MODE, data,
++ SMB2_OP_QUERY_INFO, cfile, NULL, NULL);
+ }
+- if (rc)
+- goto out;
+
+- move_smb2_info_to_cifs(data, smb2_data);
+ out:
+- kfree(smb2_data);
++ free_rsp_buf(err_buftype[0], err_iov[0].iov_base);
++ free_rsp_buf(err_buftype[1], err_iov[1].iov_base);
++ free_rsp_buf(err_buftype[2], err_iov[2].iov_base);
+ return rc;
+ }
+
+
+-int
+-smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse)
++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse)
+ {
+ int rc;
+ __u32 create_options = 0;
+ struct cifsFileInfo *cfile;
+- struct smb311_posix_qinfo *smb2_data;
++ struct kvec err_iov[3] = {};
++ int err_buftype[3] = {};
+
+ *adjust_tz = false;
+ *reparse = false;
+
+- /* BB TODO: Make struct larger when add support for parsing owner SIDs */
+- smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo),
+- GFP_KERNEL);
+- if (smb2_data == NULL)
+- return -ENOMEM;
+-
+ /*
+ * BB TODO: Add support for using the cached root handle.
+ * Create SMB2_query_posix_info worker function to do non-compounded query
+@@ -585,29 +587,32 @@ smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ */
+
+ cifs_get_readable_path(tcon, full_path, &cfile);
+- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+- FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
+- ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile);
++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN,
++ create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile,
++ err_iov, err_buftype);
+ if (rc == -EOPNOTSUPP) {
+ /* BB TODO: When support for special files added to Samba re-verify this path */
++ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER &&
++ ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE &&
++ ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) {
++ rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target);
++ if (rc)
++ goto out;
++ }
+ *reparse = true;
+ create_options |= OPEN_REPARSE_POINT;
+
+ /* Failed on a symbolic link - query a reparse point info */
+ cifs_get_readable_path(tcon, full_path, &cfile);
+- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+- FILE_READ_ATTRIBUTES, FILE_OPEN,
+- create_options, ACL_NO_MODE,
+- smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile);
++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES,
++ FILE_OPEN, create_options, ACL_NO_MODE, data,
++ SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL);
+ }
+- if (rc)
+- goto out;
+-
+- /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */
+- memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo));
+
+ out:
+- kfree(smb2_data);
++ free_rsp_buf(err_buftype[0], err_iov[0].iov_base);
++ free_rsp_buf(err_buftype[1], err_iov[1].iov_base);
++ free_rsp_buf(err_buftype[2], err_iov[2].iov_base);
+ return rc;
+ }
+
+@@ -619,7 +624,7 @@ smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
+ return smb2_compound_op(xid, tcon, cifs_sb, name,
+ FILE_WRITE_ATTRIBUTES, FILE_CREATE,
+ CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
+- NULL);
++ NULL, NULL, NULL);
+ }
+
+ void
+@@ -641,7 +646,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
+ tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
+ FILE_WRITE_ATTRIBUTES, FILE_CREATE,
+ CREATE_NOT_FILE, ACL_NO_MODE,
+- &data, SMB2_OP_SET_INFO, cfile);
++ &data, SMB2_OP_SET_INFO, cfile, NULL, NULL);
+ if (tmprc == 0)
+ cifs_i->cifsAttrs = dosattrs;
+ }
+@@ -652,7 +657,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+ {
+ return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
+ CREATE_NOT_FILE, ACL_NO_MODE,
+- NULL, SMB2_OP_RMDIR, NULL);
++ NULL, SMB2_OP_RMDIR, NULL, NULL, NULL);
+ }
+
+ int
+@@ -661,7 +666,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+ {
+ return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
+ CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
+- ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
++ ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL);
+ }
+
+ static int
+@@ -680,7 +685,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
+ }
+ rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
+ FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
+- command, cfile);
++ command, cfile, NULL, NULL);
+ smb2_rename_path:
+ kfree(smb2_to_name);
+ return rc;
+@@ -720,7 +725,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
+ cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
+ return smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
+- &eof, SMB2_OP_SET_EOF, cfile);
++ &eof, SMB2_OP_SET_EOF, cfile, NULL, NULL);
+ }
+
+ int
+@@ -746,7 +751,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
+ cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
+ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ FILE_WRITE_ATTRIBUTES, FILE_OPEN,
+- 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile);
++ 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile,
++ NULL, NULL);
+ cifs_put_tlink(tlink);
+ return rc;
+ }
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index b724bf42b5401..74052b51655ec 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -831,33 +831,25 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
+ return rc;
+ }
+
+-static int
+-smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb, const char *full_path,
+- u64 *uniqueid, FILE_ALL_INFO *data)
++static int smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ u64 *uniqueid, struct cifs_open_info_data *data)
+ {
+- *uniqueid = le64_to_cpu(data->IndexNumber);
++ *uniqueid = le64_to_cpu(data->fi.IndexNumber);
+ return 0;
+ }
+
+-static int
+-smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_fid *fid, FILE_ALL_INFO *data)
++static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data)
+ {
+- int rc;
+- struct smb2_file_all_info *smb2_data;
++ struct cifs_fid *fid = &cfile->fid;
+
+- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+- GFP_KERNEL);
+- if (smb2_data == NULL)
+- return -ENOMEM;
+-
+- rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
+- smb2_data);
+- if (!rc)
+- move_smb2_info_to_cifs(data, smb2_data);
+- kfree(smb2_data);
+- return rc;
++ if (cfile->symlink_target) {
++ data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++ if (!data->symlink_target)
++ return -ENOMEM;
++ }
++ return SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, &data->fi);
+ }
+
+ #ifdef CONFIG_CIFS_XATTR
+@@ -2836,9 +2828,6 @@ parse_reparse_point(struct reparse_data_buffer *buf,
+ }
+ }
+
+-#define SMB2_SYMLINK_STRUCT_SIZE \
+- (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
+-
+ static int
+ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, const char *full_path,
+@@ -2850,13 +2839,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_open_parms oparms;
+ struct cifs_fid fid;
+ struct kvec err_iov = {NULL, 0};
+- struct smb2_err_rsp *err_buf = NULL;
+- struct smb2_symlink_err_rsp *symlink;
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
+- unsigned int sub_len;
+- unsigned int sub_offset;
+- unsigned int print_len;
+- unsigned int print_offset;
+ int flags = CIFS_CP_CREATE_CLOSE_OP;
+ struct smb_rqst rqst[3];
+ int resp_buftype[3];
+@@ -2973,47 +2956,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ goto querty_exit;
+ }
+
+- err_buf = err_iov.iov_base;
+- if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
+- err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) {
+- rc = -EINVAL;
+- goto querty_exit;
+- }
+-
+- symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
+- if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
+- le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) {
+- rc = -EINVAL;
+- goto querty_exit;
+- }
+-
+- /* open must fail on symlink - reset rc */
+- rc = 0;
+- sub_len = le16_to_cpu(symlink->SubstituteNameLength);
+- sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
+- print_len = le16_to_cpu(symlink->PrintNameLength);
+- print_offset = le16_to_cpu(symlink->PrintNameOffset);
+-
+- if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
+- rc = -EINVAL;
+- goto querty_exit;
+- }
+-
+- if (err_iov.iov_len <
+- SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
+- rc = -EINVAL;
+- goto querty_exit;
+- }
+-
+- *target_path = cifs_strndup_from_utf16(
+- (char *)symlink->PathBuffer + sub_offset,
+- sub_len, true, cifs_sb->local_nls);
+- if (!(*target_path)) {
+- rc = -ENOMEM;
+- goto querty_exit;
+- }
+- convert_delimiter(*target_path, '/');
+- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
++ rc = smb2_parse_symlink_response(cifs_sb, &err_iov, target_path);
+
+ querty_exit:
+ cifs_dbg(FYI, "query symlink rc %d\n", rc);
+@@ -4239,69 +4182,82 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+ memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
+ }
+
+-/* We can not use the normal sg_set_buf() as we will sometimes pass a
+- * stack object as buf.
+- */
+-static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
+- unsigned int buflen)
++static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++ int num_rqst, const u8 *sig, u8 **iv,
++ struct aead_request **req, struct scatterlist **sgl,
++ unsigned int *num_sgs)
+ {
+- void *addr;
+- /*
+- * VMAP_STACK (at least) puts stack into the vmalloc address space
+- */
+- if (is_vmalloc_addr(buf))
+- addr = vmalloc_to_page(buf);
+- else
+- addr = virt_to_page(buf);
+- sg_set_page(sg, addr, buflen, offset_in_page(buf));
++ unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm);
++ unsigned int iv_size = crypto_aead_ivsize(tfm);
++ unsigned int len;
++ u8 *p;
++
++ *num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig);
++
++ len = iv_size;
++ len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1);
++ len = ALIGN(len, crypto_tfm_ctx_alignment());
++ len += req_size;
++ len = ALIGN(len, __alignof__(struct scatterlist));
++ len += *num_sgs * sizeof(**sgl);
++
++ p = kmalloc(len, GFP_ATOMIC);
++ if (!p)
++ return NULL;
++
++ *iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1);
++ *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size,
++ crypto_tfm_ctx_alignment());
++ *sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size,
++ __alignof__(struct scatterlist));
++ return p;
+ }
+
+-/* Assumes the first rqst has a transform header as the first iov.
+- * I.e.
+- * rqst[0].rq_iov[0] is transform header
+- * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+- * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+- */
+-static struct scatterlist *
+-init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
++static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++ int num_rqst, const u8 *sig, u8 **iv,
++ struct aead_request **req, struct scatterlist **sgl)
+ {
+- unsigned int sg_len;
++ unsigned int off, len, skip;
+ struct scatterlist *sg;
+- unsigned int i;
+- unsigned int j;
+- unsigned int idx = 0;
+- int skip;
+-
+- sg_len = 1;
+- for (i = 0; i < num_rqst; i++)
+- sg_len += rqst[i].rq_nvec + rqst[i].rq_npages;
++ unsigned int num_sgs;
++ unsigned long addr;
++ int i, j;
++ void *p;
+
+- sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL);
+- if (!sg)
++ p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs);
++ if (!p)
+ return NULL;
+
+- sg_init_table(sg, sg_len);
++ sg_init_table(*sgl, num_sgs);
++ sg = *sgl;
++
++ /* Assumes the first rqst has a transform header as the first iov.
++ * I.e.
++ * rqst[0].rq_iov[0] is transform header
++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++ */
+ for (i = 0; i < num_rqst; i++) {
++ /*
++ * The first rqst has a transform header where the
++ * first 20 bytes are not part of the encrypted blob.
++ */
+ for (j = 0; j < rqst[i].rq_nvec; j++) {
+- /*
+- * The first rqst has a transform header where the
+- * first 20 bytes are not part of the encrypted blob
+- */
+- skip = (i == 0) && (j == 0) ? 20 : 0;
+- smb2_sg_set_buf(&sg[idx++],
+- rqst[i].rq_iov[j].iov_base + skip,
+- rqst[i].rq_iov[j].iov_len - skip);
+- }
++ struct kvec *iov = &rqst[i].rq_iov[j];
+
++ skip = (i == 0) && (j == 0) ? 20 : 0;
++ addr = (unsigned long)iov->iov_base + skip;
++ len = iov->iov_len - skip;
++ sg = cifs_sg_set_buf(sg, (void *)addr, len);
++ }
+ for (j = 0; j < rqst[i].rq_npages; j++) {
+- unsigned int len, offset;
+-
+- rqst_page_get_length(&rqst[i], j, &len, &offset);
+- sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset);
++ rqst_page_get_length(&rqst[i], j, &len, &off);
++ sg_set_page(sg++, rqst[i].rq_pages[j], len, off);
+ }
+ }
+- smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE);
+- return sg;
++ cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE);
++
++ return p;
+ }
+
+ static int
+@@ -4347,11 +4303,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ u8 sign[SMB2_SIGNATURE_SIZE] = {};
+ u8 key[SMB3_ENC_DEC_KEY_SIZE];
+ struct aead_request *req;
+- char *iv;
+- unsigned int iv_len;
++ u8 *iv;
+ DECLARE_CRYPTO_WAIT(wait);
+ struct crypto_aead *tfm;
+ unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
++ void *creq;
+
+ rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key);
+ if (rc) {
+@@ -4386,32 +4342,15 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ return rc;
+ }
+
+- req = aead_request_alloc(tfm, GFP_KERNEL);
+- if (!req) {
+- cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
++ creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg);
++ if (unlikely(!creq))
+ return -ENOMEM;
+- }
+
+ if (!enc) {
+ memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
+ crypt_len += SMB2_SIGNATURE_SIZE;
+ }
+
+- sg = init_sg(num_rqst, rqst, sign);
+- if (!sg) {
+- cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__);
+- rc = -ENOMEM;
+- goto free_req;
+- }
+-
+- iv_len = crypto_aead_ivsize(tfm);
+- iv = kzalloc(iv_len, GFP_KERNEL);
+- if (!iv) {
+- cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
+- rc = -ENOMEM;
+- goto free_sg;
+- }
+-
+ if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+ (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
+ memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
+@@ -4420,6 +4359,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
+ }
+
++ aead_request_set_tfm(req, tfm);
+ aead_request_set_crypt(req, sg, sg, crypt_len, iv);
+ aead_request_set_ad(req, assoc_data_len);
+
+@@ -4432,11 +4372,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ if (!rc && enc)
+ memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
+
+- kfree(iv);
+-free_sg:
+- kfree(sg);
+-free_req:
+- kfree(req);
++ kfree_sensitive(creq);
+ return rc;
+ }
+
+@@ -5124,7 +5060,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ {
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ int rc = -EPERM;
+- FILE_ALL_INFO *buf = NULL;
++ struct cifs_open_info_data buf = {};
+ struct cifs_io_parms io_parms = {0};
+ __u32 oplock = 0;
+ struct cifs_fid fid;
+@@ -5140,7 +5076,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ * and was used by default in earlier versions of Windows
+ */
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
+- goto out;
++ return rc;
+
+ /*
+ * TODO: Add ability to create instead via reparse point. Windows (e.g.
+@@ -5149,16 +5085,10 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ */
+
+ if (!S_ISCHR(mode) && !S_ISBLK(mode))
+- goto out;
++ return rc;
+
+ cifs_dbg(FYI, "sfu compat create special file\n");
+
+- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+- if (buf == NULL) {
+- rc = -ENOMEM;
+- goto out;
+- }
+-
+ oparms.tcon = tcon;
+ oparms.cifs_sb = cifs_sb;
+ oparms.desired_access = GENERIC_WRITE;
+@@ -5173,21 +5103,21 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ oplock = REQ_OPLOCK;
+ else
+ oplock = 0;
+- rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
++ rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf);
+ if (rc)
+- goto out;
++ return rc;
+
+ /*
+ * BB Do not bother to decode buf since no local inode yet to put
+ * timestamps in, but we can reuse it safely.
+ */
+
+- pdev = (struct win_dev *)buf;
++ pdev = (struct win_dev *)&buf.fi;
+ io_parms.pid = current->tgid;
+ io_parms.tcon = tcon;
+ io_parms.offset = 0;
+ io_parms.length = sizeof(struct win_dev);
+- iov[1].iov_base = buf;
++ iov[1].iov_base = &buf.fi;
+ iov[1].iov_len = sizeof(struct win_dev);
+ if (S_ISCHR(mode)) {
+ memcpy(pdev->type, "IntxCHR", 8);
+@@ -5206,8 +5136,8 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ d_drop(dentry);
+
+ /* FIXME: add code here to set EAs */
+-out:
+- kfree(buf);
++
++ cifs_free_open_info(&buf);
+ return rc;
+ }
+
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 92a1d0695ebdf..aa0245268d40e 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1345,7 +1345,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
+ static void
+ SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data)
+ {
+- free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
++ struct kvec *iov = sess_data->iov;
++
++ /* iov[1] is already freed by caller */
++ if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
++ memzero_explicit(iov[0].iov_base, iov[0].iov_len);
++
++ free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
+ sess_data->buf0_type = CIFS_NO_BUFFER;
+ }
+
+@@ -1477,6 +1483,8 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
+ out_put_spnego_key:
+ key_invalidate(spnego_key);
+ key_put(spnego_key);
++ if (rc)
++ kfree_sensitive(ses->auth_key.response);
+ out:
+ sess_data->result = rc;
+ sess_data->func = NULL;
+@@ -1573,7 +1581,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
+ }
+
+ out:
+- kfree(ntlmssp_blob);
++ kfree_sensitive(ntlmssp_blob);
+ SMB2_sess_free_buffer(sess_data);
+ if (!rc) {
+ sess_data->result = 0;
+@@ -1581,7 +1589,7 @@ out:
+ return;
+ }
+ out_err:
+- kfree(ses->ntlmssp);
++ kfree_sensitive(ses->ntlmssp);
+ ses->ntlmssp = NULL;
+ sess_data->result = rc;
+ sess_data->func = NULL;
+@@ -1657,9 +1665,9 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
+ }
+ #endif
+ out:
+- kfree(ntlmssp_blob);
++ kfree_sensitive(ntlmssp_blob);
+ SMB2_sess_free_buffer(sess_data);
+- kfree(ses->ntlmssp);
++ kfree_sensitive(ses->ntlmssp);
+ ses->ntlmssp = NULL;
+ sess_data->result = rc;
+ sess_data->func = NULL;
+@@ -1737,7 +1745,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
+ cifs_server_dbg(VFS, "signing requested but authenticated as guest\n");
+ rc = sess_data->result;
+ out:
+- kfree(sess_data);
++ kfree_sensitive(sess_data);
+ return rc;
+ }
+
+diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
+index f57881b8464fb..1237bb86e93a8 100644
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -56,6 +56,9 @@ struct smb2_rdma_crypto_transform {
+
+ #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL
+
++#define SMB2_SYMLINK_STRUCT_SIZE \
++ (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
++
+ #define SYMLINK_ERROR_TAG 0x4c4d5953
+
+ struct smb2_symlink_err_rsp {
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
+index 3f740f24b96a7..7818d0b835672 100644
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -53,16 +53,12 @@ extern bool smb2_is_valid_oplock_break(char *buffer,
+ struct TCP_Server_Info *srv);
+ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
+ struct mid_q_entry *mid);
+-
+-extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
+- struct smb2_file_all_info *src);
+ extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, const char *path,
+ __u32 *reparse_tag);
+-extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb,
+- const char *full_path, FILE_ALL_INFO *data,
+- bool *adjust_tz, bool *symlink);
++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
+ const char *full_path, __u64 size,
+ struct cifs_sb_info *cifs_sb, bool set_alloc);
+@@ -95,9 +91,9 @@ 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);
+-extern int smb2_open_file(const unsigned int xid,
+- struct cifs_open_parms *oparms,
+- __u32 *oplock, FILE_ALL_INFO *buf);
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, 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,
+ struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
+@@ -278,9 +274,9 @@ extern int smb2_query_info_compound(const unsigned int xid,
+ struct kvec *rsp, int *buftype,
+ struct cifs_sb_info *cifs_sb);
+ /* query path info from the server using SMB311 POSIX extensions*/
+-extern int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+- struct cifs_sb_info *sb, const char *path, struct smb311_posix_qinfo *qinf,
+- bool *adjust_tx, bool *symlink);
++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb, const char *full_path,
++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ int posix_info_parse(const void *beg, const void *end,
+ struct smb2_posix_info_parsed *out);
+ int posix_info_sid_size(const void *beg, const void *end);
+diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
+index d1f9d26322027..ec6519e1ca3bf 100644
+--- a/fs/configfs/dir.c
++++ b/fs/configfs/dir.c
+@@ -316,6 +316,7 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
+ return 0;
+
+ out_remove:
++ configfs_put(dentry->d_fsdata);
+ configfs_remove_dirent(dentry);
+ return PTR_ERR(inode);
+ }
+@@ -382,6 +383,7 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent,
+ return 0;
+
+ out_remove:
++ configfs_put(dentry->d_fsdata);
+ configfs_remove_dirent(dentry);
+ return PTR_ERR(inode);
+ }
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
+index 950c63fa4d0b2..38930d9b0bb73 100644
+--- a/fs/debugfs/file.c
++++ b/fs/debugfs/file.c
+@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+ }
+ EXPORT_SYMBOL_GPL(debugfs_attr_read);
+
+-ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+- size_t len, loff_t *ppos)
++static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos, bool is_signed)
+ {
+ struct dentry *dentry = F_DENTRY(file);
+ ssize_t ret;
+@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+ ret = debugfs_file_get(dentry);
+ if (unlikely(ret))
+ return ret;
+- ret = simple_attr_write(file, buf, len, ppos);
++ if (is_signed)
++ ret = simple_attr_write_signed(file, buf, len, ppos);
++ else
++ ret = simple_attr_write(file, buf, len, ppos);
+ debugfs_file_put(dentry);
+ return ret;
+ }
++
++ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ return debugfs_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(debugfs_attr_write);
+
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ return debugfs_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(debugfs_attr_write_signed);
++
+ static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *value,
+ const struct file_operations *fops,
+@@ -738,11 +754,11 @@ static int debugfs_atomic_t_get(void *data, u64 *val)
+ *val = atomic_read((atomic_t *)data);
+ return 0;
+ }
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get,
+ debugfs_atomic_t_set, "%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
+ "%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
+ "%lld\n");
+
+ /**
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index 2d55569f96ace..51b7ac7166d96 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -317,52 +317,61 @@ dstmap_out:
+ return ret;
+ }
+
+-static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq,
+- struct page **pagepool)
++static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
++ struct page **pagepool)
+ {
+- const unsigned int nrpages_out =
++ const unsigned int inpages = PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT;
++ const unsigned int outpages =
+ PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT;
+ const unsigned int righthalf = min_t(unsigned int, rq->outputsize,
+ PAGE_SIZE - rq->pageofs_out);
+ const unsigned int lefthalf = rq->outputsize - righthalf;
++ const unsigned int interlaced_offset =
++ rq->alg == Z_EROFS_COMPRESSION_SHIFTED ? 0 : rq->pageofs_out;
+ unsigned char *src, *dst;
+
+- if (nrpages_out > 2) {
++ if (outpages > 2 && rq->alg == Z_EROFS_COMPRESSION_SHIFTED) {
+ DBG_BUGON(1);
+- return -EIO;
++ return -EFSCORRUPTED;
+ }
+
+ if (rq->out[0] == *rq->in) {
+- DBG_BUGON(nrpages_out != 1);
++ DBG_BUGON(rq->pageofs_out);
+ return 0;
+ }
+
+- src = kmap_atomic(*rq->in) + rq->pageofs_in;
++ src = kmap_local_page(rq->in[inpages - 1]) + rq->pageofs_in;
+ if (rq->out[0]) {
+- dst = kmap_atomic(rq->out[0]);
+- memcpy(dst + rq->pageofs_out, src, righthalf);
+- kunmap_atomic(dst);
++ dst = kmap_local_page(rq->out[0]);
++ memcpy(dst + rq->pageofs_out, src + interlaced_offset,
++ righthalf);
++ kunmap_local(dst);
+ }
+
+- if (nrpages_out == 2) {
+- DBG_BUGON(!rq->out[1]);
+- if (rq->out[1] == *rq->in) {
++ if (outpages > inpages) {
++ DBG_BUGON(!rq->out[outpages - 1]);
++ if (rq->out[outpages - 1] != rq->in[inpages - 1]) {
++ dst = kmap_local_page(rq->out[outpages - 1]);
++ memcpy(dst, interlaced_offset ? src :
++ (src + righthalf), lefthalf);
++ kunmap_local(dst);
++ } else if (!interlaced_offset) {
+ memmove(src, src + righthalf, lefthalf);
+- } else {
+- dst = kmap_atomic(rq->out[1]);
+- memcpy(dst, src + righthalf, lefthalf);
+- kunmap_atomic(dst);
+ }
+ }
+- kunmap_atomic(src);
++ kunmap_local(src);
+ return 0;
+ }
+
+ static struct z_erofs_decompressor decompressors[] = {
+ [Z_EROFS_COMPRESSION_SHIFTED] = {
+- .decompress = z_erofs_shifted_transform,
++ .decompress = z_erofs_transform_plain,
+ .name = "shifted"
+ },
++ [Z_EROFS_COMPRESSION_INTERLACED] = {
++ .decompress = z_erofs_transform_plain,
++ .name = "interlaced"
++ },
+ [Z_EROFS_COMPRESSION_LZ4] = {
+ .decompress = z_erofs_lz4_decompress,
+ .name = "lz4"
+diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
+index 2b48373f690b6..5c1de6d7ad71f 100644
+--- a/fs/erofs/erofs_fs.h
++++ b/fs/erofs/erofs_fs.h
+@@ -295,11 +295,13 @@ struct z_erofs_lzma_cfgs {
+ * bit 1 : HEAD1 big pcluster (0 - off; 1 - on)
+ * bit 2 : HEAD2 big pcluster (0 - off; 1 - on)
+ * bit 3 : tailpacking inline pcluster (0 - off; 1 - on)
++ * bit 4 : interlaced plain pcluster (0 - off; 1 - on)
+ */
+ #define Z_EROFS_ADVISE_COMPACTED_2B 0x0001
+ #define Z_EROFS_ADVISE_BIG_PCLUSTER_1 0x0002
+ #define Z_EROFS_ADVISE_BIG_PCLUSTER_2 0x0004
+ #define Z_EROFS_ADVISE_INLINE_PCLUSTER 0x0008
++#define Z_EROFS_ADVISE_INTERLACED_PCLUSTER 0x0010
+
+ struct z_erofs_map_header {
+ __le16 h_reserved1;
+diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
+index a01cc82795a25..12d075dfb964b 100644
+--- a/fs/erofs/internal.h
++++ b/fs/erofs/internal.h
+@@ -407,6 +407,7 @@ struct erofs_map_blocks {
+
+ enum {
+ Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
++ Z_EROFS_COMPRESSION_INTERLACED,
+ Z_EROFS_COMPRESSION_RUNTIME_MAX
+ };
+
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index c7511b4317763..f19875d96cc1f 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -487,7 +487,8 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
+ struct erofs_workgroup *grp;
+ int err;
+
+- if (!(map->m_flags & EROFS_MAP_ENCODED)) {
++ if (!(map->m_flags & EROFS_MAP_ENCODED) ||
++ (!ztailpacking && !(map->m_pa >> PAGE_SHIFT))) {
+ DBG_BUGON(1);
+ return -EFSCORRUPTED;
+ }
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index 63fd2f1460265..720d74b5c699d 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -673,15 +673,26 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+ map->m_pa = blknr_to_addr(m.pblk);
+ err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
+ if (err)
+- goto out;
++ goto unmap_out;
+ }
+
+- if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN)
+- map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED;
+- else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2)
++ if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) {
++ if (map->m_llen > map->m_plen) {
++ DBG_BUGON(1);
++ err = -EFSCORRUPTED;
++ goto unmap_out;
++ }
++ if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER)
++ map->m_algorithmformat =
++ Z_EROFS_COMPRESSION_INTERLACED;
++ else
++ map->m_algorithmformat =
++ Z_EROFS_COMPRESSION_SHIFTED;
++ } else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
+ map->m_algorithmformat = vi->z_algorithmtype[1];
+- else
++ } else {
+ map->m_algorithmformat = vi->z_algorithmtype[0];
++ }
+
+ if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
+ ((flags & EROFS_GET_BLOCKS_READMORE) &&
+@@ -691,14 +702,12 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+ if (!err)
+ map->m_flags |= EROFS_MAP_FULL_MAPPED;
+ }
++
+ unmap_out:
+ erofs_unmap_metabuf(&m.map->buf);
+-
+-out:
+ erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o",
+ __func__, map->m_la, map->m_pa,
+ map->m_llen, map->m_plen, map->m_flags);
+-
+ return err;
+ }
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 70e97075e535e..e70928e92b2cd 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -346,7 +346,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
+ if (!level)
+ level = F2FS_ZSTD_DEFAULT_CLEVEL;
+
+- params = zstd_get_params(F2FS_ZSTD_DEFAULT_CLEVEL, cc->rlen);
++ params = zstd_get_params(level, cc->rlen);
+ workspace_size = zstd_cstream_workspace_bound(¶ms.cParams);
+
+ workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 1e57b11ffe2a6..a7227640fbdf2 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2966,7 +2966,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr)
+ /* Flags that should be inherited by new inodes from their parent. */
+ #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \
+ F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
+- F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL)
++ F2FS_CASEFOLD_FL)
+
+ /* Flags that are appropriate for regular files (all but dir-specific ones). */
+ #define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index ce4905a073b3c..74337edcbbb09 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1866,6 +1866,10 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+ if (!f2fs_disable_compressed_file(inode))
+ return -EINVAL;
+ } else {
++ /* try to convert inline_data to support compression */
++ int err = f2fs_convert_inline_inode(inode);
++ if (err)
++ return err;
+ if (!f2fs_may_compress(inode))
+ return -EINVAL;
+ if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 73881314bdda8..68eb1d33128be 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1738,8 +1738,9 @@ freed:
+ get_valid_blocks(sbi, segno, false) == 0)
+ seg_freed++;
+
+- if (__is_large_section(sbi) && segno + 1 < end_segno)
+- sbi->next_victim_seg[gc_type] = segno + 1;
++ if (__is_large_section(sbi))
++ sbi->next_victim_seg[gc_type] =
++ (segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
+ skip:
+ f2fs_put_page(sum_page, 0);
+ }
+@@ -2127,8 +2128,6 @@ out_unlock:
+ if (err)
+ return err;
+
+- set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+-
+ freeze_super(sbi->sb);
+ f2fs_down_write(&sbi->gc_lock);
+ f2fs_down_write(&sbi->cp_global_sem);
+@@ -2144,6 +2143,7 @@ out_unlock:
+ if (err)
+ goto out_err;
+
++ set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ err = free_segment_range(sbi, secs, false);
+ if (err)
+ goto recover_out;
+@@ -2167,6 +2167,7 @@ out_unlock:
+ f2fs_commit_super(sbi, false);
+ }
+ recover_out:
++ clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ if (err) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_err(sbi, "resize_fs failed, should run fsck to repair!");
+@@ -2179,6 +2180,5 @@ out_err:
+ f2fs_up_write(&sbi->cp_global_sem);
+ f2fs_up_write(&sbi->gc_lock);
+ thaw_super(sbi->sb);
+- clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ return err;
+ }
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index bf00d5057abb8..0073e3511b2ad 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -22,8 +22,163 @@
+ #include "acl.h"
+ #include <trace/events/f2fs.h>
+
++static inline int is_extension_exist(const unsigned char *s, const char *sub,
++ bool tmp_ext)
++{
++ size_t slen = strlen(s);
++ size_t sublen = strlen(sub);
++ int i;
++
++ if (sublen == 1 && *sub == '*')
++ return 1;
++
++ /*
++ * filename format of multimedia file should be defined as:
++ * "filename + '.' + extension + (optional: '.' + temp extension)".
++ */
++ if (slen < sublen + 2)
++ return 0;
++
++ if (!tmp_ext) {
++ /* file has no temp extension */
++ if (s[slen - sublen - 1] != '.')
++ return 0;
++ return !strncasecmp(s + slen - sublen, sub, sublen);
++ }
++
++ for (i = 1; i < slen - sublen; i++) {
++ if (s[i] != '.')
++ continue;
++ if (!strncasecmp(s + i + 1, sub, sublen))
++ return 1;
++ }
++
++ return 0;
++}
++
++int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
++ bool hot, bool set)
++{
++ __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
++ int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
++ int hot_count = sbi->raw_super->hot_ext_count;
++ int total_count = cold_count + hot_count;
++ int start, count;
++ int i;
++
++ if (set) {
++ if (total_count == F2FS_MAX_EXTENSION)
++ return -EINVAL;
++ } else {
++ if (!hot && !cold_count)
++ return -EINVAL;
++ if (hot && !hot_count)
++ return -EINVAL;
++ }
++
++ if (hot) {
++ start = cold_count;
++ count = total_count;
++ } else {
++ start = 0;
++ count = cold_count;
++ }
++
++ for (i = start; i < count; i++) {
++ if (strcmp(name, extlist[i]))
++ continue;
++
++ if (set)
++ return -EINVAL;
++
++ memcpy(extlist[i], extlist[i + 1],
++ F2FS_EXTENSION_LEN * (total_count - i - 1));
++ memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
++ if (hot)
++ sbi->raw_super->hot_ext_count = hot_count - 1;
++ else
++ sbi->raw_super->extension_count =
++ cpu_to_le32(cold_count - 1);
++ return 0;
++ }
++
++ if (!set)
++ return -EINVAL;
++
++ if (hot) {
++ memcpy(extlist[count], name, strlen(name));
++ sbi->raw_super->hot_ext_count = hot_count + 1;
++ } else {
++ char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
++
++ memcpy(buf, &extlist[cold_count],
++ F2FS_EXTENSION_LEN * hot_count);
++ memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
++ memcpy(extlist[cold_count], name, strlen(name));
++ memcpy(&extlist[cold_count + 1], buf,
++ F2FS_EXTENSION_LEN * hot_count);
++ sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
++ }
++ return 0;
++}
++
++static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir,
++ struct inode *inode, const unsigned char *name)
++{
++ __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
++ unsigned char (*noext)[F2FS_EXTENSION_LEN] =
++ F2FS_OPTION(sbi).noextensions;
++ unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions;
++ unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
++ unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
++ int i, cold_count, hot_count;
++
++ if (!f2fs_sb_has_compression(sbi))
++ return;
++
++ if (S_ISDIR(inode->i_mode))
++ goto inherit_comp;
++
++ /* This name comes only from normal files. */
++ if (!name)
++ return;
++
++ /* Don't compress hot files. */
++ f2fs_down_read(&sbi->sb_lock);
++ cold_count = le32_to_cpu(sbi->raw_super->extension_count);
++ hot_count = sbi->raw_super->hot_ext_count;
++ for (i = cold_count; i < cold_count + hot_count; i++)
++ if (is_extension_exist(name, extlist[i], false))
++ break;
++ f2fs_up_read(&sbi->sb_lock);
++ if (i < (cold_count + hot_count))
++ return;
++
++ /* Don't compress unallowed extension. */
++ for (i = 0; i < noext_cnt; i++)
++ if (is_extension_exist(name, noext[i], false))
++ return;
++
++ /* Compress wanting extension. */
++ for (i = 0; i < ext_cnt; i++) {
++ if (is_extension_exist(name, ext[i], false)) {
++ set_compress_context(inode);
++ return;
++ }
++ }
++inherit_comp:
++ /* Inherit the {no-}compression flag in directory */
++ if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) {
++ F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL;
++ f2fs_mark_inode_dirty_sync(inode, true);
++ } else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) {
++ set_compress_context(inode);
++ }
++}
++
+ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns,
+- struct inode *dir, umode_t mode)
++ struct inode *dir, umode_t mode,
++ const char *name)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+ nid_t ino;
+@@ -114,12 +269,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns,
+ if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
+ set_inode_flag(inode, FI_PROJ_INHERIT);
+
+- if (f2fs_sb_has_compression(sbi)) {
+- /* Inherit the compression flag in directory */
+- if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) &&
+- f2fs_may_compress(inode))
+- set_compress_context(inode);
+- }
++ /* Check compression first. */
++ set_compress_new_inode(sbi, dir, inode, name);
+
+ /* Should enable inline_data after compression set */
+ if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
+@@ -153,40 +304,6 @@ fail_drop:
+ return ERR_PTR(err);
+ }
+
+-static inline int is_extension_exist(const unsigned char *s, const char *sub,
+- bool tmp_ext)
+-{
+- size_t slen = strlen(s);
+- size_t sublen = strlen(sub);
+- int i;
+-
+- if (sublen == 1 && *sub == '*')
+- return 1;
+-
+- /*
+- * filename format of multimedia file should be defined as:
+- * "filename + '.' + extension + (optional: '.' + temp extension)".
+- */
+- if (slen < sublen + 2)
+- return 0;
+-
+- if (!tmp_ext) {
+- /* file has no temp extension */
+- if (s[slen - sublen - 1] != '.')
+- return 0;
+- return !strncasecmp(s + slen - sublen, sub, sublen);
+- }
+-
+- for (i = 1; i < slen - sublen; i++) {
+- if (s[i] != '.')
+- continue;
+- if (!strncasecmp(s + i + 1, sub, sublen))
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+ /*
+ * Set file's temperature for hot/cold data separation
+ */
+@@ -217,124 +334,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *
+ file_set_hot(inode);
+ }
+
+-int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+- bool hot, bool set)
+-{
+- __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+- int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+- int hot_count = sbi->raw_super->hot_ext_count;
+- int total_count = cold_count + hot_count;
+- int start, count;
+- int i;
+-
+- if (set) {
+- if (total_count == F2FS_MAX_EXTENSION)
+- return -EINVAL;
+- } else {
+- if (!hot && !cold_count)
+- return -EINVAL;
+- if (hot && !hot_count)
+- return -EINVAL;
+- }
+-
+- if (hot) {
+- start = cold_count;
+- count = total_count;
+- } else {
+- start = 0;
+- count = cold_count;
+- }
+-
+- for (i = start; i < count; i++) {
+- if (strcmp(name, extlist[i]))
+- continue;
+-
+- if (set)
+- return -EINVAL;
+-
+- memcpy(extlist[i], extlist[i + 1],
+- F2FS_EXTENSION_LEN * (total_count - i - 1));
+- memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
+- if (hot)
+- sbi->raw_super->hot_ext_count = hot_count - 1;
+- else
+- sbi->raw_super->extension_count =
+- cpu_to_le32(cold_count - 1);
+- return 0;
+- }
+-
+- if (!set)
+- return -EINVAL;
+-
+- if (hot) {
+- memcpy(extlist[count], name, strlen(name));
+- sbi->raw_super->hot_ext_count = hot_count + 1;
+- } else {
+- char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
+-
+- memcpy(buf, &extlist[cold_count],
+- F2FS_EXTENSION_LEN * hot_count);
+- memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
+- memcpy(extlist[cold_count], name, strlen(name));
+- memcpy(&extlist[cold_count + 1], buf,
+- F2FS_EXTENSION_LEN * hot_count);
+- sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
+- }
+- return 0;
+-}
+-
+-static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode,
+- const unsigned char *name)
+-{
+- __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+- unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions;
+- unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions;
+- unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
+- unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
+- int i, cold_count, hot_count;
+-
+- if (!f2fs_sb_has_compression(sbi) ||
+- F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL ||
+- !f2fs_may_compress(inode) ||
+- (!ext_cnt && !noext_cnt))
+- return;
+-
+- f2fs_down_read(&sbi->sb_lock);
+-
+- cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+- hot_count = sbi->raw_super->hot_ext_count;
+-
+- for (i = cold_count; i < cold_count + hot_count; i++) {
+- if (is_extension_exist(name, extlist[i], false)) {
+- f2fs_up_read(&sbi->sb_lock);
+- return;
+- }
+- }
+-
+- f2fs_up_read(&sbi->sb_lock);
+-
+- for (i = 0; i < noext_cnt; i++) {
+- if (is_extension_exist(name, noext[i], false)) {
+- f2fs_disable_compressed_file(inode);
+- return;
+- }
+- }
+-
+- if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
+- return;
+-
+- for (i = 0; i < ext_cnt; i++) {
+- if (!is_extension_exist(name, ext[i], false))
+- continue;
+-
+- /* Do not use inline_data with compression */
+- stat_dec_inline_inode(inode);
+- clear_inode_flag(inode, FI_INLINE_DATA);
+- set_compress_context(inode);
+- return;
+- }
+-}
+-
+ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir,
+ struct dentry *dentry, umode_t mode, bool excl)
+ {
+@@ -352,15 +351,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir,
+ if (err)
+ return err;
+
+- inode = f2fs_new_inode(mnt_userns, dir, mode);
++ inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
+ set_file_temperature(sbi, inode, dentry->d_name.name);
+
+- set_compress_inode(sbi, inode, dentry->d_name.name);
+-
+ inode->i_op = &f2fs_file_inode_operations;
+ inode->i_fop = &f2fs_file_operations;
+ inode->i_mapping->a_ops = &f2fs_dblock_aops;
+@@ -689,7 +686,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ if (err)
+ return err;
+
+- inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO);
++ inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+@@ -760,7 +757,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+ if (err)
+ return err;
+
+- inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode);
++ inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, NULL);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+@@ -817,7 +814,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ if (err)
+ return err;
+
+- inode = f2fs_new_inode(mnt_userns, dir, mode);
++ inode = f2fs_new_inode(mnt_userns, dir, mode, NULL);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+@@ -856,7 +853,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ if (err)
+ return err;
+
+- inode = f2fs_new_inode(mnt_userns, dir, mode);
++ inode = f2fs_new_inode(mnt_userns, dir, mode, NULL);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 84bad18ce13d5..2afed479160b8 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -1171,7 +1171,7 @@ submit:
+
+ atomic_inc(&dcc->issued_discard);
+
+- f2fs_update_iostat(sbi, FS_DISCARD, 1);
++ f2fs_update_iostat(sbi, FS_DISCARD, len * F2FS_BLKSIZE);
+
+ lstart += len;
+ start += len;
+@@ -1449,7 +1449,7 @@ retry:
+ if (i + 1 < dpolicy->granularity)
+ break;
+
+- if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
++ if (i + 1 < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
+ return __issue_discard_cmd_orderly(sbi, dpolicy);
+
+ pend_list = &dcc->pend_list[i];
+@@ -2026,8 +2026,10 @@ int f2fs_start_discard_thread(struct f2fs_sb_info *sbi)
+
+ dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi,
+ "f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev));
+- if (IS_ERR(dcc->f2fs_issue_discard))
++ if (IS_ERR(dcc->f2fs_issue_discard)) {
+ err = PTR_ERR(dcc->f2fs_issue_discard);
++ dcc->f2fs_issue_discard = NULL;
++ }
+
+ return err;
+ }
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 5415c06d8246f..1187f29dc8e0a 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4460,9 +4460,9 @@ free_nm:
+ f2fs_destroy_node_manager(sbi);
+ free_sm:
+ f2fs_destroy_segment_manager(sbi);
+- f2fs_destroy_post_read_wq(sbi);
+ stop_ckpt_thread:
+ f2fs_stop_ckpt_thread(sbi);
++ f2fs_destroy_post_read_wq(sbi);
+ free_devices:
+ destroy_device_list(sbi);
+ kvfree(sbi->ckpt);
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index c4526f16355d5..a0746be3c1de7 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -458,6 +458,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ /* panic? */
+ return -EIO;
+
++ if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
++ return -EIO;
+ fd.search_key->cat = HFS_I(main_inode)->cat_key;
+ if (hfs_brec_find(&fd))
+ /* panic? */
+diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c
+index 39f5e343bf4d4..fdb0edb8a607d 100644
+--- a/fs/hfs/trans.c
++++ b/fs/hfs/trans.c
+@@ -109,7 +109,7 @@ void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr
+ if (nls_io) {
+ wchar_t ch;
+
+- while (srclen > 0) {
++ while (srclen > 0 && dstlen > 0) {
+ size = nls_io->char2uni(src, srclen, &ch);
+ if (size < 0) {
+ ch = '?';
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index fbcfa6bfee805..26169d75f6cf7 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -1256,7 +1256,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+
+ case Opt_size:
+ /* memparse() will accept a K/M/G without a digit */
+- if (!isdigit(param->string[0]))
++ if (!param->string || !isdigit(param->string[0]))
+ goto bad_val;
+ ctx->max_size_opt = memparse(param->string, &rest);
+ ctx->max_val_type = SIZE_STD;
+@@ -1266,7 +1266,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+
+ case Opt_nr_inodes:
+ /* memparse() will accept a K/M/G without a digit */
+- if (!isdigit(param->string[0]))
++ if (!param->string || !isdigit(param->string[0]))
+ goto bad_val;
+ ctx->nr_inodes = memparse(param->string, &rest);
+ return 0;
+@@ -1282,7 +1282,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+
+ case Opt_min_size:
+ /* memparse() will accept a K/M/G without a digit */
+- if (!isdigit(param->string[0]))
++ if (!param->string || !isdigit(param->string[0]))
+ goto bad_val;
+ ctx->min_size_opt = memparse(param->string, &rest);
+ ctx->min_val_type = SIZE_STD;
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 6b838d3ae7c2e..765838578a722 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -155,7 +155,7 @@ int dbMount(struct inode *ipbmap)
+ struct bmap *bmp;
+ struct dbmap_disk *dbmp_le;
+ struct metapage *mp;
+- int i;
++ int i, err;
+
+ /*
+ * allocate/initialize the in-memory bmap descriptor
+@@ -170,8 +170,8 @@ int dbMount(struct inode *ipbmap)
+ BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
+ PSIZE, 0);
+ if (mp == NULL) {
+- kfree(bmp);
+- return -EIO;
++ err = -EIO;
++ goto err_kfree_bmp;
+ }
+
+ /* copy the on-disk bmap descriptor to its in-memory version. */
+@@ -181,9 +181,8 @@ int dbMount(struct inode *ipbmap)
+ bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+ bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+ if (!bmp->db_numag) {
+- release_metapage(mp);
+- kfree(bmp);
+- return -EINVAL;
++ err = -EINVAL;
++ goto err_release_metapage;
+ }
+
+ bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
+@@ -194,6 +193,16 @@ int dbMount(struct inode *ipbmap)
+ bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+ bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+ bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
++ if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
++ err = -EINVAL;
++ goto err_release_metapage;
++ }
++
++ if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
++ err = -EINVAL;
++ goto err_release_metapage;
++ }
++
+ for (i = 0; i < MAXAG; i++)
+ bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
+ bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
+@@ -214,6 +223,12 @@ int dbMount(struct inode *ipbmap)
+ BMAP_LOCK_INIT(bmp);
+
+ return (0);
++
++err_release_metapage:
++ release_metapage(mp);
++err_kfree_bmp:
++ kfree(bmp);
++ return err;
+ }
+
+
+diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
+index 9db4f5789c0ec..4fbbf88435e69 100644
+--- a/fs/jfs/namei.c
++++ b/fs/jfs/namei.c
+@@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip,
+ if (ssize <= IDATASIZE) {
+ ip->i_op = &jfs_fast_symlink_inode_operations;
+
+- ip->i_link = JFS_IP(ip)->i_inline;
++ ip->i_link = JFS_IP(ip)->i_inline_all;
+ memcpy(ip->i_link, name, ssize);
+ ip->i_size = ssize - 1;
+
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 3fa2139a0b309..92b1603b5abeb 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -108,15 +108,17 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
+ entry->method = method;
+ entry->id = ksmbd_ipc_id_alloc();
+ if (entry->id < 0)
+- goto error;
++ goto free_entry;
+
+ resp = ksmbd_rpc_open(sess, entry->id);
+ if (!resp)
+- goto error;
++ goto free_id;
+
+ kvfree(resp);
+ return entry->id;
+-error:
++free_id:
++ ksmbd_rpc_id_free(entry->id);
++free_entry:
+ list_del(&entry->list);
+ kfree(entry);
+ return -EINVAL;
+diff --git a/fs/libfs.c b/fs/libfs.c
+index 31b0ddf01c31d..76fb29a103a2f 100644
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -994,8 +994,8 @@ out:
+ EXPORT_SYMBOL_GPL(simple_attr_read);
+
+ /* interpret the buffer as a number to call the set function with */
+-ssize_t simple_attr_write(struct file *file, const char __user *buf,
+- size_t len, loff_t *ppos)
++static ssize_t simple_attr_write_xsigned(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos, bool is_signed)
+ {
+ struct simple_attr *attr;
+ unsigned long long val;
+@@ -1016,7 +1016,10 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ goto out;
+
+ attr->set_buf[size] = '\0';
+- ret = kstrtoull(attr->set_buf, 0, &val);
++ if (is_signed)
++ ret = kstrtoll(attr->set_buf, 0, &val);
++ else
++ ret = kstrtoull(attr->set_buf, 0, &val);
+ if (ret)
+ goto out;
+ ret = attr->set(attr->data, val);
+@@ -1026,8 +1029,21 @@ out:
+ mutex_unlock(&attr->mutex);
+ return ret;
+ }
++
++ssize_t simple_attr_write(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ return simple_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(simple_attr_write);
+
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ return simple_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(simple_attr_write_signed);
++
+ /**
+ * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+ * @sb: filesystem to do the file handle conversion on
+diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
+index e1c4617de7714..3515f17eaf3fb 100644
+--- a/fs/lockd/svcsubs.c
++++ b/fs/lockd/svcsubs.c
+@@ -176,7 +176,7 @@ nlm_delete_file(struct nlm_file *file)
+ }
+ }
+
+-static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner)
++static int nlm_unlock_files(struct nlm_file *file, const struct file_lock *fl)
+ {
+ struct file_lock lock;
+
+@@ -184,12 +184,15 @@ static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner)
+ lock.fl_type = F_UNLCK;
+ lock.fl_start = 0;
+ lock.fl_end = OFFSET_MAX;
+- lock.fl_owner = owner;
+- if (file->f_file[O_RDONLY] &&
+- vfs_lock_file(file->f_file[O_RDONLY], F_SETLK, &lock, NULL))
++ lock.fl_owner = fl->fl_owner;
++ lock.fl_pid = fl->fl_pid;
++ lock.fl_flags = FL_POSIX;
++
++ lock.fl_file = file->f_file[O_RDONLY];
++ if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL))
+ goto out_err;
+- if (file->f_file[O_WRONLY] &&
+- vfs_lock_file(file->f_file[O_WRONLY], F_SETLK, &lock, NULL))
++ lock.fl_file = file->f_file[O_WRONLY];
++ if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL))
+ goto out_err;
+ return 0;
+ out_err:
+@@ -226,7 +229,7 @@ again:
+ if (match(lockhost, host)) {
+
+ spin_unlock(&flctx->flc_lock);
+- if (nlm_unlock_files(file, fl->fl_owner))
++ if (nlm_unlock_files(file, fl))
+ return 1;
+ goto again;
+ }
+diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
+index 4da701fd1424f..0c330bc13ef20 100644
+--- a/fs/nfs/fs_context.c
++++ b/fs/nfs/fs_context.c
+@@ -684,6 +684,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ return ret;
+ break;
+ case Opt_vers:
++ if (!param->string)
++ goto out_invalid_value;
+ trace_nfs_mount_assign(param->key, param->string);
+ ret = nfs_parse_version_string(fc, param->string);
+ if (ret < 0)
+@@ -696,6 +698,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ break;
+
+ case Opt_proto:
++ if (!param->string)
++ goto out_invalid_value;
+ trace_nfs_mount_assign(param->key, param->string);
+ protofamily = AF_INET;
+ switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+@@ -732,6 +736,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ break;
+
+ case Opt_mountproto:
++ if (!param->string)
++ goto out_invalid_value;
+ trace_nfs_mount_assign(param->key, param->string);
+ mountfamily = AF_INET;
+ switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 898dd95bc7a7c..c194a1e50f0bc 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -741,12 +741,10 @@ unsigned long nfs_io_size(unsigned long iosize, enum xprt_transports proto)
+ iosize = NFS_DEF_FILE_IO_SIZE;
+ else if (iosize >= NFS_MAX_FILE_IO_SIZE)
+ iosize = NFS_MAX_FILE_IO_SIZE;
+- else
+- iosize = iosize & PAGE_MASK;
+
+- if (proto == XPRT_TRANSPORT_UDP)
++ if (proto == XPRT_TRANSPORT_UDP || iosize < PAGE_SIZE)
+ return nfs_block_bits(iosize, NULL);
+- return iosize;
++ return iosize & PAGE_MASK;
+ }
+
+ /*
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 3295af4110f1b..c7363d9e11bf2 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -147,7 +147,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
+ struct nfs_fs_context *ctx;
+ struct fs_context *fc;
+ struct vfsmount *mnt = ERR_PTR(-ENOMEM);
+- struct nfs_server *server = NFS_SERVER(d_inode(path->dentry));
++ struct nfs_server *server = NFS_SB(path->dentry->d_sb);
+ struct nfs_client *client = server->nfs_client;
+ int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
+ int ret;
+diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
+index b56f05113d367..f742c7a5745e0 100644
+--- a/fs/nfs/nfs42xdr.c
++++ b/fs/nfs/nfs42xdr.c
+@@ -1134,7 +1134,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
+ if (!segs)
+ return -ENOMEM;
+
+- xdr_set_scratch_buffer(xdr, &scratch_buf, 32);
++ xdr_set_scratch_buffer(xdr, &scratch_buf, sizeof(scratch_buf));
+ status = -EIO;
+ for (i = 0; i < segments; i++) {
+ status = decode_read_plus_segment(xdr, &segs[i]);
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 313e9145b6c9f..6e247647a5fb6 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -122,6 +122,11 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
+ if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
+ return NULL;
+
++ label->lfs = 0;
++ label->pi = 0;
++ label->len = 0;
++ label->label = NULL;
++
+ err = security_dentry_init_security(dentry, sattr->ia_mode,
+ &dentry->d_name, NULL,
+ (void **)&label->label, &label->len);
+@@ -2125,18 +2130,18 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
+ }
+
+ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
+- fmode_t fmode)
++ fmode_t fmode)
+ {
+ struct nfs4_state *newstate;
++ struct nfs_server *server = NFS_SB(opendata->dentry->d_sb);
++ int openflags = opendata->o_arg.open_flags;
+ int ret;
+
+ if (!nfs4_mode_match_open_stateid(opendata->state, fmode))
+ return 0;
+- opendata->o_arg.open_flags = 0;
+ opendata->o_arg.fmode = fmode;
+- opendata->o_arg.share_access = nfs4_map_atomic_open_share(
+- NFS_SB(opendata->dentry->d_sb),
+- fmode, 0);
++ opendata->o_arg.share_access =
++ nfs4_map_atomic_open_share(server, fmode, openflags);
+ memset(&opendata->o_res, 0, sizeof(opendata->o_res));
+ memset(&opendata->c_res, 0, sizeof(opendata->c_res));
+ nfs4_init_opendata_res(opendata);
+@@ -2718,10 +2723,15 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
+ struct nfs4_opendata *opendata;
+ int ret;
+
+- opendata = nfs4_open_recoverdata_alloc(ctx, state,
+- NFS4_OPEN_CLAIM_FH);
++ opendata = nfs4_open_recoverdata_alloc(ctx, state, NFS4_OPEN_CLAIM_FH);
+ if (IS_ERR(opendata))
+ return PTR_ERR(opendata);
++ /*
++ * We're not recovering a delegation, so ask for no delegation.
++ * Otherwise the recovery thread could deadlock with an outstanding
++ * delegation return.
++ */
++ opendata->o_arg.open_flags = O_DIRECT;
+ ret = nfs4_open_recover(opendata, state);
+ if (ret == -ESTALE)
+ d_drop(ctx->dentry);
+@@ -3795,7 +3805,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
+ int open_flags, struct iattr *attr, int *opened)
+ {
+ struct nfs4_state *state;
+- struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
++ struct nfs4_label l, *label;
+
+ label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
+
+@@ -4012,7 +4022,7 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
+
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+- return -ENOMEM;
++ goto out_put_cred;
+ locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
+ if (!locations)
+ goto out_free;
+@@ -4034,6 +4044,8 @@ out_free_2:
+ kfree(locations);
+ out_free:
+ __free_page(page);
++out_put_cred:
++ put_cred(cred);
+ return status;
+ }
+
+@@ -4681,7 +4693,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+ int flags)
+ {
+ struct nfs_server *server = NFS_SERVER(dir);
+- struct nfs4_label l, *ilabel = NULL;
++ struct nfs4_label l, *ilabel;
+ struct nfs_open_context *ctx;
+ struct nfs4_state *state;
+ int status = 0;
+@@ -5032,7 +5044,7 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+ struct nfs4_exception exception = {
+ .interruptible = true,
+ };
+- struct nfs4_label l, *label = NULL;
++ struct nfs4_label l, *label;
+ int err;
+
+ label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -5073,7 +5085,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
+ struct nfs4_exception exception = {
+ .interruptible = true,
+ };
+- struct nfs4_label l, *label = NULL;
++ struct nfs4_label l, *label;
+ int err;
+
+ label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -5192,7 +5204,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
+ struct nfs4_exception exception = {
+ .interruptible = true,
+ };
+- struct nfs4_label l, *label = NULL;
++ struct nfs4_label l, *label;
+ int err;
+
+ label = nfs4_label_init_security(dir, dentry, sattr, &l);
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index a629d7db9420a..0774355249c93 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1232,6 +1232,8 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
+ if (IS_ERR(task)) {
+ printk(KERN_ERR "%s: kthread_run: %ld\n",
+ __func__, PTR_ERR(task));
++ if (!nfs_client_init_is_complete(clp))
++ nfs_mark_client_ready(clp, PTR_ERR(task));
+ nfs4_clear_state_manager_bit(clp);
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+ nfs_put_client(clp);
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index acfe5f4bda480..deec76cf5afea 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -4234,19 +4234,17 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
+ p = xdr_inline_decode(xdr, len);
+ if (unlikely(!p))
+ return -EIO;
++ bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+ if (len < NFS4_MAXLABELLEN) {
+- if (label) {
+- if (label->len) {
+- if (label->len < len)
+- return -ERANGE;
+- memcpy(label->label, p, len);
+- }
++ if (label && label->len) {
++ if (label->len < len)
++ return -ERANGE;
++ memcpy(label->label, p, len);
+ label->len = len;
+ label->pi = pi;
+ label->lfs = lfs;
+ status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
+ }
+- bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+ } else
+ printk(KERN_WARNING "%s: label too long (%u)!\n",
+ __func__, len);
+@@ -4755,12 +4753,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
+ if (status < 0)
+ goto xdr_error;
+
+- if (fattr->label) {
+- status = decode_attr_security_label(xdr, bitmap, fattr->label);
+- if (status < 0)
+- goto xdr_error;
+- fattr->valid |= status;
+- }
++ status = decode_attr_security_label(xdr, bitmap, fattr->label);
++ if (status < 0)
++ goto xdr_error;
++ fattr->valid |= status;
+
+ xdr_error:
+ dprintk("%s: xdr returned %d\n", __func__, -status);
+diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
+index 9edd3c1a30fb1..87f224cd30a85 100644
+--- a/fs/nfsd/nfs2acl.c
++++ b/fs/nfsd/nfs2acl.c
+@@ -246,7 +246,6 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ struct nfsd3_getaclres *resp = rqstp->rq_resp;
+ struct dentry *dentry = resp->fh.fh_dentry;
+ struct inode *inode;
+- int w;
+
+ if (!svcxdr_encode_stat(xdr, resp->status))
+ return false;
+@@ -260,15 +259,6 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
+ return false;
+
+- rqstp->rq_res.page_len = w = nfsacl_size(
+- (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
+- (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+- while (w > 0) {
+- if (!*(rqstp->rq_next_page++))
+- return true;
+- w -= PAGE_SIZE;
+- }
+-
+ if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
+ resp->mask & NFS_ACL, 0))
+ return false;
+diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
+index 9446c67436649..7c798b5f4ec68 100644
+--- a/fs/nfsd/nfs3acl.c
++++ b/fs/nfsd/nfs3acl.c
+@@ -171,11 +171,7 @@ nfs3svc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ {
+ struct nfsd3_getaclres *resp = rqstp->rq_resp;
+ struct dentry *dentry = resp->fh.fh_dentry;
+- struct kvec *head = rqstp->rq_res.head;
+ struct inode *inode;
+- unsigned int base;
+- int n;
+- int w;
+
+ if (!svcxdr_encode_nfsstat3(xdr, resp->status))
+ return false;
+@@ -187,26 +183,12 @@ nfs3svc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
+ return false;
+
+- base = (char *)xdr->p - (char *)head->iov_base;
+-
+- rqstp->rq_res.page_len = w = nfsacl_size(
+- (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
+- (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+- while (w > 0) {
+- if (!*(rqstp->rq_next_page++))
+- return false;
+- w -= PAGE_SIZE;
+- }
+-
+- n = nfsacl_encode(&rqstp->rq_res, base, inode,
+- resp->acl_access,
+- resp->mask & NFS_ACL, 0);
+- if (n > 0)
+- n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
+- resp->acl_default,
+- resp->mask & NFS_DFACL,
+- NFS_ACL_DEFAULT);
+- if (n <= 0)
++ if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
++ resp->mask & NFS_ACL, 0))
++ return false;
++ if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
++ resp->mask & NFS_DFACL,
++ NFS_ACL_DEFAULT))
+ return false;
+ break;
+ default:
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 4ce328209f614..775d38dc00fef 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -916,7 +916,6 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+ } else {
+ if (!conn->cb_xprt)
+ return -EINVAL;
+- clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+ clp->cl_cb_session = ses;
+ args.bc_xprt = conn->cb_xprt;
+ args.prognumber = clp->cl_cb_session->se_cb_prog;
+@@ -936,6 +935,9 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+ rpc_shutdown_client(client);
+ return -ENOMEM;
+ }
++
++ if (clp->cl_minorversion != 0)
++ clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+ clp->cl_cb_client = client;
+ clp->cl_cb_cred = cred;
+ rcu_read_lock();
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 6ba25a5b76e17..cfc2da4456587 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1141,6 +1141,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 0, (time64_t)0);
+ if (!status)
+ status = nfserrno(attrs.na_labelerr);
++ if (!status)
++ status = nfserrno(attrs.na_aclerr);
+ out:
+ nfsd_attrs_free(&attrs);
+ fh_drop_write(&cstate->current_fh);
+@@ -1648,6 +1650,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
+ u64 src_pos = copy->cp_src_pos;
+ u64 dst_pos = copy->cp_dst_pos;
+ int status;
++ loff_t end;
+
+ /* See RFC 7862 p.67: */
+ if (bytes_total == 0)
+@@ -1667,8 +1670,8 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
+ /* for a non-zero asynchronous copy do a commit of data */
+ if (nfsd4_copy_is_async(copy) && copy->cp_res.wr_bytes_written > 0) {
+ since = READ_ONCE(dst->f_wb_err);
+- status = vfs_fsync_range(dst, copy->cp_dst_pos,
+- copy->cp_res.wr_bytes_written, 0);
++ end = copy->cp_dst_pos + copy->cp_res.wr_bytes_written - 1;
++ status = vfs_fsync_range(dst, copy->cp_dst_pos, end, 0);
+ if (!status)
+ status = filemap_check_wb_err(dst->f_mapping, since);
+ if (!status)
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index ddb2bf078fdaf..94420fad4c410 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -664,15 +664,26 @@ find_any_file(struct nfs4_file *f)
+ return ret;
+ }
+
+-static struct nfsd_file *find_deleg_file(struct nfs4_file *f)
++static struct nfsd_file *find_any_file_locked(struct nfs4_file *f)
+ {
+- struct nfsd_file *ret = NULL;
++ lockdep_assert_held(&f->fi_lock);
++
++ if (f->fi_fds[O_RDWR])
++ return f->fi_fds[O_RDWR];
++ if (f->fi_fds[O_WRONLY])
++ return f->fi_fds[O_WRONLY];
++ if (f->fi_fds[O_RDONLY])
++ return f->fi_fds[O_RDONLY];
++ return NULL;
++}
++
++static struct nfsd_file *find_deleg_file_locked(struct nfs4_file *f)
++{
++ lockdep_assert_held(&f->fi_lock);
+
+- spin_lock(&f->fi_lock);
+ if (f->fi_deleg_file)
+- ret = nfsd_file_get(f->fi_deleg_file);
+- spin_unlock(&f->fi_lock);
+- return ret;
++ return f->fi_deleg_file;
++ return NULL;
+ }
+
+ static atomic_long_t num_delegations;
+@@ -2606,9 +2617,11 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+ ols = openlockstateid(st);
+ oo = ols->st_stateowner;
+ nf = st->sc_file;
+- file = find_any_file(nf);
++
++ spin_lock(&nf->fi_lock);
++ file = find_any_file_locked(nf);
+ if (!file)
+- return 0;
++ goto out;
+
+ seq_printf(s, "- ");
+ nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2630,8 +2643,8 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+ seq_printf(s, ", ");
+ nfs4_show_owner(s, oo);
+ seq_printf(s, " }\n");
+- nfsd_file_put(file);
+-
++out:
++ spin_unlock(&nf->fi_lock);
+ return 0;
+ }
+
+@@ -2645,9 +2658,10 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+ ols = openlockstateid(st);
+ oo = ols->st_stateowner;
+ nf = st->sc_file;
+- file = find_any_file(nf);
++ spin_lock(&nf->fi_lock);
++ file = find_any_file_locked(nf);
+ if (!file)
+- return 0;
++ goto out;
+
+ seq_printf(s, "- ");
+ nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2667,8 +2681,8 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+ seq_printf(s, ", ");
+ nfs4_show_owner(s, oo);
+ seq_printf(s, " }\n");
+- nfsd_file_put(file);
+-
++out:
++ spin_unlock(&nf->fi_lock);
+ return 0;
+ }
+
+@@ -2680,9 +2694,10 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+
+ ds = delegstateid(st);
+ nf = st->sc_file;
+- file = find_deleg_file(nf);
++ spin_lock(&nf->fi_lock);
++ file = find_deleg_file_locked(nf);
+ if (!file)
+- return 0;
++ goto out;
+
+ seq_printf(s, "- ");
+ nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2698,8 +2713,8 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+ seq_printf(s, ", ");
+ nfs4_show_fname(s, file);
+ seq_printf(s, " }\n");
+- nfsd_file_put(file);
+-
++out:
++ spin_unlock(&nf->fi_lock);
+ return 0;
+ }
+
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index c8b89b4f94e0e..2064e6473d304 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -13,6 +13,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/backing-dev.h>
+ #include <linux/random.h>
++#include <linux/log2.h>
+ #include <linux/crc32.h>
+ #include "nilfs.h"
+ #include "segment.h"
+@@ -192,6 +193,34 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
+ return ret;
+ }
+
++/**
++ * nilfs_get_blocksize - get block size from raw superblock data
++ * @sb: super block instance
++ * @sbp: superblock raw data buffer
++ * @blocksize: place to store block size
++ *
++ * nilfs_get_blocksize() calculates the block size from the block size
++ * exponent information written in @sbp and stores it in @blocksize,
++ * or aborts with an error message if it's too large.
++ *
++ * Return Value: On success, 0 is returned. If the block size is too
++ * large, -EINVAL is returned.
++ */
++static int nilfs_get_blocksize(struct super_block *sb,
++ struct nilfs_super_block *sbp, int *blocksize)
++{
++ unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++
++ if (unlikely(shift_bits >
++ ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) {
++ nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB",
++ shift_bits);
++ return -EINVAL;
++ }
++ *blocksize = BLOCK_SIZE << shift_bits;
++ return 0;
++}
++
+ /**
+ * load_nilfs - load and recover the nilfs
+ * @nilfs: the_nilfs structure to be released
+@@ -245,11 +274,15 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
+
+ /* verify consistency between two super blocks */
+- blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
++ err = nilfs_get_blocksize(sb, sbp[0], &blocksize);
++ if (err)
++ goto scan_error;
++
+ if (blocksize != nilfs->ns_blocksize) {
+ nilfs_warn(sb,
+ "blocksize differs between two super blocks (%d != %d)",
+ blocksize, nilfs->ns_blocksize);
++ err = -EINVAL;
+ goto scan_error;
+ }
+
+@@ -443,11 +476,33 @@ static int nilfs_valid_sb(struct nilfs_super_block *sbp)
+ return crc == le32_to_cpu(sbp->s_sum);
+ }
+
+-static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
++/**
++ * nilfs_sb2_bad_offset - check the location of the second superblock
++ * @sbp: superblock raw data buffer
++ * @offset: byte offset of second superblock calculated from device size
++ *
++ * nilfs_sb2_bad_offset() checks if the position on the second
++ * superblock is valid or not based on the filesystem parameters
++ * stored in @sbp. If @offset points to a location within the segment
++ * area, or if the parameters themselves are not normal, it is
++ * determined to be invalid.
++ *
++ * Return Value: true if invalid, false if valid.
++ */
++static bool nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
+ {
+- return offset < ((le64_to_cpu(sbp->s_nsegments) *
+- le32_to_cpu(sbp->s_blocks_per_segment)) <<
+- (le32_to_cpu(sbp->s_log_block_size) + 10));
++ unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++ u32 blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
++ u64 nsegments = le64_to_cpu(sbp->s_nsegments);
++ u64 index;
++
++ if (blocks_per_segment < NILFS_SEG_MIN_BLOCKS ||
++ shift_bits > ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)
++ return true;
++
++ index = offset >> (shift_bits + BLOCK_SIZE_BITS);
++ do_div(index, blocks_per_segment);
++ return index < nsegments;
+ }
+
+ static void nilfs_release_super_block(struct the_nilfs *nilfs)
+@@ -586,9 +641,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+ if (err)
+ goto failed_sbh;
+
+- blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+- if (blocksize < NILFS_MIN_BLOCK_SIZE ||
+- blocksize > NILFS_MAX_BLOCK_SIZE) {
++ err = nilfs_get_blocksize(sb, sbp, &blocksize);
++ if (err)
++ goto failed_sbh;
++
++ if (blocksize < NILFS_MIN_BLOCK_SIZE) {
+ nilfs_err(sb,
+ "couldn't mount because of unsupported filesystem blocksize %d",
+ blocksize);
+diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
+index 5d44ceac855b7..087282cb130b7 100644
+--- a/fs/ntfs3/bitmap.c
++++ b/fs/ntfs3/bitmap.c
+@@ -1424,7 +1424,7 @@ int ntfs_trim_fs(struct ntfs_sb_info *sbi, struct fstrim_range *range)
+
+ down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
+
+- for (; iw < wnd->nbits; iw++, wbit = 0) {
++ for (; iw < wnd->nwnd; iw++, wbit = 0) {
+ CLST lcn_wnd = iw * wbits;
+ struct buffer_head *bh;
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 47012c9bf505e..adc4f73722b7c 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -672,7 +672,7 @@ static u32 true_sectors_per_clst(const struct NTFS_BOOT *boot)
+ if (boot->sectors_per_clusters <= 0x80)
+ return boot->sectors_per_clusters;
+ if (boot->sectors_per_clusters >= 0xf4) /* limit shift to 2MB max */
+- return 1U << (0 - boot->sectors_per_clusters);
++ return 1U << -(s8)boot->sectors_per_clusters;
+ return -EINVAL;
+ }
+
+diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
+index 7de8718c68a90..ea582b4fe1d9d 100644
+--- a/fs/ntfs3/xattr.c
++++ b/fs/ntfs3/xattr.c
+@@ -107,7 +107,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
+ return -EFBIG;
+
+ /* Allocate memory for packed Ea. */
+- ea_p = kmalloc(size + add_bytes, GFP_NOFS);
++ ea_p = kmalloc(size_add(size, add_bytes), GFP_NOFS);
+ if (!ea_p)
+ return -ENOMEM;
+
+diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
+index fa87d89cf7542..1be7d440eff37 100644
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -157,7 +157,7 @@ static void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
+ replay_map->rm_state = REPLAY_DONE;
+ }
+
+-static void ocfs2_free_replay_slots(struct ocfs2_super *osb)
++void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+ {
+ struct ocfs2_replay_map *replay_map = osb->replay_map;
+
+diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
+index 969d0aa287187..41c382f68529e 100644
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -150,6 +150,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb);
+ void ocfs2_recovery_exit(struct ocfs2_super *osb);
+
+ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
++void ocfs2_free_replay_slots(struct ocfs2_super *osb);
+ /*
+ * Journal Control:
+ * Initialize, Load, Shutdown, Wipe a journal.
+diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
+index dd77b7aaabf5c..3633da5f71179 100644
+--- a/fs/ocfs2/stackglue.c
++++ b/fs/ocfs2/stackglue.c
+@@ -669,6 +669,8 @@ static struct ctl_table_header *ocfs2_table_header;
+
+ static int __init ocfs2_stack_glue_init(void)
+ {
++ int ret;
++
+ strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
+
+ ocfs2_table_header = register_sysctl("fs/ocfs2/nm", ocfs2_nm_table);
+@@ -678,7 +680,11 @@ static int __init ocfs2_stack_glue_init(void)
+ return -ENOMEM; /* or something. */
+ }
+
+- return ocfs2_sysfs_init();
++ ret = ocfs2_sysfs_init();
++ if (ret)
++ unregister_sysctl_table(ocfs2_table_header);
++
++ return ret;
+ }
+
+ static void __exit ocfs2_stack_glue_exit(void)
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index e2cc9eec287c9..78441e466e6fd 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1159,6 +1159,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+ out_dismount:
+ atomic_set(&osb->vol_state, VOLUME_DISABLED);
+ wake_up(&osb->osb_mount_event);
++ ocfs2_free_replay_slots(osb);
+ ocfs2_dismount_volume(sb, 1);
+ goto out;
+
+@@ -1824,12 +1825,14 @@ static int ocfs2_mount_volume(struct super_block *sb)
+ status = ocfs2_truncate_log_init(osb);
+ if (status < 0) {
+ mlog_errno(status);
+- goto out_system_inodes;
++ goto out_check_volume;
+ }
+
+ ocfs2_super_unlock(osb, 1);
+ return 0;
+
++out_check_volume:
++ ocfs2_free_replay_slots(osb);
+ out_system_inodes:
+ if (osb->local_alloc_state == OCFS2_LA_ENABLED)
+ ocfs2_shutdown_local_alloc(osb);
+diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
+index 29eaa45443727..1b508f5433846 100644
+--- a/fs/orangefs/orangefs-debugfs.c
++++ b/fs/orangefs/orangefs-debugfs.c
+@@ -194,15 +194,10 @@ void orangefs_debugfs_init(int debug_mask)
+ */
+ static void orangefs_kernel_debug_init(void)
+ {
+- int rc = -ENOMEM;
+- char *k_buffer = NULL;
++ static char k_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+
+ gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+
+- k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+- if (!k_buffer)
+- goto out;
+-
+ if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+ strcpy(k_buffer, kernel_debug_string);
+ strcat(k_buffer, "\n");
+@@ -213,15 +208,14 @@ static void orangefs_kernel_debug_init(void)
+
+ debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer,
+ &kernel_debug_fops);
+-
+-out:
+- gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+ }
+
+
+ void orangefs_debugfs_cleanup(void)
+ {
+ debugfs_remove_recursive(debug_dir);
++ kfree(debug_help_string);
++ debug_help_string = NULL;
+ }
+
+ /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
+@@ -297,18 +291,13 @@ static int help_show(struct seq_file *m, void *v)
+ /*
+ * initialize the client-debug file.
+ */
+-static int orangefs_client_debug_init(void)
++static void orangefs_client_debug_init(void)
+ {
+
+- int rc = -ENOMEM;
+- char *c_buffer = NULL;
++ static char c_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+
+ gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+
+- c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+- if (!c_buffer)
+- goto out;
+-
+ if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+ strcpy(c_buffer, client_debug_string);
+ strcat(c_buffer, "\n");
+@@ -322,13 +311,6 @@ static int orangefs_client_debug_init(void)
+ debug_dir,
+ c_buffer,
+ &kernel_debug_fops);
+-
+- rc = 0;
+-
+-out:
+-
+- gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+- return rc;
+ }
+
+ /* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
+@@ -671,6 +653,7 @@ int orangefs_prepare_debugfs_help_string(int at_boot)
+ memset(debug_help_string, 0, DEBUG_HELP_STRING_SIZE);
+ strlcat(debug_help_string, new, string_size);
+ mutex_unlock(&orangefs_help_file_lock);
++ kfree(new);
+ }
+
+ rc = 0;
+diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c
+index cd7297815f91e..5ab741c60b7e2 100644
+--- a/fs/orangefs/orangefs-mod.c
++++ b/fs/orangefs/orangefs-mod.c
+@@ -141,7 +141,7 @@ static int __init orangefs_init(void)
+ gossip_err("%s: could not initialize device subsystem %d!\n",
+ __func__,
+ ret);
+- goto cleanup_device;
++ goto cleanup_sysfs;
+ }
+
+ ret = register_filesystem(&orangefs_fs_type);
+@@ -152,11 +152,11 @@ static int __init orangefs_init(void)
+ goto out;
+ }
+
+- orangefs_sysfs_exit();
+-
+-cleanup_device:
+ orangefs_dev_cleanup();
+
++cleanup_sysfs:
++ orangefs_sysfs_exit();
++
+ sysfs_init_failed:
+ orangefs_debugfs_cleanup();
+
+diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c
+index de80b62553bb1..be4ba03a01a0f 100644
+--- a/fs/orangefs/orangefs-sysfs.c
++++ b/fs/orangefs/orangefs-sysfs.c
+@@ -896,9 +896,18 @@ static struct attribute *orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(orangefs_default);
+
++static struct kobject *orangefs_obj;
++
++static void orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(orangefs_obj);
++ orangefs_obj = NULL;
++}
++
+ static struct kobj_type orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = orangefs_default_groups,
++ .release = orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute acache_hard_limit_attribute =
+@@ -934,9 +943,18 @@ static struct attribute *acache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(acache_orangefs_default);
+
++static struct kobject *acache_orangefs_obj;
++
++static void acache_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(acache_orangefs_obj);
++ acache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type acache_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = acache_orangefs_default_groups,
++ .release = acache_orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute capcache_hard_limit_attribute =
+@@ -972,9 +990,18 @@ static struct attribute *capcache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(capcache_orangefs_default);
+
++static struct kobject *capcache_orangefs_obj;
++
++static void capcache_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(capcache_orangefs_obj);
++ capcache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type capcache_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = capcache_orangefs_default_groups,
++ .release = capcache_orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute ccache_hard_limit_attribute =
+@@ -1010,9 +1037,18 @@ static struct attribute *ccache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(ccache_orangefs_default);
+
++static struct kobject *ccache_orangefs_obj;
++
++static void ccache_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(ccache_orangefs_obj);
++ ccache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type ccache_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = ccache_orangefs_default_groups,
++ .release = ccache_orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute ncache_hard_limit_attribute =
+@@ -1048,9 +1084,18 @@ static struct attribute *ncache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(ncache_orangefs_default);
+
++static struct kobject *ncache_orangefs_obj;
++
++static void ncache_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(ncache_orangefs_obj);
++ ncache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type ncache_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = ncache_orangefs_default_groups,
++ .release = ncache_orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute pc_acache_attribute =
+@@ -1079,9 +1124,18 @@ static struct attribute *pc_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(pc_orangefs_default);
+
++static struct kobject *pc_orangefs_obj;
++
++static void pc_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(pc_orangefs_obj);
++ pc_orangefs_obj = NULL;
++}
++
+ static struct kobj_type pc_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = pc_orangefs_default_groups,
++ .release = pc_orangefs_obj_release,
+ };
+
+ static struct orangefs_attribute stats_reads_attribute =
+@@ -1103,19 +1157,20 @@ static struct attribute *stats_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(stats_orangefs_default);
+
++static struct kobject *stats_orangefs_obj;
++
++static void stats_orangefs_obj_release(struct kobject *kobj)
++{
++ kfree(stats_orangefs_obj);
++ stats_orangefs_obj = NULL;
++}
++
+ static struct kobj_type stats_orangefs_ktype = {
+ .sysfs_ops = &orangefs_sysfs_ops,
+ .default_groups = stats_orangefs_default_groups,
++ .release = stats_orangefs_obj_release,
+ };
+
+-static struct kobject *orangefs_obj;
+-static struct kobject *acache_orangefs_obj;
+-static struct kobject *capcache_orangefs_obj;
+-static struct kobject *ccache_orangefs_obj;
+-static struct kobject *ncache_orangefs_obj;
+-static struct kobject *pc_orangefs_obj;
+-static struct kobject *stats_orangefs_obj;
+-
+ int orangefs_sysfs_init(void)
+ {
+ int rc = -EINVAL;
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index daff601b5c410..a34f8042724ce 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -517,9 +517,16 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
+ const struct cred *old_cred;
+ int ret;
+
++ inode_lock(inode);
++ /* Update mode */
++ ovl_copyattr(inode);
++ ret = file_remove_privs(file);
++ if (ret)
++ goto out_unlock;
++
+ ret = ovl_real_fdget(file, &real);
+ if (ret)
+- return ret;
++ goto out_unlock;
+
+ old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ ret = vfs_fallocate(real.file, mode, offset, len);
+@@ -530,6 +537,9 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
+
+ fdput(real);
+
++out_unlock:
++ inode_unlock(inode);
++
+ return ret;
+ }
+
+@@ -567,14 +577,23 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+ const struct cred *old_cred;
+ loff_t ret;
+
++ inode_lock(inode_out);
++ if (op != OVL_DEDUPE) {
++ /* Update mode */
++ ovl_copyattr(inode_out);
++ ret = file_remove_privs(file_out);
++ if (ret)
++ goto out_unlock;
++ }
++
+ ret = ovl_real_fdget(file_out, &real_out);
+ if (ret)
+- return ret;
++ goto out_unlock;
+
+ ret = ovl_real_fdget(file_in, &real_in);
+ if (ret) {
+ fdput(real_out);
+- return ret;
++ goto out_unlock;
+ }
+
+ old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
+@@ -603,6 +622,9 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+ fdput(real_in);
+ fdput(real_out);
+
++out_unlock:
++ inode_unlock(inode_out);
++
+ return ret;
+ }
+
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index ec746d447f1bb..79a77aa6892cb 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -138,11 +138,16 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry,
+ unsigned int flags, bool weak)
+ {
+ struct ovl_entry *oe = dentry->d_fsdata;
++ struct inode *inode = d_inode_rcu(dentry);
+ struct dentry *upper;
+ unsigned int i;
+ int ret = 1;
+
+- upper = ovl_dentry_upper(dentry);
++ /* Careful in RCU mode */
++ if (!inode)
++ return -ECHILD;
++
++ upper = ovl_i_dentry_upper(inode);
+ if (upper)
+ ret = ovl_revalidate_real(upper, flags, weak);
+
+diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
+index 8adabde685f13..c49d554cc9ae9 100644
+--- a/fs/pstore/Kconfig
++++ b/fs/pstore/Kconfig
+@@ -126,6 +126,7 @@ config PSTORE_CONSOLE
+ config PSTORE_PMSG
+ bool "Log user space messages"
+ depends on PSTORE
++ select RT_MUTEXES
+ help
+ When the option is enabled, pstore will export a character
+ interface /dev/pmsg0 to log user space messages. On reboot
+diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
+index d8542ec2f38c6..18cf94b597e05 100644
+--- a/fs/pstore/pmsg.c
++++ b/fs/pstore/pmsg.c
+@@ -7,9 +7,10 @@
+ #include <linux/device.h>
+ #include <linux/fs.h>
+ #include <linux/uaccess.h>
++#include <linux/rtmutex.h>
+ #include "internal.h"
+
+-static DEFINE_MUTEX(pmsg_lock);
++static DEFINE_RT_MUTEX(pmsg_lock);
+
+ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+@@ -28,9 +29,9 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ if (!access_ok(buf, count))
+ return -EFAULT;
+
+- mutex_lock(&pmsg_lock);
++ rt_mutex_lock(&pmsg_lock);
+ ret = psinfo->write_user(&record, buf);
+- mutex_unlock(&pmsg_lock);
++ rt_mutex_unlock(&pmsg_lock);
+ return ret ? ret : count;
+ }
+
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index fefe3d391d3af..74e4d93f3e08d 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -735,6 +735,7 @@ static int ramoops_probe(struct platform_device *pdev)
+ /* Make sure we didn't get bogus platform data pointer. */
+ if (!pdata) {
+ pr_err("NULL platform data\n");
++ err = -EINVAL;
+ goto fail_out;
+ }
+
+@@ -742,6 +743,7 @@ static int ramoops_probe(struct platform_device *pdev)
+ !pdata->ftrace_size && !pdata->pmsg_size)) {
+ pr_err("The memory size and the record/console size must be "
+ "non-zero\n");
++ err = -EINVAL;
+ goto fail_out;
+ }
+
+diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
+index a89e33719fcf2..8bf09886e7e66 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -439,7 +439,11 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
+ phys_addr_t addr = page_start + i * PAGE_SIZE;
+ pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
+ }
+- vaddr = vmap(pages, page_count, VM_MAP, prot);
++ /*
++ * VM_IOREMAP used here to bypass this region during vread()
++ * and kmap_atomic() (i.e. kcore) to avoid __va() failures.
++ */
++ vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
+ kfree(pages);
+
+ /*
+diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
+index 3d7a35d6a18bc..b916859992ec8 100644
+--- a/fs/reiserfs/namei.c
++++ b/fs/reiserfs/namei.c
+@@ -696,6 +696,7 @@ static int reiserfs_create(struct user_namespace *mnt_userns, struct inode *dir,
+
+ out_failed:
+ reiserfs_write_unlock(dir->i_sb);
++ reiserfs_security_free(&security);
+ return retval;
+ }
+
+@@ -779,6 +780,7 @@ static int reiserfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+
+ out_failed:
+ reiserfs_write_unlock(dir->i_sb);
++ reiserfs_security_free(&security);
+ return retval;
+ }
+
+@@ -878,6 +880,7 @@ static int reiserfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+ retval = journal_end(&th);
+ out_failed:
+ reiserfs_write_unlock(dir->i_sb);
++ reiserfs_security_free(&security);
+ return retval;
+ }
+
+@@ -1194,6 +1197,7 @@ static int reiserfs_symlink(struct user_namespace *mnt_userns,
+ retval = journal_end(&th);
+ out_failed:
+ reiserfs_write_unlock(parent_dir->i_sb);
++ reiserfs_security_free(&security);
+ return retval;
+ }
+
+diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
+index 8965c8e5e172b..857a65b057264 100644
+--- a/fs/reiserfs/xattr_security.c
++++ b/fs/reiserfs/xattr_security.c
+@@ -50,6 +50,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
+ int error;
+
+ sec->name = NULL;
++ sec->value = NULL;
+
+ /* Don't add selinux attributes on xattrs - they'll never get used */
+ if (IS_PRIVATE(dir))
+@@ -95,7 +96,6 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
+
+ void reiserfs_security_free(struct reiserfs_security_handle *sec)
+ {
+- kfree(sec->name);
+ kfree(sec->value);
+ sec->name = NULL;
+ sec->value = NULL;
+diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
+index d4ec9bb97de95..3b8567564e7e4 100644
+--- a/fs/sysv/itree.c
++++ b/fs/sysv/itree.c
+@@ -438,7 +438,7 @@ static unsigned sysv_nblocks(struct super_block *s, loff_t size)
+ res += blocks;
+ direct = 1;
+ }
+- return blocks;
++ return res;
+ }
+
+ int sysv_getattr(struct user_namespace *mnt_userns, const struct path *path,
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index 865e658535b11..0e30a50060d9d 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -1091,8 +1091,9 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ return -EINVAL;
+
+ ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
+- if (IS_ERR(ofi)) {
+- retval = PTR_ERR(ofi);
++ if (!ofi || IS_ERR(ofi)) {
++ if (IS_ERR(ofi))
++ retval = PTR_ERR(ofi);
+ goto end_rename;
+ }
+
+@@ -1101,8 +1102,7 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+
+ brelse(ofibh.sbh);
+ tloc = lelb_to_cpu(ocfi.icb.extLocation);
+- if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
+- != old_inode->i_ino)
++ if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino)
+ goto end_rename;
+
+ nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
+diff --git a/fs/xattr.c b/fs/xattr.c
+index a1f4998bc6be3..8ea6b104b1063 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -1147,7 +1147,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
+ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
+ char *buffer, size_t size)
+ {
+- bool trusted = capable(CAP_SYS_ADMIN);
++ bool trusted = ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
+ struct simple_xattr *xattr;
+ ssize_t remaining_size = size;
+ int err = 0;
+diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
+index 7df7876b2ad56..d9879fc9ceb17 100644
+--- a/include/drm/drm_connector.h
++++ b/include/drm/drm_connector.h
+@@ -635,6 +635,12 @@ struct drm_display_info {
+ * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels.
+ */
+ u8 mso_pixel_overlap;
++
++ /**
++ * @max_dsc_bpp: Maximum DSC target bitrate, if it is set to 0 the
++ * monitor's default value is used instead.
++ */
++ u32 max_dsc_bpp;
+ };
+
+ int drm_display_info_set_bus_formats(struct drm_display_info *info,
+diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
+index 17a0310e8aaaf..b7d3f3843f1e6 100644
+--- a/include/drm/ttm/ttm_tt.h
++++ b/include/drm/ttm/ttm_tt.h
+@@ -88,7 +88,7 @@ struct ttm_tt {
+ #define TTM_TT_FLAG_EXTERNAL (1 << 2)
+ #define TTM_TT_FLAG_EXTERNAL_MAPPABLE (1 << 3)
+
+-#define TTM_TT_FLAG_PRIV_POPULATED (1 << 31)
++#define TTM_TT_FLAG_PRIV_POPULATED (1U << 31)
+ uint32_t page_flags;
+ /** @num_pages: Number of pages in the page array. */
+ uint32_t num_pages;
+diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
+index 07b8a282c2682..04809edab33cf 100644
+--- a/include/dt-bindings/clock/imx8mn-clock.h
++++ b/include/dt-bindings/clock/imx8mn-clock.h
+@@ -16,40 +16,48 @@
+ #define IMX8MN_CLK_EXT4 7
+ #define IMX8MN_AUDIO_PLL1_REF_SEL 8
+ #define IMX8MN_AUDIO_PLL2_REF_SEL 9
+-#define IMX8MN_VIDEO_PLL1_REF_SEL 10
++#define IMX8MN_VIDEO_PLL_REF_SEL 10
++#define IMX8MN_VIDEO_PLL1_REF_SEL IMX8MN_VIDEO_PLL_REF_SEL
+ #define IMX8MN_DRAM_PLL_REF_SEL 11
+ #define IMX8MN_GPU_PLL_REF_SEL 12
+-#define IMX8MN_VPU_PLL_REF_SEL 13
++#define IMX8MN_M7_ALT_PLL_REF_SEL 13
++#define IMX8MN_VPU_PLL_REF_SEL IMX8MN_M7_ALT_PLL_REF_SEL
+ #define IMX8MN_ARM_PLL_REF_SEL 14
+ #define IMX8MN_SYS_PLL1_REF_SEL 15
+ #define IMX8MN_SYS_PLL2_REF_SEL 16
+ #define IMX8MN_SYS_PLL3_REF_SEL 17
+ #define IMX8MN_AUDIO_PLL1 18
+ #define IMX8MN_AUDIO_PLL2 19
+-#define IMX8MN_VIDEO_PLL1 20
++#define IMX8MN_VIDEO_PLL 20
++#define IMX8MN_VIDEO_PLL1 IMX8MN_VIDEO_PLL
+ #define IMX8MN_DRAM_PLL 21
+ #define IMX8MN_GPU_PLL 22
+-#define IMX8MN_VPU_PLL 23
++#define IMX8MN_M7_ALT_PLL 23
++#define IMX8MN_VPU_PLL IMX8MN_M7_ALT_PLL
+ #define IMX8MN_ARM_PLL 24
+ #define IMX8MN_SYS_PLL1 25
+ #define IMX8MN_SYS_PLL2 26
+ #define IMX8MN_SYS_PLL3 27
+ #define IMX8MN_AUDIO_PLL1_BYPASS 28
+ #define IMX8MN_AUDIO_PLL2_BYPASS 29
+-#define IMX8MN_VIDEO_PLL1_BYPASS 30
++#define IMX8MN_VIDEO_PLL_BYPASS 30
++#define IMX8MN_VIDEO_PLL1_BYPASS IMX8MN_VIDEO_PLL_BYPASS
+ #define IMX8MN_DRAM_PLL_BYPASS 31
+ #define IMX8MN_GPU_PLL_BYPASS 32
+-#define IMX8MN_VPU_PLL_BYPASS 33
++#define IMX8MN_M7_ALT_PLL_BYPASS 33
++#define IMX8MN_VPU_PLL_BYPASS IMX8MN_M7_ALT_PLL_BYPASS
+ #define IMX8MN_ARM_PLL_BYPASS 34
+ #define IMX8MN_SYS_PLL1_BYPASS 35
+ #define IMX8MN_SYS_PLL2_BYPASS 36
+ #define IMX8MN_SYS_PLL3_BYPASS 37
+ #define IMX8MN_AUDIO_PLL1_OUT 38
+ #define IMX8MN_AUDIO_PLL2_OUT 39
+-#define IMX8MN_VIDEO_PLL1_OUT 40
++#define IMX8MN_VIDEO_PLL_OUT 40
++#define IMX8MN_VIDEO_PLL1_OUT IMX8MN_VIDEO_PLL_OUT
+ #define IMX8MN_DRAM_PLL_OUT 41
+ #define IMX8MN_GPU_PLL_OUT 42
+-#define IMX8MN_VPU_PLL_OUT 43
++#define IMX8MN_M7_ALT_PLL_OUT 43
++#define IMX8MN_VPU_PLL_OUT IMX8MN_M7_ALT_PLL_OUT
+ #define IMX8MN_ARM_PLL_OUT 44
+ #define IMX8MN_SYS_PLL1_OUT 45
+ #define IMX8MN_SYS_PLL2_OUT 46
+diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
+index 9d5cc2ddde896..1417b7b1b7dfe 100644
+--- a/include/dt-bindings/clock/imx8mp-clock.h
++++ b/include/dt-bindings/clock/imx8mp-clock.h
+@@ -324,8 +324,9 @@
+ #define IMX8MP_CLK_CLKOUT2_SEL 317
+ #define IMX8MP_CLK_CLKOUT2_DIV 318
+ #define IMX8MP_CLK_CLKOUT2 319
++#define IMX8MP_CLK_USB_SUSP 320
+
+-#define IMX8MP_CLK_END 320
++#define IMX8MP_CLK_END 321
+
+ #define IMX8MP_CLK_AUDIOMIX_SAI1_IPG 0
+ #define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1
+diff --git a/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h b/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
+index 20ef2ea673f3b..22dcd47d45139 100644
+--- a/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
++++ b/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
+@@ -24,6 +24,11 @@
+ #define LPASS_AUDIO_CC_RX_MCLK_CLK 14
+ #define LPASS_AUDIO_CC_RX_MCLK_CLK_SRC 15
+
++/* LPASS AUDIO CC CSR */
++#define LPASS_AUDIO_SWR_RX_CGCR 0
++#define LPASS_AUDIO_SWR_TX_CGCR 1
++#define LPASS_AUDIO_SWR_WSA_CGCR 2
++
+ /* LPASS_AON_CC clocks */
+ #define LPASS_AON_CC_PLL 0
+ #define LPASS_AON_CC_PLL_OUT_EVEN 1
+diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
+index 28ed2a07aacc3..0324c69ce9686 100644
+--- a/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
++++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
+@@ -19,6 +19,8 @@
+ #define LPASS_CORE_CC_LPM_CORE_CLK 9
+ #define LPASS_CORE_CC_LPM_MEM0_CORE_CLK 10
+ #define LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK 11
++#define LPASS_CORE_CC_EXT_MCLK0_CLK 12
++#define LPASS_CORE_CC_EXT_MCLK0_CLK_SRC 13
+
+ /* LPASS_CORE_CC power domains */
+ #define LPASS_CORE_CC_LPASS_CORE_HM_GDSC 0
+diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h
+index 2aea877d644f8..2b98720084285 100644
+--- a/include/linux/btf_ids.h
++++ b/include/linux/btf_ids.h
+@@ -204,7 +204,7 @@ extern struct btf_id_set8 name;
+
+ #else
+
+-#define BTF_ID_LIST(name) static u32 __maybe_unused name[5];
++#define BTF_ID_LIST(name) static u32 __maybe_unused name[16];
+ #define BTF_ID(prefix, name)
+ #define BTF_ID_FLAGS(prefix, name, ...)
+ #define BTF_ID_UNUSED
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index f60674692d365..ea2d919fd9c79 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -45,7 +45,7 @@ struct debugfs_u32_array {
+
+ extern struct dentry *arch_debugfs_dir;
+
+-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
++#define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed) \
+ static int __fops ## _open(struct inode *inode, struct file *file) \
+ { \
+ __simple_attr_check_format(__fmt, 0ull); \
+@@ -56,10 +56,16 @@ static const struct file_operations __fops = { \
+ .open = __fops ## _open, \
+ .release = simple_attr_release, \
+ .read = debugfs_attr_read, \
+- .write = debugfs_attr_write, \
++ .write = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write, \
+ .llseek = no_llseek, \
+ }
+
++#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \
++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
+
+ #if defined(CONFIG_DEBUG_FS)
+@@ -102,6 +108,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos);
+ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos);
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos);
+
+ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+ struct dentry *new_dir, const char *new_name);
+@@ -254,6 +262,13 @@ static inline ssize_t debugfs_attr_write(struct file *file,
+ return -ENODEV;
+ }
+
++static inline ssize_t debugfs_attr_write_signed(struct file *file,
++ const char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ return -ENODEV;
++}
++
+ static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+ struct dentry *new_dir, char *new_name)
+ {
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 30eb30d6909b0..3cd202d3eefb3 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -61,7 +61,7 @@ static inline struct eventfd_ctx *eventfd_ctx_fdget(int fd)
+ return ERR_PTR(-ENOSYS);
+ }
+
+-static inline int eventfd_signal(struct eventfd_ctx *ctx, int n)
++static inline int eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ {
+ return -ENOSYS;
+ }
+diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
+index fce2fb2fc9626..c26160fe2e34e 100644
+--- a/include/linux/fortify-string.h
++++ b/include/linux/fortify-string.h
+@@ -3,6 +3,7 @@
+ #define _LINUX_FORTIFY_STRING_H_
+
+ #include <linux/const.h>
++#include <linux/limits.h>
+
+ #define __FORTIFY_INLINE extern __always_inline __gnu_inline __overloadable
+ #define __RENAME(x) __asm__(#x)
+@@ -16,10 +17,10 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("
+
+ #define __compiletime_strlen(p) \
+ ({ \
+- unsigned char *__p = (unsigned char *)(p); \
+- size_t __ret = (size_t)-1; \
++ char *__p = (char *)(p); \
++ size_t __ret = SIZE_MAX; \
+ size_t __p_size = __builtin_object_size(p, 1); \
+- if (__p_size != (size_t)-1 && \
++ if (__p_size != SIZE_MAX && \
+ __builtin_constant_p(*__p)) { \
+ size_t __p_len = __p_size - 1; \
+ if (__builtin_constant_p(__p[__p_len]) && \
+@@ -95,7 +96,7 @@ char *strcat(char * const POS p, const char *q)
+ {
+ size_t p_size = __builtin_object_size(p, 1);
+
+- if (p_size == (size_t)-1)
++ if (p_size == SIZE_MAX)
+ return __underlying_strcat(p, q);
+ if (strlcat(p, q, p_size) >= p_size)
+ fortify_panic(__func__);
+@@ -110,7 +111,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
+ size_t ret;
+
+ /* We can take compile-time actions when maxlen is const. */
+- if (__builtin_constant_p(maxlen) && p_len != (size_t)-1) {
++ if (__builtin_constant_p(maxlen) && p_len != SIZE_MAX) {
+ /* If p is const, we can use its compile-time-known len. */
+ if (maxlen >= p_size)
+ return p_len;
+@@ -138,7 +139,7 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
+ size_t p_size = __builtin_object_size(p, 1);
+
+ /* Give up if we don't know how large p is. */
+- if (p_size == (size_t)-1)
++ if (p_size == SIZE_MAX)
+ return __underlying_strlen(p);
+ ret = strnlen(p, p_size);
+ if (p_size <= ret)
+@@ -155,7 +156,7 @@ __FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, si
+ size_t q_len; /* Full count of source string length. */
+ size_t len; /* Count of characters going into destination. */
+
+- if (p_size == (size_t)-1 && q_size == (size_t)-1)
++ if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ return __real_strlcpy(p, q, size);
+ q_len = strlen(q);
+ len = (q_len >= size) ? size - 1 : q_len;
+@@ -183,7 +184,7 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s
+ size_t q_size = __builtin_object_size(q, 1);
+
+ /* If we cannot get size of p and q default to call strscpy. */
+- if (p_size == (size_t) -1 && q_size == (size_t) -1)
++ if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ return __real_strscpy(p, q, size);
+
+ /*
+@@ -228,7 +229,7 @@ char *strncat(char * const POS p, const char * const POS q, __kernel_size_t coun
+ size_t p_size = __builtin_object_size(p, 1);
+ size_t q_size = __builtin_object_size(q, 1);
+
+- if (p_size == (size_t)-1 && q_size == (size_t)-1)
++ if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ return __underlying_strncat(p, q, count);
+ p_len = strlen(p);
+ copy_len = strnlen(q, count);
+@@ -269,10 +270,10 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
+ /*
+ * Always stop accesses beyond the struct that contains the
+ * field, when the buffer's remaining size is known.
+- * (The -1 test is to optimize away checks where the buffer
++ * (The SIZE_MAX test is to optimize away checks where the buffer
+ * lengths are unknown.)
+ */
+- if (p_size != (size_t)(-1) && p_size < size)
++ if (p_size != SIZE_MAX && p_size < size)
+ fortify_panic("memset");
+ }
+
+@@ -363,11 +364,11 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size,
+ /*
+ * Always stop accesses beyond the struct that contains the
+ * field, when the buffer's remaining size is known.
+- * (The -1 test is to optimize away checks where the buffer
++ * (The SIZE_MAX test is to optimize away checks where the buffer
+ * lengths are unknown.)
+ */
+- if ((p_size != (size_t)(-1) && p_size < size) ||
+- (q_size != (size_t)(-1) && q_size < size))
++ if ((p_size != SIZE_MAX && p_size < size) ||
++ (q_size != SIZE_MAX && q_size < size))
+ fortify_panic(func);
+ }
+
+@@ -466,7 +467,7 @@ char *strcpy(char * const POS p, const char * const POS q)
+ size_t size;
+
+ /* If neither buffer size is known, immediately give up. */
+- if (p_size == (size_t)-1 && q_size == (size_t)-1)
++ if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ return __underlying_strcpy(p, q);
+ size = strlen(q) + 1;
+ /* Compile-time check for const size overflow. */
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index be074b6895b97..8e79a761c56c5 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3480,7 +3480,7 @@ void simple_transaction_set(struct file *file, size_t n);
+ * All attributes contain a text representation of a numeric value
+ * that are accessed with the get() and set() functions.
+ */
+-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
++#define DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed) \
+ static int __fops ## _open(struct inode *inode, struct file *file) \
+ { \
+ __simple_attr_check_format(__fmt, 0ull); \
+@@ -3491,10 +3491,16 @@ static const struct file_operations __fops = { \
+ .open = __fops ## _open, \
+ .release = simple_attr_release, \
+ .read = simple_attr_read, \
+- .write = simple_attr_write, \
++ .write = (__is_signed) ? simple_attr_write_signed : simple_attr_write, \
+ .llseek = generic_file_llseek, \
+ }
+
++#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
++ DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \
++ DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ static inline __printf(1, 2)
+ void __simple_attr_check_format(const char *fmt, ...)
+ {
+@@ -3509,6 +3515,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos);
+ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos);
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++ size_t len, loff_t *ppos);
+
+ struct ctl_table;
+ int __init list_bdev_fs_names(char *buf, size_t size);
+diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h
+index 116e8bd68c999..ce0c3ed67a5f4 100644
+--- a/include/linux/hisi_acc_qm.h
++++ b/include/linux/hisi_acc_qm.h
+@@ -168,6 +168,15 @@ enum qm_vf_state {
+ QM_NOT_READY,
+ };
+
++enum qm_cap_bits {
++ QM_SUPPORT_DB_ISOLATION = 0x0,
++ QM_SUPPORT_FUNC_QOS,
++ QM_SUPPORT_STOP_QP,
++ QM_SUPPORT_MB_COMMAND,
++ QM_SUPPORT_SVA_PREFETCH,
++ QM_SUPPORT_RPM,
++};
++
+ struct dfx_diff_registers {
+ u32 *regs;
+ u32 reg_offset;
+@@ -258,6 +267,18 @@ struct hisi_qm_err_ini {
+ void (*err_info_init)(struct hisi_qm *qm);
+ };
+
++struct hisi_qm_cap_info {
++ u32 type;
++ /* Register offset */
++ u32 offset;
++ /* Bit offset in register */
++ u32 shift;
++ u32 mask;
++ u32 v1_val;
++ u32 v2_val;
++ u32 v3_val;
++};
++
+ struct hisi_qm_list {
+ struct mutex lock;
+ struct list_head list;
+@@ -278,6 +299,9 @@ struct hisi_qm {
+ struct pci_dev *pdev;
+ void __iomem *io_base;
+ void __iomem *db_io_base;
++
++ /* Capbility version, 0: not supports */
++ u32 cap_ver;
+ u32 sqe_size;
+ u32 qp_base;
+ u32 qp_num;
+@@ -304,6 +328,8 @@ struct hisi_qm {
+ struct hisi_qm_err_info err_info;
+ struct hisi_qm_err_status err_status;
+ unsigned long misc_ctl; /* driver removing and reset sched */
++ /* Device capability bit */
++ unsigned long caps;
+
+ struct rw_semaphore qps_lock;
+ struct idr qp_idr;
+@@ -326,8 +352,6 @@ struct hisi_qm {
+ bool use_sva;
+ bool is_frozen;
+
+- /* doorbell isolation enable */
+- bool use_db_isolation;
+ resource_size_t phys_base;
+ resource_size_t db_phys_base;
+ struct uacce_device *uacce;
+@@ -376,14 +400,14 @@ struct hisi_qp {
+ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+ unsigned int device)
+ {
+- struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
+- device, NULL);
++ struct pci_dev *pdev;
+ u32 n, q_num;
+ int ret;
+
+ if (!val)
+ return -EINVAL;
+
++ pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, device, NULL);
+ if (!pdev) {
+ q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2);
+ pr_info("No device found currently, suppose queue number is %u\n",
+@@ -393,6 +417,8 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+ q_num = QM_QNUM_V1;
+ else
+ q_num = QM_QNUM_V2;
++
++ pci_dev_put(pdev);
+ }
+
+ ret = kstrtou32(val, 10, &n);
+@@ -501,6 +527,9 @@ void hisi_qm_pm_init(struct hisi_qm *qm);
+ int hisi_qm_get_dfx_access(struct hisi_qm *qm);
+ void hisi_qm_put_dfx_access(struct hisi_qm *qm);
+ void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset);
++u32 hisi_qm_get_hw_info(struct hisi_qm *qm,
++ const struct hisi_qm_cap_info *info_table,
++ u32 index, bool is_read);
+
+ /* Used by VFIO ACC live migration driver */
+ struct pci_driver *hisi_sec_get_pf_driver(void);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 3b42264333ef8..646f1da9f27e0 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1341,6 +1341,8 @@ struct hv_ring_buffer_debug_info {
+ int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
+ struct hv_ring_buffer_debug_info *debug_info);
+
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel);
++
+ /* Vmbus interface */
+ #define vmbus_driver_register(driver) \
+ __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index b6e6d5b407747..181e758c70c12 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -4588,7 +4588,7 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
+ return 0;
+ }
+
+- return common + mle->variable[0];
++ return sizeof(*mle) + common + mle->variable[0];
+ }
+
+ /**
+diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
+index 515ca09764fe4..bcbefb7574751 100644
+--- a/include/linux/iio/imu/adis.h
++++ b/include/linux/iio/imu/adis.h
+@@ -402,9 +402,20 @@ static inline int adis_update_bits_base(struct adis *adis, unsigned int reg,
+ __adis_update_bits_base(adis, reg, mask, val, sizeof(val)); \
+ })
+
+-int adis_enable_irq(struct adis *adis, bool enable);
+ int __adis_check_status(struct adis *adis);
+ int __adis_initial_startup(struct adis *adis);
++int __adis_enable_irq(struct adis *adis, bool enable);
++
++static inline int adis_enable_irq(struct adis *adis, bool enable)
++{
++ int ret;
++
++ mutex_lock(&adis->state_lock);
++ ret = __adis_enable_irq(adis, enable);
++ mutex_unlock(&adis->state_lock);
++
++ return ret;
++}
+
+ static inline int adis_check_status(struct adis *adis)
+ {
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 05d6f3facd5a5..47b8b0ab76946 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -171,31 +171,38 @@ static inline bool dev_xmit_complete(int rc)
+ * (unsigned long) so they can be read and written atomically.
+ */
+
++#define NET_DEV_STAT(FIELD) \
++ union { \
++ unsigned long FIELD; \
++ atomic_long_t __##FIELD; \
++ }
++
+ struct net_device_stats {
+- unsigned long rx_packets;
+- unsigned long tx_packets;
+- unsigned long rx_bytes;
+- unsigned long tx_bytes;
+- unsigned long rx_errors;
+- unsigned long tx_errors;
+- unsigned long rx_dropped;
+- unsigned long tx_dropped;
+- unsigned long multicast;
+- unsigned long collisions;
+- unsigned long rx_length_errors;
+- unsigned long rx_over_errors;
+- unsigned long rx_crc_errors;
+- unsigned long rx_frame_errors;
+- unsigned long rx_fifo_errors;
+- unsigned long rx_missed_errors;
+- unsigned long tx_aborted_errors;
+- unsigned long tx_carrier_errors;
+- unsigned long tx_fifo_errors;
+- unsigned long tx_heartbeat_errors;
+- unsigned long tx_window_errors;
+- unsigned long rx_compressed;
+- unsigned long tx_compressed;
++ NET_DEV_STAT(rx_packets);
++ NET_DEV_STAT(tx_packets);
++ NET_DEV_STAT(rx_bytes);
++ NET_DEV_STAT(tx_bytes);
++ NET_DEV_STAT(rx_errors);
++ NET_DEV_STAT(tx_errors);
++ NET_DEV_STAT(rx_dropped);
++ NET_DEV_STAT(tx_dropped);
++ NET_DEV_STAT(multicast);
++ NET_DEV_STAT(collisions);
++ NET_DEV_STAT(rx_length_errors);
++ NET_DEV_STAT(rx_over_errors);
++ NET_DEV_STAT(rx_crc_errors);
++ NET_DEV_STAT(rx_frame_errors);
++ NET_DEV_STAT(rx_fifo_errors);
++ NET_DEV_STAT(rx_missed_errors);
++ NET_DEV_STAT(tx_aborted_errors);
++ NET_DEV_STAT(tx_carrier_errors);
++ NET_DEV_STAT(tx_fifo_errors);
++ NET_DEV_STAT(tx_heartbeat_errors);
++ NET_DEV_STAT(tx_window_errors);
++ NET_DEV_STAT(rx_compressed);
++ NET_DEV_STAT(tx_compressed);
+ };
++#undef NET_DEV_STAT
+
+ /* per-cpu stats, allocated on demand.
+ * Try to fit them in a single cache line, for dev_get_stats() sake.
+@@ -5143,4 +5150,9 @@ extern struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
+
+ extern struct net_device *blackhole_netdev;
+
++/* Note: Avoid these macros in fast path, prefer per-cpu or per-queue counters. */
++#define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD)
++#define DEV_STATS_ADD(DEV, FIELD, VAL) \
++ atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
++
+ #endif /* _LINUX_NETDEVICE_H */
+diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
+index 81d6e4ec2294b..0260f5ea98fe1 100644
+--- a/include/linux/proc_fs.h
++++ b/include/linux/proc_fs.h
+@@ -208,8 +208,10 @@ static inline void proc_remove(struct proc_dir_entry *de) {}
+ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
+
+ #define proc_create_net_data(name, mode, parent, ops, state_size, data) ({NULL;})
++#define proc_create_net_data_write(name, mode, parent, ops, write, state_size, data) ({NULL;})
+ #define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
+ #define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
++#define proc_create_net_single_write(name, mode, parent, show, write, data) ({NULL;})
+
+ static inline struct pid *tgid_pidfd_to_pid(const struct file *file)
+ {
+diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
+index f9a7461e72b80..d3b4a3d4514ab 100644
+--- a/include/linux/regulator/driver.h
++++ b/include/linux/regulator/driver.h
+@@ -687,7 +687,8 @@ static inline int regulator_err2notif(int err)
+
+
+ struct regulator_dev *
+-regulator_register(const struct regulator_desc *regulator_desc,
++regulator_register(struct device *dev,
++ const struct regulator_desc *regulator_desc,
+ const struct regulator_config *config);
+ struct regulator_dev *
+ devm_regulator_register(struct device *dev,
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 70d6cb94e5802..84f787416a54d 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -82,6 +82,7 @@ struct sk_psock {
+ u32 apply_bytes;
+ u32 cork_bytes;
+ u32 eval;
++ bool redir_ingress; /* undefined if sk_redir is null */
+ struct sk_msg *cork;
+ struct sk_psock_progs progs;
+ #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)
+diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h
+index 93884086f3924..adc80e29168ea 100644
+--- a/include/linux/timerqueue.h
++++ b/include/linux/timerqueue.h
+@@ -35,7 +35,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
+ {
+ struct rb_node *leftmost = rb_first_cached(&head->rb_root);
+
+- return rb_entry(leftmost, struct timerqueue_node, node);
++ return rb_entry_safe(leftmost, struct timerqueue_node, node);
+ }
+
+ static inline void timerqueue_init(struct timerqueue_node *node)
+diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h
+index 2f6b0861322ae..ac60c9fcfe9a6 100644
+--- a/include/media/dvbdev.h
++++ b/include/media/dvbdev.h
+@@ -126,6 +126,7 @@ struct dvb_adapter {
+ * struct dvb_device - represents a DVB device node
+ *
+ * @list_head: List head with all DVB devices
++ * @ref: reference counter
+ * @fops: pointer to struct file_operations
+ * @adapter: pointer to the adapter that holds this device node
+ * @type: type of the device, as defined by &enum dvb_device_type.
+@@ -156,6 +157,7 @@ struct dvb_adapter {
+ */
+ struct dvb_device {
+ struct list_head list_head;
++ struct kref ref;
+ const struct file_operations *fops;
+ struct dvb_adapter *adapter;
+ enum dvb_device_type type;
+@@ -187,6 +189,20 @@ struct dvb_device {
+ void *priv;
+ };
+
++/**
++ * dvb_device_get - Increase dvb_device reference
++ *
++ * @dvbdev: pointer to struct dvb_device
++ */
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
++
++/**
++ * dvb_device_put - Decrease dvb_device reference
++ *
++ * @dvbdev: pointer to struct dvb_device
++ */
++void dvb_device_put(struct dvb_device *dvbdev);
++
+ /**
+ * dvb_register_adapter - Registers a new DVB adapter
+ *
+@@ -231,29 +247,17 @@ int dvb_register_device(struct dvb_adapter *adap,
+ /**
+ * dvb_remove_device - Remove a registered DVB device
+ *
+- * This does not free memory. To do that, call dvb_free_device().
++ * This does not free memory. dvb_free_device() will do that when
++ * reference counter is empty
+ *
+ * @dvbdev: pointer to struct dvb_device
+ */
+ void dvb_remove_device(struct dvb_device *dvbdev);
+
+-/**
+- * dvb_free_device - Free memory occupied by a DVB device.
+- *
+- * Call dvb_unregister_device() before calling this function.
+- *
+- * @dvbdev: pointer to struct dvb_device
+- */
+-void dvb_free_device(struct dvb_device *dvbdev);
+
+ /**
+ * dvb_unregister_device - Unregisters a DVB device
+ *
+- * This is a combination of dvb_remove_device() and dvb_free_device().
+- * Using this function is usually a mistake, and is often an indicator
+- * for a use-after-free bug (when a userspace process keeps a file
+- * handle to a detached device).
+- *
+ * @dvbdev: pointer to struct dvb_device
+ */
+ void dvb_unregister_device(struct dvb_device *dvbdev);
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 4518c63e9d179..dd455ce067701 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -274,6 +274,26 @@ enum {
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN,
++
++ /*
++ * When this quirk is set, the HCI_OP_LE_SET_EXT_SCAN_ENABLE command is
++ * disabled. This is required for some Broadcom controllers which
++ * erroneously claim to support extended scanning.
++ *
++ * This quirk can be set before hci_register_dev is called or
++ * during the hdev->setup vendor callback.
++ */
++ HCI_QUIRK_BROKEN_EXT_SCAN,
++
++ /*
++ * When this quirk is set, the HCI_OP_GET_MWS_TRANSPORT_CONFIG command is
++ * disabled. This is required for some Broadcom controllers which
++ * erroneously claim to support MWS Transport Layer Configuration.
++ *
++ * This quirk can be set before hci_register_dev is called or
++ * during the hdev->setup vendor callback.
++ */
++ HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG,
+ };
+
+ /* HCI device flags */
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index e7862903187d8..6afb4771ce355 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1681,7 +1681,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+
+ /* Use ext scanning if set ext scan param and ext scan enable is supported */
+ #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
+- ((dev)->commands[37] & 0x40))
++ ((dev)->commands[37] & 0x40) && \
++ !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))
++
+ /* Use ext create connection if command is supported */
+ #define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
+
+@@ -1709,6 +1711,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ ((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL)
+ #define bis_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER)
+
++#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
++ (!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks)))
++
+ /* ----- HCI protocols ----- */
+ #define HCI_PROTO_DEFER 0x01
+
+diff --git a/include/net/dst.h b/include/net/dst.h
+index 6aa252c3fc55c..19af7a2713ccb 100644
+--- a/include/net/dst.h
++++ b/include/net/dst.h
+@@ -362,9 +362,8 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ struct net *net)
+ {
+- /* TODO : stats should be SMP safe */
+- dev->stats.rx_packets++;
+- dev->stats.rx_bytes += skb->len;
++ DEV_STATS_INC(dev, rx_packets);
++ DEV_STATS_ADD(dev, rx_bytes, skb->len);
+ __skb_tunnel_rx(skb, dev, net);
+ }
+
+diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
+index ff1804a0c4692..1fca6a88114ad 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -351,11 +351,11 @@ struct ip_vs_seq {
+
+ /* counters per cpu */
+ struct ip_vs_counters {
+- __u64 conns; /* connections scheduled */
+- __u64 inpkts; /* incoming packets */
+- __u64 outpkts; /* outgoing packets */
+- __u64 inbytes; /* incoming bytes */
+- __u64 outbytes; /* outgoing bytes */
++ u64_stats_t conns; /* connections scheduled */
++ u64_stats_t inpkts; /* incoming packets */
++ u64_stats_t outpkts; /* outgoing packets */
++ u64_stats_t inbytes; /* incoming bytes */
++ u64_stats_t outbytes; /* outgoing bytes */
+ };
+ /* Stats per cpu */
+ struct ip_vs_cpu_stats {
+diff --git a/include/net/mrp.h b/include/net/mrp.h
+index 92cd3fb6cf9da..b28915ffea284 100644
+--- a/include/net/mrp.h
++++ b/include/net/mrp.h
+@@ -124,6 +124,7 @@ struct mrp_applicant {
+ struct sk_buff *pdu;
+ struct rb_root mad;
+ struct rcu_head rcu;
++ bool active;
+ };
+
+ struct mrp_port {
+diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
+index efc9085c68927..6ec140b0a61bf 100644
+--- a/include/net/sock_reuseport.h
++++ b/include/net/sock_reuseport.h
+@@ -16,6 +16,7 @@ struct sock_reuseport {
+ u16 max_socks; /* length of socks */
+ u16 num_socks; /* elements in socks */
+ u16 num_closed_socks; /* closed elements in socks */
++ u16 incoming_cpu;
+ /* The last synq overflow event timestamp of this
+ * reuse->socks[] group.
+ */
+@@ -58,5 +59,6 @@ static inline bool reuseport_has_conns(struct sock *sk)
+ }
+
+ void reuseport_has_conns_set(struct sock *sk);
++void reuseport_update_incoming_cpu(struct sock *sk, int val);
+
+ #endif /* _SOCK_REUSEPORT_H */
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 95c1d51393ac4..3cde7b4a401f2 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -2284,8 +2284,8 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore);
+ void tcp_bpf_clone(const struct sock *sk, struct sock *newsk);
+ #endif /* CONFIG_BPF_SYSCALL */
+
+-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, u32 bytes,
+- int flags);
++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress,
++ struct sk_msg *msg, u32 bytes, int flags);
+ #endif /* CONFIG_NET_SOCK_MSG */
+
+ #if !defined(CONFIG_BPF_SYSCALL) || !defined(CONFIG_NET_SOCK_MSG)
+diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
+index a1df4f9d57a31..ec646217e7f6e 100644
+--- a/include/scsi/sas_ata.h
++++ b/include/scsi/sas_ata.h
+@@ -35,6 +35,7 @@ void sas_ata_end_eh(struct ata_port *ap);
+ int sas_execute_ata_cmd(struct domain_device *device, u8 *fis,
+ int force_phy_id);
+ int sas_ata_wait_after_reset(struct domain_device *dev, unsigned long deadline);
++int smp_ata_check_ready_type(struct ata_link *link);
+ #else
+
+
+@@ -98,6 +99,11 @@ static inline int sas_ata_wait_after_reset(struct domain_device *dev,
+ {
+ return -ETIMEDOUT;
+ }
++
++static inline int smp_ata_check_ready_type(struct ata_link *link)
++{
++ return 0;
++}
+ #endif
+
+ #endif /* _SAS_ATA_H_ */
+diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
+index 6d3c82c4b6acd..ec2a2ba21cc39 100644
+--- a/include/sound/hda_codec.h
++++ b/include/sound/hda_codec.h
+@@ -258,7 +258,7 @@ struct hda_codec {
+ unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
+ unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
+ unsigned int forced_resume:1; /* forced resume for jack */
+- unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
++ unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
+
+ #ifdef CONFIG_PM
+ unsigned long power_on_acct;
+diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
+index 797bf67a164db..ceaa7b7cfdc30 100644
+--- a/include/sound/hdaudio.h
++++ b/include/sound/hdaudio.h
+@@ -562,6 +562,7 @@ int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
+ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
+ void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
+ void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
++void snd_hdac_stop_streams(struct hdac_bus *bus);
+ void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);
+ void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
+ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
+diff --git a/include/sound/pcm.h b/include/sound/pcm.h
+index 8c48a5bce88c1..25695f5f795a1 100644
+--- a/include/sound/pcm.h
++++ b/include/sound/pcm.h
+@@ -106,24 +106,24 @@ struct snd_pcm_ops {
+ #define SNDRV_PCM_POS_XRUN ((snd_pcm_uframes_t)-1)
+
+ /* If you change this don't forget to change rates[] table in pcm_native.c */
+-#define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */
+-#define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */
+-#define SNDRV_PCM_RATE_11025 (1<<2) /* 11025Hz */
+-#define SNDRV_PCM_RATE_16000 (1<<3) /* 16000Hz */
+-#define SNDRV_PCM_RATE_22050 (1<<4) /* 22050Hz */
+-#define SNDRV_PCM_RATE_32000 (1<<5) /* 32000Hz */
+-#define SNDRV_PCM_RATE_44100 (1<<6) /* 44100Hz */
+-#define SNDRV_PCM_RATE_48000 (1<<7) /* 48000Hz */
+-#define SNDRV_PCM_RATE_64000 (1<<8) /* 64000Hz */
+-#define SNDRV_PCM_RATE_88200 (1<<9) /* 88200Hz */
+-#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */
+-#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */
+-#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */
+-#define SNDRV_PCM_RATE_352800 (1<<13) /* 352800Hz */
+-#define SNDRV_PCM_RATE_384000 (1<<14) /* 384000Hz */
+-
+-#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */
+-#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */
++#define SNDRV_PCM_RATE_5512 (1U<<0) /* 5512Hz */
++#define SNDRV_PCM_RATE_8000 (1U<<1) /* 8000Hz */
++#define SNDRV_PCM_RATE_11025 (1U<<2) /* 11025Hz */
++#define SNDRV_PCM_RATE_16000 (1U<<3) /* 16000Hz */
++#define SNDRV_PCM_RATE_22050 (1U<<4) /* 22050Hz */
++#define SNDRV_PCM_RATE_32000 (1U<<5) /* 32000Hz */
++#define SNDRV_PCM_RATE_44100 (1U<<6) /* 44100Hz */
++#define SNDRV_PCM_RATE_48000 (1U<<7) /* 48000Hz */
++#define SNDRV_PCM_RATE_64000 (1U<<8) /* 64000Hz */
++#define SNDRV_PCM_RATE_88200 (1U<<9) /* 88200Hz */
++#define SNDRV_PCM_RATE_96000 (1U<<10) /* 96000Hz */
++#define SNDRV_PCM_RATE_176400 (1U<<11) /* 176400Hz */
++#define SNDRV_PCM_RATE_192000 (1U<<12) /* 192000Hz */
++#define SNDRV_PCM_RATE_352800 (1U<<13) /* 352800Hz */
++#define SNDRV_PCM_RATE_384000 (1U<<14) /* 384000Hz */
++
++#define SNDRV_PCM_RATE_CONTINUOUS (1U<<30) /* continuous range */
++#define SNDRV_PCM_RATE_KNOT (1U<<31) /* supports more non-continuos rates */
+
+ #define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
+ SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
+diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
+index f1e9222377368..f4556911c2347 100644
+--- a/include/trace/events/f2fs.h
++++ b/include/trace/events/f2fs.h
+@@ -322,7 +322,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ __field(ino_t, ino)
+ __field(loff_t, size)
+ __field(blkcnt_t, blocks)
+- __field(const char *, name)
++ __string(name, dentry->d_name.name)
+ ),
+
+ TP_fast_assign(
+@@ -330,7 +330,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ __entry->ino = dir->i_ino;
+ __entry->size = dir->i_size;
+ __entry->blocks = dir->i_blocks;
+- __entry->name = dentry->d_name.name;
++ __assign_str(name, dentry->d_name.name);
+ ),
+
+ TP_printk("dev = (%d,%d), dir ino = %lu, i_size = %lld, "
+@@ -338,7 +338,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ show_dev_ino(__entry),
+ __entry->size,
+ (unsigned long long)__entry->blocks,
+- __entry->name)
++ __get_str(name))
+ );
+
+ DEFINE_EVENT(f2fs__inode_exit, f2fs_unlink_exit,
+@@ -940,25 +940,29 @@ TRACE_EVENT(f2fs_direct_IO_enter,
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(ino_t, ino)
+- __field(struct kiocb *, iocb)
++ __field(loff_t, ki_pos)
++ __field(int, ki_flags)
++ __field(u16, ki_ioprio)
+ __field(unsigned long, len)
+ __field(int, rw)
+ ),
+
+ TP_fast_assign(
+- __entry->dev = inode->i_sb->s_dev;
+- __entry->ino = inode->i_ino;
+- __entry->iocb = iocb;
+- __entry->len = len;
+- __entry->rw = rw;
++ __entry->dev = inode->i_sb->s_dev;
++ __entry->ino = inode->i_ino;
++ __entry->ki_pos = iocb->ki_pos;
++ __entry->ki_flags = iocb->ki_flags;
++ __entry->ki_ioprio = iocb->ki_ioprio;
++ __entry->len = len;
++ __entry->rw = rw;
+ ),
+
+ TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu ki_flags = %x ki_ioprio = %x rw = %d",
+ show_dev_ino(__entry),
+- __entry->iocb->ki_pos,
++ __entry->ki_pos,
+ __entry->len,
+- __entry->iocb->ki_flags,
+- __entry->iocb->ki_ioprio,
++ __entry->ki_flags,
++ __entry->ki_ioprio,
+ __entry->rw)
+ );
+
+@@ -1407,19 +1411,19 @@ TRACE_EVENT(f2fs_write_checkpoint,
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(int, reason)
+- __field(char *, msg)
++ __string(dest_msg, msg)
+ ),
+
+ TP_fast_assign(
+ __entry->dev = sb->s_dev;
+ __entry->reason = reason;
+- __entry->msg = msg;
++ __assign_str(dest_msg, msg);
+ ),
+
+ TP_printk("dev = (%d,%d), checkpoint for %s, state = %s",
+ show_dev(__entry->dev),
+ show_cpreason(__entry->reason),
+- __entry->msg)
++ __get_str(dest_msg))
+ );
+
+ DECLARE_EVENT_CLASS(f2fs_discard,
+diff --git a/include/trace/events/ib_mad.h b/include/trace/events/ib_mad.h
+index 59363a083ecb9..d92691c78cff6 100644
+--- a/include/trace/events/ib_mad.h
++++ b/include/trace/events/ib_mad.h
+@@ -49,7 +49,6 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ __field(int, retries_left)
+ __field(int, max_retries)
+ __field(int, retry)
+- __field(u16, pkey)
+ ),
+
+ TP_fast_assign(
+@@ -89,7 +88,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ "hdr : base_ver 0x%x class 0x%x class_ver 0x%x " \
+ "method 0x%x status 0x%x class_specific 0x%x tid 0x%llx " \
+ "attr_id 0x%x attr_mod 0x%x => dlid 0x%08x sl %d "\
+- "pkey 0x%x rpqn 0x%x rqpkey 0x%x",
++ "rpqn 0x%x rqpkey 0x%x",
+ __entry->dev_index, __entry->port_num, __entry->qp_num,
+ __entry->agent_priv, be64_to_cpu(__entry->wrtid),
+ __entry->retries_left, __entry->max_retries,
+@@ -100,7 +99,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ be16_to_cpu(__entry->class_specific),
+ be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+ be32_to_cpu(__entry->attr_mod),
+- be32_to_cpu(__entry->dlid), __entry->sl, __entry->pkey,
++ be32_to_cpu(__entry->dlid), __entry->sl,
+ __entry->rqpn, __entry->rqkey
+ )
+ );
+@@ -204,7 +203,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ __field(u16, wc_status)
+ __field(u32, slid)
+ __field(u32, dev_index)
+- __field(u16, pkey)
+ ),
+
+ TP_fast_assign(
+@@ -224,9 +222,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ __entry->slid = wc->slid;
+ __entry->src_qp = wc->src_qp;
+ __entry->sl = wc->sl;
+- ib_query_pkey(qp_info->port_priv->device,
+- qp_info->port_priv->port_num,
+- wc->pkey_index, &__entry->pkey);
+ __entry->wc_status = wc->status;
+ ),
+
+@@ -234,7 +229,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ "base_ver 0x%02x class 0x%02x class_ver 0x%02x " \
+ "method 0x%02x status 0x%04x class_specific 0x%04x " \
+ "tid 0x%016llx attr_id 0x%04x attr_mod 0x%08x " \
+- "slid 0x%08x src QP%d, sl %d pkey 0x%04x",
++ "slid 0x%08x src QP%d, sl %d",
+ __entry->dev_index, __entry->port_num, __entry->qp_num,
+ __entry->wc_status,
+ __entry->length,
+@@ -244,7 +239,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ be16_to_cpu(__entry->class_specific),
+ be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+ be32_to_cpu(__entry->attr_mod),
+- __entry->slid, __entry->src_qp, __entry->sl, __entry->pkey
++ __entry->slid, __entry->src_qp, __entry->sl
+ )
+ );
+
+diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h
+index 2b9e7feba3f32..1d553bedbdb51 100644
+--- a/include/uapi/linux/idxd.h
++++ b/include/uapi/linux/idxd.h
+@@ -295,7 +295,7 @@ struct dsa_completion_record {
+ };
+
+ uint32_t delta_rec_size;
+- uint32_t crc_val;
++ uint64_t crc_val;
+
+ /* DIF check & strip */
+ struct {
+diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
+index 0723a9cce747c..01717181339eb 100644
+--- a/include/uapi/linux/swab.h
++++ b/include/uapi/linux/swab.h
+@@ -3,7 +3,7 @@
+ #define _UAPI_LINUX_SWAB_H
+
+ #include <linux/types.h>
+-#include <linux/compiler.h>
++#include <linux/stddef.h>
+ #include <asm/bitsperlong.h>
+ #include <asm/swab.h>
+
+diff --git a/include/uapi/rdma/hns-abi.h b/include/uapi/rdma/hns-abi.h
+index f6fde06db4b4e..745790ce3c261 100644
+--- a/include/uapi/rdma/hns-abi.h
++++ b/include/uapi/rdma/hns-abi.h
+@@ -85,11 +85,26 @@ struct hns_roce_ib_create_qp_resp {
+ __aligned_u64 dwqe_mmap_key;
+ };
+
++enum {
++ HNS_ROCE_EXSGE_FLAGS = 1 << 0,
++};
++
++enum {
++ HNS_ROCE_RSP_EXSGE_FLAGS = 1 << 0,
++};
++
+ struct hns_roce_ib_alloc_ucontext_resp {
+ __u32 qp_tab_size;
+ __u32 cqe_size;
+ __u32 srq_tab_size;
+ __u32 reserved;
++ __u32 config;
++ __u32 max_inline_data;
++};
++
++struct hns_roce_ib_alloc_ucontext {
++ __u32 config;
++ __u32 reserved;
+ };
+
+ struct hns_roce_ib_alloc_pd_resp {
+diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h
+index a75e14edc957e..dbd60f48b4b01 100644
+--- a/include/uapi/sound/asequencer.h
++++ b/include/uapi/sound/asequencer.h
+@@ -344,10 +344,10 @@ typedef int __bitwise snd_seq_client_type_t;
+ #define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2)
+
+ /* event filter flags */
+-#define SNDRV_SEQ_FILTER_BROADCAST (1<<0) /* accept broadcast messages */
+-#define SNDRV_SEQ_FILTER_MULTICAST (1<<1) /* accept multicast messages */
+-#define SNDRV_SEQ_FILTER_BOUNCE (1<<2) /* accept bounce event in error */
+-#define SNDRV_SEQ_FILTER_USE_EVENT (1<<31) /* use event filter */
++#define SNDRV_SEQ_FILTER_BROADCAST (1U<<0) /* accept broadcast messages */
++#define SNDRV_SEQ_FILTER_MULTICAST (1U<<1) /* accept multicast messages */
++#define SNDRV_SEQ_FILTER_BOUNCE (1U<<2) /* accept bounce event in error */
++#define SNDRV_SEQ_FILTER_USE_EVENT (1U<<31) /* use event filter */
+
+ struct snd_seq_client_info {
+ int client; /* client number to inquire */
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 90d2fc6fd80e4..080867143f287 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -164,6 +164,8 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
+ }
+
+ done:
++ if (ret == -EAGAIN)
++ return -EAGAIN;
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 8205cfecd647c..eaaacee91a1ff 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -772,10 +772,10 @@ retry_multishot:
+ goto retry_multishot;
+
+ if (mshot_finished) {
+- io_netmsg_recycle(req, issue_flags);
+ /* fast path, check for non-NULL to avoid function call */
+ if (kmsg->free_iov)
+ kfree(kmsg->free_iov);
++ io_netmsg_recycle(req, issue_flags);
+ req->flags &= ~REQ_F_NEED_CLEANUP;
+ }
+
+diff --git a/io_uring/timeout.c b/io_uring/timeout.c
+index 78ea2c64b70e0..535ecaee5a0bb 100644
+--- a/io_uring/timeout.c
++++ b/io_uring/timeout.c
+@@ -72,10 +72,12 @@ static bool io_kill_timeout(struct io_kiocb *req, int status)
+ __cold void io_flush_timeouts(struct io_ring_ctx *ctx)
+ __must_hold(&ctx->completion_lock)
+ {
+- u32 seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
++ u32 seq;
+ struct io_timeout *timeout, *tmp;
+
+ spin_lock_irq(&ctx->timeout_lock);
++ seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
++
+ list_for_each_entry_safe(timeout, tmp, &ctx->timeout_list, list) {
+ struct io_kiocb *req = cmd_to_io_kiocb(timeout);
+ u32 events_needed, events_got;
+diff --git a/ipc/mqueue.c b/ipc/mqueue.c
+index 9cf314b3f079f..b258f24555534 100644
+--- a/ipc/mqueue.c
++++ b/ipc/mqueue.c
+@@ -1727,7 +1727,8 @@ static int __init init_mqueue_fs(void)
+
+ if (!setup_mq_sysctls(&init_ipc_ns)) {
+ pr_warn("sysctl registration failed\n");
+- return -ENOMEM;
++ error = -ENOMEM;
++ goto out_kmem;
+ }
+
+ error = register_filesystem(&mqueue_fs_type);
+@@ -1745,8 +1746,9 @@ static int __init init_mqueue_fs(void)
+ out_filesystem:
+ unregister_filesystem(&mqueue_fs_type);
+ out_sysctl:
+- kmem_cache_destroy(mqueue_inode_cachep);
+ retire_mq_sysctls(&init_ipc_ns);
++out_kmem:
++ kmem_cache_destroy(mqueue_inode_cachep);
+ return error;
+ }
+
+diff --git a/kernel/acct.c b/kernel/acct.c
+index 13706356ec54d..67bde1633d8f9 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -350,6 +350,8 @@ static comp_t encode_comp_t(unsigned long value)
+ exp++;
+ }
+
++ if (exp > (((comp_t) ~0U) >> MANTSIZE))
++ return (comp_t) ~0U;
+ /*
+ * Clean it up and polish it off.
+ */
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 0d23d4bcd81cc..44e93c3abebde 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -4481,6 +4481,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
+ break;
+ }
+
++ if (btf_type_is_resolve_source_only(arg_type)) {
++ btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1);
++ return -EINVAL;
++ }
++
+ if (args[i].name_off &&
+ (!btf_name_offset_valid(btf, args[i].name_off) ||
+ !btf_name_valid_identifier(btf, args[i].name_off))) {
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 0e758911d963f..6b6fb7237ebea 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -3505,9 +3505,9 @@ static int bpf_prog_attach(const union bpf_attr *attr)
+ case BPF_PROG_TYPE_LSM:
+ if (ptype == BPF_PROG_TYPE_LSM &&
+ prog->expected_attach_type != BPF_LSM_CGROUP)
+- return -EINVAL;
+-
+- ret = cgroup_bpf_prog_attach(attr, ptype, prog);
++ ret = -EINVAL;
++ else
++ ret = cgroup_bpf_prog_attach(attr, ptype, prog);
+ break;
+ default:
+ ret = -EINVAL;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index b781075dd5109..57f76b597012c 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2751,7 +2751,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
+ }
+ }
+
+-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
++static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
+ int spi)
+ {
+ struct bpf_verifier_state *st = env->cur_state;
+@@ -2768,7 +2768,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ if (!env->bpf_capable)
+ return 0;
+
+- func = st->frame[st->curframe];
++ func = st->frame[frame];
+ if (regno >= 0) {
+ reg = &func->regs[regno];
+ if (reg->type != SCALAR_VALUE) {
+@@ -2849,7 +2849,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ break;
+
+ new_marks = false;
+- func = st->frame[st->curframe];
++ func = st->frame[frame];
+ bitmap_from_u64(mask, reg_mask);
+ for_each_set_bit(i, mask, 32) {
+ reg = &func->regs[i];
+@@ -2915,12 +2915,17 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+
+ static int mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ {
+- return __mark_chain_precision(env, regno, -1);
++ return __mark_chain_precision(env, env->cur_state->curframe, regno, -1);
+ }
+
+-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi)
++static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno)
+ {
+- return __mark_chain_precision(env, -1, spi);
++ return __mark_chain_precision(env, frame, regno, -1);
++}
++
++static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi)
++{
++ return __mark_chain_precision(env, frame, -1, spi);
+ }
+
+ static bool is_spillable_regtype(enum bpf_reg_type type)
+@@ -3169,14 +3174,17 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
+ stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
+ mark_stack_slot_scratched(env, spi);
+
+- if (!env->allow_ptr_leaks
+- && *stype != NOT_INIT
+- && *stype != SCALAR_VALUE) {
+- /* Reject the write if there's are spilled pointers in
+- * range. If we didn't reject here, the ptr status
+- * would be erased below (even though not all slots are
+- * actually overwritten), possibly opening the door to
+- * leaks.
++ if (!env->allow_ptr_leaks && *stype != STACK_MISC && *stype != STACK_ZERO) {
++ /* Reject the write if range we may write to has not
++ * been initialized beforehand. If we didn't reject
++ * here, the ptr status would be erased below (even
++ * though not all slots are actually overwritten),
++ * possibly opening the door to leaks.
++ *
++ * We do however catch STACK_INVALID case below, and
++ * only allow reading possibly uninitialized memory
++ * later for CAP_PERFMON, as the write may not happen to
++ * that slot.
+ */
+ verbose(env, "spilled ptr in range of var-offset stack write; insn %d, ptr off: %d",
+ insn_idx, i);
+@@ -5142,10 +5150,6 @@ static int check_stack_range_initialized(
+ goto mark;
+ }
+
+- if (is_spilled_reg(&state->stack[spi]) &&
+- base_type(state->stack[spi].spilled_ptr.type) == PTR_TO_BTF_ID)
+- goto mark;
+-
+ if (is_spilled_reg(&state->stack[spi]) &&
+ (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
+ env->allow_ptr_leaks)) {
+@@ -5176,6 +5180,11 @@ mark:
+ mark_reg_read(env, &state->stack[spi].spilled_ptr,
+ state->stack[spi].spilled_ptr.parent,
+ REG_LIVE_READ64);
++ /* We do not set REG_LIVE_WRITTEN for stack slot, as we can not
++ * be sure that whether stack slot is written to or not. Hence,
++ * we must still conservatively propagate reads upwards even if
++ * helper may write to the entire memory range.
++ */
+ }
+ return update_stack_depth(env, state, min_off);
+ }
+@@ -9057,6 +9066,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
+ return err;
+ return adjust_ptr_min_max_vals(env, insn,
+ dst_reg, src_reg);
++ } else if (dst_reg->precise) {
++ /* if dst_reg is precise, src_reg should be precise as well */
++ err = mark_chain_precision(env, insn->src_reg);
++ if (err)
++ return err;
+ }
+ } else {
+ /* Pretend the src is a reg with a known value, since we only
+@@ -11693,34 +11707,36 @@ static int propagate_precision(struct bpf_verifier_env *env,
+ {
+ struct bpf_reg_state *state_reg;
+ struct bpf_func_state *state;
+- int i, err = 0;
++ int i, err = 0, fr;
+
+- state = old->frame[old->curframe];
+- state_reg = state->regs;
+- for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+- if (state_reg->type != SCALAR_VALUE ||
+- !state_reg->precise)
+- continue;
+- if (env->log.level & BPF_LOG_LEVEL2)
+- verbose(env, "propagating r%d\n", i);
+- err = mark_chain_precision(env, i);
+- if (err < 0)
+- return err;
+- }
++ for (fr = old->curframe; fr >= 0; fr--) {
++ state = old->frame[fr];
++ state_reg = state->regs;
++ for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
++ if (state_reg->type != SCALAR_VALUE ||
++ !state_reg->precise)
++ continue;
++ if (env->log.level & BPF_LOG_LEVEL2)
++ verbose(env, "frame %d: propagating r%d\n", i, fr);
++ err = mark_chain_precision_frame(env, fr, i);
++ if (err < 0)
++ return err;
++ }
+
+- for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+- if (!is_spilled_reg(&state->stack[i]))
+- continue;
+- state_reg = &state->stack[i].spilled_ptr;
+- if (state_reg->type != SCALAR_VALUE ||
+- !state_reg->precise)
+- continue;
+- if (env->log.level & BPF_LOG_LEVEL2)
+- verbose(env, "propagating fp%d\n",
+- (-i - 1) * BPF_REG_SIZE);
+- err = mark_chain_precision_stack(env, i);
+- if (err < 0)
+- return err;
++ for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
++ if (!is_spilled_reg(&state->stack[i]))
++ continue;
++ state_reg = &state->stack[i].spilled_ptr;
++ if (state_reg->type != SCALAR_VALUE ||
++ !state_reg->precise)
++ continue;
++ if (env->log.level & BPF_LOG_LEVEL2)
++ verbose(env, "frame %d: propagating fp%d\n",
++ (-i - 1) * BPF_REG_SIZE, fr);
++ err = mark_chain_precision_stack_frame(env, fr, i);
++ if (err < 0)
++ return err;
++ }
+ }
+ return 0;
+ }
+@@ -13283,6 +13299,10 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
+ if (!bpf_jit_needs_zext() && !is_cmpxchg_insn(&insn))
+ continue;
+
++ /* Zero-extension is done by the caller. */
++ if (bpf_pseudo_kfunc_call(&insn))
++ continue;
++
+ if (WARN_ON(load_reg == -1)) {
+ verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
+ return -EFAULT;
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index bbad5e375d3ba..98a7a7b1471b7 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -663,21 +663,51 @@ static bool cpuhp_next_state(bool bringup,
+ return true;
+ }
+
+-static int cpuhp_invoke_callback_range(bool bringup,
+- unsigned int cpu,
+- struct cpuhp_cpu_state *st,
+- enum cpuhp_state target)
++static int __cpuhp_invoke_callback_range(bool bringup,
++ unsigned int cpu,
++ struct cpuhp_cpu_state *st,
++ enum cpuhp_state target,
++ bool nofail)
+ {
+ enum cpuhp_state state;
+- int err = 0;
++ int ret = 0;
+
+ while (cpuhp_next_state(bringup, &state, st, target)) {
++ int err;
++
+ err = cpuhp_invoke_callback(cpu, state, bringup, NULL, NULL);
+- if (err)
++ if (!err)
++ continue;
++
++ if (nofail) {
++ pr_warn("CPU %u %s state %s (%d) failed (%d)\n",
++ cpu, bringup ? "UP" : "DOWN",
++ cpuhp_get_step(st->state)->name,
++ st->state, err);
++ ret = -1;
++ } else {
++ ret = err;
+ break;
++ }
+ }
+
+- return err;
++ return ret;
++}
++
++static inline int cpuhp_invoke_callback_range(bool bringup,
++ unsigned int cpu,
++ struct cpuhp_cpu_state *st,
++ enum cpuhp_state target)
++{
++ return __cpuhp_invoke_callback_range(bringup, cpu, st, target, false);
++}
++
++static inline void cpuhp_invoke_callback_range_nofail(bool bringup,
++ unsigned int cpu,
++ struct cpuhp_cpu_state *st,
++ enum cpuhp_state target)
++{
++ __cpuhp_invoke_callback_range(bringup, cpu, st, target, true);
+ }
+
+ static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st)
+@@ -999,7 +1029,6 @@ static int take_cpu_down(void *_param)
+ struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
+ enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
+ int err, cpu = smp_processor_id();
+- int ret;
+
+ /* Ensure this CPU doesn't handle any more interrupts. */
+ err = __cpu_disable();
+@@ -1012,13 +1041,10 @@ static int take_cpu_down(void *_param)
+ */
+ WARN_ON(st->state != (CPUHP_TEARDOWN_CPU - 1));
+
+- /* Invoke the former CPU_DYING callbacks */
+- ret = cpuhp_invoke_callback_range(false, cpu, st, target);
+-
+ /*
+- * DYING must not fail!
++ * Invoke the former CPU_DYING callbacks. DYING must not fail!
+ */
+- WARN_ON_ONCE(ret);
++ cpuhp_invoke_callback_range_nofail(false, cpu, st, target);
+
+ /* Give up timekeeping duties */
+ tick_handover_do_timer();
+@@ -1296,16 +1322,14 @@ void notify_cpu_starting(unsigned int cpu)
+ {
+ struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
+ enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
+- int ret;
+
+ rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */
+ cpumask_set_cpu(cpu, &cpus_booted_once_mask);
+- ret = cpuhp_invoke_callback_range(true, cpu, st, target);
+
+ /*
+ * STARTING must not fail!
+ */
+- WARN_ON_ONCE(ret);
++ cpuhp_invoke_callback_range_nofail(true, cpu, st, target);
+ }
+
+ /*
+@@ -2326,8 +2350,10 @@ static ssize_t target_store(struct device *dev, struct device_attribute *attr,
+
+ if (st->state < target)
+ ret = cpu_up(dev->id, target);
+- else
++ else if (st->state > target)
+ ret = cpu_down(dev->id, target);
++ else if (WARN_ON(st->target != target))
++ st->target = target;
+ out:
+ unlock_device_hotplug();
+ return ret ? ret : count;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 91473e9f88cd9..a636fab5e381a 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -11136,13 +11136,15 @@ static int pmu_dev_alloc(struct pmu *pmu)
+
+ pmu->dev->groups = pmu->attr_groups;
+ device_initialize(pmu->dev);
+- ret = dev_set_name(pmu->dev, "%s", pmu->name);
+- if (ret)
+- goto free_dev;
+
+ dev_set_drvdata(pmu->dev, pmu);
+ pmu->dev->bus = &pmu_bus;
+ pmu->dev->release = pmu_dev_release;
++
++ ret = dev_set_name(pmu->dev, "%s", pmu->name);
++ if (ret)
++ goto free_dev;
++
+ ret = device_add(pmu->dev);
+ if (ret)
+ goto free_dev;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 2b6bd511c6ed1..f925d2b96e0a9 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -537,6 +537,9 @@ void put_task_stack(struct task_struct *tsk)
+
+ void free_task(struct task_struct *tsk)
+ {
++#ifdef CONFIG_SECCOMP
++ WARN_ON_ONCE(tsk->seccomp.filter);
++#endif
+ release_user_cpus_ptr(tsk);
+ scs_release(tsk);
+
+@@ -2407,12 +2410,6 @@ static __latent_entropy struct task_struct *copy_process(
+
+ spin_lock(¤t->sighand->siglock);
+
+- /*
+- * Copy seccomp details explicitly here, in case they were changed
+- * before holding sighand lock.
+- */
+- copy_seccomp(p);
+-
+ rv_task_fork(p);
+
+ rseq_fork(p, clone_flags);
+@@ -2429,6 +2426,14 @@ static __latent_entropy struct task_struct *copy_process(
+ goto bad_fork_cancel_cgroup;
+ }
+
++ /* No more failure paths after this point. */
++
++ /*
++ * Copy seccomp details explicitly here, in case they were changed
++ * before holding sighand lock.
++ */
++ copy_seccomp(p);
++
+ init_task_pid_links(p);
+ if (likely(p->pid)) {
+ ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
+diff --git a/kernel/futex/core.c b/kernel/futex/core.c
+index b22ef1efe7511..514e4582b8634 100644
+--- a/kernel/futex/core.c
++++ b/kernel/futex/core.c
+@@ -638,6 +638,7 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
+ bool pi, bool pending_op)
+ {
+ u32 uval, nval, mval;
++ pid_t owner;
+ int err;
+
+ /* Futex address must be 32bit aligned */
+@@ -659,6 +660,10 @@ retry:
+ * 2. A woken up waiter is killed before it can acquire the
+ * futex in user space.
+ *
++ * In the second case, the wake up notification could be generated
++ * by the unlock path in user space after setting the futex value
++ * to zero or by the kernel after setting the OWNER_DIED bit below.
++ *
+ * In both cases the TID validation below prevents a wakeup of
+ * potential waiters which can cause these waiters to block
+ * forever.
+@@ -667,24 +672,27 @@ retry:
+ *
+ * 1) task->robust_list->list_op_pending != NULL
+ * @pending_op == true
+- * 2) User space futex value == 0
++ * 2) The owner part of user space futex value == 0
+ * 3) Regular futex: @pi == false
+ *
+ * If these conditions are met, it is safe to attempt waking up a
+ * potential waiter without touching the user space futex value and
+- * trying to set the OWNER_DIED bit. The user space futex value is
+- * uncontended and the rest of the user space mutex state is
+- * consistent, so a woken waiter will just take over the
+- * uncontended futex. Setting the OWNER_DIED bit would create
+- * inconsistent state and malfunction of the user space owner died
+- * handling.
++ * trying to set the OWNER_DIED bit. If the futex value is zero,
++ * the rest of the user space mutex state is consistent, so a woken
++ * waiter will just take over the uncontended futex. Setting the
++ * OWNER_DIED bit would create inconsistent state and malfunction
++ * of the user space owner died handling. Otherwise, the OWNER_DIED
++ * bit is already set, and the woken waiter is expected to deal with
++ * this.
+ */
+- if (pending_op && !pi && !uval) {
++ owner = uval & FUTEX_TID_MASK;
++
++ if (pending_op && !pi && !owner) {
+ futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
+ return 0;
+ }
+
+- if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
++ if (owner != task_pid_vnr(curr))
+ return 0;
+
+ /*
+diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c
+index 7971e989e425b..74a4ef1da9ad7 100644
+--- a/kernel/gcov/gcc_4_7.c
++++ b/kernel/gcov/gcc_4_7.c
+@@ -82,6 +82,7 @@ struct gcov_fn_info {
+ * @version: gcov version magic indicating the gcc version used for compilation
+ * @next: list head for a singly-linked list
+ * @stamp: uniquifying time stamp
++ * @checksum: unique object checksum
+ * @filename: name of the associated gcov data file
+ * @merge: merge functions (null for unused counter type)
+ * @n_functions: number of instrumented functions
+@@ -94,6 +95,10 @@ struct gcov_info {
+ unsigned int version;
+ struct gcov_info *next;
+ unsigned int stamp;
++ /* Since GCC 12.1 a checksum field is added. */
++#if (__GNUC__ >= 12)
++ unsigned int checksum;
++#endif
+ const char *filename;
+ void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
+ unsigned int n_functions;
+diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
+index f09c60393e559..5fdc0b5575797 100644
+--- a/kernel/irq/internals.h
++++ b/kernel/irq/internals.h
+@@ -52,6 +52,7 @@ enum {
+ * IRQS_PENDING - irq is pending and replayed later
+ * IRQS_SUSPENDED - irq is suspended
+ * IRQS_NMI - irq line is used to deliver NMIs
++ * IRQS_SYSFS - descriptor has been added to sysfs
+ */
+ enum {
+ IRQS_AUTODETECT = 0x00000001,
+@@ -64,6 +65,7 @@ enum {
+ IRQS_SUSPENDED = 0x00000800,
+ IRQS_TIMINGS = 0x00001000,
+ IRQS_NMI = 0x00002000,
++ IRQS_SYSFS = 0x00004000,
+ };
+
+ #include "debug.h"
+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
+index 5db0230aa6b52..c797d4054d0e5 100644
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -288,22 +288,25 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc)
+ if (irq_kobj_base) {
+ /*
+ * Continue even in case of failure as this is nothing
+- * crucial.
++ * crucial and failures in the late irq_sysfs_init()
++ * cannot be rolled back.
+ */
+ if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
+ pr_warn("Failed to add kobject for irq %d\n", irq);
++ else
++ desc->istate |= IRQS_SYSFS;
+ }
+ }
+
+ static void irq_sysfs_del(struct irq_desc *desc)
+ {
+ /*
+- * If irq_sysfs_init() has not yet been invoked (early boot), then
+- * irq_kobj_base is NULL and the descriptor was never added.
+- * kobject_del() complains about a object with no parent, so make
+- * it conditional.
++ * Only invoke kobject_del() when kobject_add() was successfully
++ * invoked for the descriptor. This covers both early boot, where
++ * sysfs is not initialized yet, and the case of a failed
++ * kobject_add() invocation.
+ */
+- if (irq_kobj_base)
++ if (desc->istate & IRQS_SYSFS)
+ kobject_del(&desc->kobj);
+ }
+
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 6d2a8623ec7b5..771fcce54fac0 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2360,6 +2360,14 @@ static void kill_kprobe(struct kprobe *p)
+
+ lockdep_assert_held(&kprobe_mutex);
+
++ /*
++ * The module is going away. We should disarm the kprobe which
++ * is using ftrace, because ftrace framework is still available at
++ * 'MODULE_STATE_GOING' notification.
++ */
++ if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
++ disarm_kprobe_ftrace(p);
++
+ p->flags |= KPROBE_FLAG_GONE;
+ if (kprobe_aggrprobe(p)) {
+ /*
+@@ -2376,14 +2384,6 @@ static void kill_kprobe(struct kprobe *p)
+ * the original probed function (which will be freed soon) any more.
+ */
+ arch_remove_kprobe(p);
+-
+- /*
+- * The module is going away. We should disarm the kprobe which
+- * is using ftrace, because ftrace framework is still available at
+- * 'MODULE_STATE_GOING' notification.
+- */
+- if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
+- disarm_kprobe_ftrace(p);
+ }
+
+ /* Disable one kprobe */
+diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c
+index 4d0bcb3d9e449..82c07b1d97975 100644
+--- a/kernel/module/decompress.c
++++ b/kernel/module/decompress.c
+@@ -114,8 +114,8 @@ static ssize_t module_gzip_decompress(struct load_info *info,
+ do {
+ struct page *page = module_get_next_page(info);
+
+- if (!page) {
+- retval = -ENOMEM;
++ if (IS_ERR(page)) {
++ retval = PTR_ERR(page);
+ goto out_inflate_end;
+ }
+
+@@ -173,8 +173,8 @@ static ssize_t module_xz_decompress(struct load_info *info,
+ do {
+ struct page *page = module_get_next_page(info);
+
+- if (!page) {
+- retval = -ENOMEM;
++ if (IS_ERR(page)) {
++ retval = PTR_ERR(page);
+ goto out;
+ }
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index e5819bb8bd1dc..de90af5fcbe6b 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -207,14 +207,16 @@ int padata_do_parallel(struct padata_shell *ps,
+ pw = padata_work_alloc();
+ spin_unlock(&padata_works_lock);
+
++ if (!pw) {
++ /* Maximum works limit exceeded, run in the current task. */
++ padata->parallel(padata);
++ }
++
+ rcu_read_unlock_bh();
+
+ if (pw) {
+ padata_work_init(pw, padata_parallel_worker, padata, 0);
+ queue_work(pinst->parallel_wq, &pw->pw_work);
+- } else {
+- /* Maximum works limit exceeded, run in the current task. */
+- padata->parallel(padata);
+ }
+
+ return 0;
+@@ -388,13 +390,16 @@ void padata_do_serial(struct padata_priv *padata)
+ int hashed_cpu = padata_cpu_hash(pd, padata->seq_nr);
+ struct padata_list *reorder = per_cpu_ptr(pd->reorder_list, hashed_cpu);
+ struct padata_priv *cur;
++ struct list_head *pos;
+
+ spin_lock(&reorder->lock);
+ /* Sort in ascending order of sequence number. */
+- list_for_each_entry_reverse(cur, &reorder->list, list)
++ list_for_each_prev(pos, &reorder->list) {
++ cur = list_entry(pos, struct padata_priv, list);
+ if (cur->seq_nr < padata->seq_nr)
+ break;
+- list_add(&padata->list, &cur->list);
++ }
++ list_add(&padata->list, pos);
+ spin_unlock(&reorder->lock);
+
+ /*
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index 2a406753af904..c20ca5fb9adc8 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -1723,8 +1723,8 @@ static unsigned long minimum_image_size(unsigned long saveable)
+ * /sys/power/reserved_size, respectively). To make this happen, we compute the
+ * total number of available page frames and allocate at least
+ *
+- * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
+- * + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
++ * ([page frames total] - PAGES_FOR_IO - [metadata pages]) / 2
++ * - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
+ *
+ * of them, which corresponds to the maximum size of a hibernation image.
+ *
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 5b52727dcc1c4..aedd43e1f21c4 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -2415,7 +2415,7 @@ void rcu_force_quiescent_state(void)
+ struct rcu_node *rnp_old = NULL;
+
+ /* Funnel through hierarchy to reduce memory contention. */
+- rnp = __this_cpu_read(rcu_data.mynode);
++ rnp = raw_cpu_read(rcu_data.mynode);
+ for (; rnp != NULL; rnp = rnp->parent) {
+ ret = (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) ||
+ !raw_spin_trylock(&rnp->fqslock);
+diff --git a/kernel/relay.c b/kernel/relay.c
+index 6a611e779e958..fd1d196e04d4f 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -151,13 +151,13 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan)
+ {
+ struct rchan_buf *buf;
+
+- if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
++ if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t))
+ return NULL;
+
+ buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+ if (!buf)
+ return NULL;
+- buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *),
++ buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t),
+ GFP_KERNEL);
+ if (!buf->padding)
+ goto free_buf;
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index ee28253c9ac0c..cb9d8ae7c4dbf 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1398,7 +1398,7 @@ static inline void uclamp_idle_reset(struct rq *rq, enum uclamp_id clamp_id,
+ if (!(rq->uclamp_flags & UCLAMP_FLAG_IDLE))
+ return;
+
+- WRITE_ONCE(rq->uclamp[clamp_id].value, clamp_value);
++ uclamp_rq_set(rq, clamp_id, clamp_value);
+ }
+
+ static inline
+@@ -1549,8 +1549,8 @@ static inline void uclamp_rq_inc_id(struct rq *rq, struct task_struct *p,
+ if (bucket->tasks == 1 || uc_se->value > bucket->value)
+ bucket->value = uc_se->value;
+
+- if (uc_se->value > READ_ONCE(uc_rq->value))
+- WRITE_ONCE(uc_rq->value, uc_se->value);
++ if (uc_se->value > uclamp_rq_get(rq, clamp_id))
++ uclamp_rq_set(rq, clamp_id, uc_se->value);
+ }
+
+ /*
+@@ -1616,7 +1616,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
+ if (likely(bucket->tasks))
+ return;
+
+- rq_clamp = READ_ONCE(uc_rq->value);
++ rq_clamp = uclamp_rq_get(rq, clamp_id);
+ /*
+ * Defensive programming: this should never happen. If it happens,
+ * e.g. due to future modification, warn and fixup the expected value.
+@@ -1624,7 +1624,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
+ SCHED_WARN_ON(bucket->value > rq_clamp);
+ if (bucket->value >= rq_clamp) {
+ bkt_clamp = uclamp_rq_max_value(rq, clamp_id, uc_se->value);
+- WRITE_ONCE(uc_rq->value, bkt_clamp);
++ uclamp_rq_set(rq, clamp_id, bkt_clamp);
+ }
+ }
+
+diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c
+index 02d970a879edd..57c92d751bcd7 100644
+--- a/kernel/sched/cpudeadline.c
++++ b/kernel/sched/cpudeadline.c
+@@ -123,7 +123,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,
+ unsigned long cap, max_cap = 0;
+ int cpu, max_cpu = -1;
+
+- if (!static_branch_unlikely(&sched_asym_cpucapacity))
++ if (!sched_asym_cpucap_active())
+ return 1;
+
+ /* Ensure the capacity of the CPUs fits the task. */
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 0ab79d819a0d6..8bebc36a1b71b 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -144,7 +144,7 @@ static inline unsigned long __dl_bw_capacity(int i)
+ */
+ static inline unsigned long dl_bw_capacity(int i)
+ {
+- if (!static_branch_unlikely(&sched_asym_cpucapacity) &&
++ if (!sched_asym_cpucap_active() &&
+ capacity_orig_of(i) == SCHED_CAPACITY_SCALE) {
+ return dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT;
+ } else {
+@@ -1849,7 +1849,7 @@ select_task_rq_dl(struct task_struct *p, int cpu, int flags)
+ * Take the capacity of the CPU into account to
+ * ensure it fits the requirement of the task.
+ */
+- if (static_branch_unlikely(&sched_asym_cpucapacity))
++ if (sched_asym_cpucap_active())
+ select_rq |= !dl_task_fits_capacity(p, cpu);
+
+ if (select_rq) {
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 914096c5b1ae1..532e6cdf706d6 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -4108,14 +4108,16 @@ static inline unsigned long task_util_est(struct task_struct *p)
+ }
+
+ #ifdef CONFIG_UCLAMP_TASK
+-static inline unsigned long uclamp_task_util(struct task_struct *p)
++static inline unsigned long uclamp_task_util(struct task_struct *p,
++ unsigned long uclamp_min,
++ unsigned long uclamp_max)
+ {
+- return clamp(task_util_est(p),
+- uclamp_eff_value(p, UCLAMP_MIN),
+- uclamp_eff_value(p, UCLAMP_MAX));
++ return clamp(task_util_est(p), uclamp_min, uclamp_max);
+ }
+ #else
+-static inline unsigned long uclamp_task_util(struct task_struct *p)
++static inline unsigned long uclamp_task_util(struct task_struct *p,
++ unsigned long uclamp_min,
++ unsigned long uclamp_max)
+ {
+ return task_util_est(p);
+ }
+@@ -4254,15 +4256,140 @@ done:
+ trace_sched_util_est_se_tp(&p->se);
+ }
+
+-static inline int task_fits_capacity(struct task_struct *p,
+- unsigned long capacity)
++static inline int util_fits_cpu(unsigned long util,
++ unsigned long uclamp_min,
++ unsigned long uclamp_max,
++ int cpu)
+ {
+- return fits_capacity(uclamp_task_util(p), capacity);
++ unsigned long capacity_orig, capacity_orig_thermal;
++ unsigned long capacity = capacity_of(cpu);
++ bool fits, uclamp_max_fits;
++
++ /*
++ * Check if the real util fits without any uclamp boost/cap applied.
++ */
++ fits = fits_capacity(util, capacity);
++
++ if (!uclamp_is_used())
++ return fits;
++
++ /*
++ * We must use capacity_orig_of() for comparing against uclamp_min and
++ * uclamp_max. We only care about capacity pressure (by using
++ * capacity_of()) for comparing against the real util.
++ *
++ * If a task is boosted to 1024 for example, we don't want a tiny
++ * pressure to skew the check whether it fits a CPU or not.
++ *
++ * Similarly if a task is capped to capacity_orig_of(little_cpu), it
++ * should fit a little cpu even if there's some pressure.
++ *
++ * Only exception is for thermal pressure since it has a direct impact
++ * on available OPP of the system.
++ *
++ * We honour it for uclamp_min only as a drop in performance level
++ * could result in not getting the requested minimum performance level.
++ *
++ * For uclamp_max, we can tolerate a drop in performance level as the
++ * goal is to cap the task. So it's okay if it's getting less.
++ *
++ * In case of capacity inversion, which is not handled yet, we should
++ * honour the inverted capacity for both uclamp_min and uclamp_max all
++ * the time.
++ */
++ capacity_orig = capacity_orig_of(cpu);
++ capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
++
++ /*
++ * We want to force a task to fit a cpu as implied by uclamp_max.
++ * But we do have some corner cases to cater for..
++ *
++ *
++ * C=z
++ * | ___
++ * | C=y | |
++ * |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _ uclamp_max
++ * | C=x | | | |
++ * | ___ | | | |
++ * | | | | | | | (util somewhere in this region)
++ * | | | | | | |
++ * | | | | | | |
++ * +----------------------------------------
++ * cpu0 cpu1 cpu2
++ *
++ * In the above example if a task is capped to a specific performance
++ * point, y, then when:
++ *
++ * * util = 80% of x then it does not fit on cpu0 and should migrate
++ * to cpu1
++ * * util = 80% of y then it is forced to fit on cpu1 to honour
++ * uclamp_max request.
++ *
++ * which is what we're enforcing here. A task always fits if
++ * uclamp_max <= capacity_orig. But when uclamp_max > capacity_orig,
++ * the normal upmigration rules should withhold still.
++ *
++ * Only exception is when we are on max capacity, then we need to be
++ * careful not to block overutilized state. This is so because:
++ *
++ * 1. There's no concept of capping at max_capacity! We can't go
++ * beyond this performance level anyway.
++ * 2. The system is being saturated when we're operating near
++ * max capacity, it doesn't make sense to block overutilized.
++ */
++ uclamp_max_fits = (capacity_orig == SCHED_CAPACITY_SCALE) && (uclamp_max == SCHED_CAPACITY_SCALE);
++ uclamp_max_fits = !uclamp_max_fits && (uclamp_max <= capacity_orig);
++ fits = fits || uclamp_max_fits;
++
++ /*
++ *
++ * C=z
++ * | ___ (region a, capped, util >= uclamp_max)
++ * | C=y | |
++ * |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _ uclamp_max
++ * | C=x | | | |
++ * | ___ | | | | (region b, uclamp_min <= util <= uclamp_max)
++ * |_ _ _|_ _|_ _ _ _| _ | _ _ _| _ | _ _ _ _ _ uclamp_min
++ * | | | | | | |
++ * | | | | | | | (region c, boosted, util < uclamp_min)
++ * +----------------------------------------
++ * cpu0 cpu1 cpu2
++ *
++ * a) If util > uclamp_max, then we're capped, we don't care about
++ * actual fitness value here. We only care if uclamp_max fits
++ * capacity without taking margin/pressure into account.
++ * See comment above.
++ *
++ * b) If uclamp_min <= util <= uclamp_max, then the normal
++ * fits_capacity() rules apply. Except we need to ensure that we
++ * enforce we remain within uclamp_max, see comment above.
++ *
++ * c) If util < uclamp_min, then we are boosted. Same as (b) but we
++ * need to take into account the boosted value fits the CPU without
++ * taking margin/pressure into account.
++ *
++ * Cases (a) and (b) are handled in the 'fits' variable already. We
++ * just need to consider an extra check for case (c) after ensuring we
++ * handle the case uclamp_min > uclamp_max.
++ */
++ uclamp_min = min(uclamp_min, uclamp_max);
++ if (util < uclamp_min && capacity_orig != SCHED_CAPACITY_SCALE)
++ fits = fits && (uclamp_min <= capacity_orig_thermal);
++
++ return fits;
++}
++
++static inline int task_fits_cpu(struct task_struct *p, int cpu)
++{
++ unsigned long uclamp_min = uclamp_eff_value(p, UCLAMP_MIN);
++ unsigned long uclamp_max = uclamp_eff_value(p, UCLAMP_MAX);
++ unsigned long util = task_util_est(p);
++ return util_fits_cpu(util, uclamp_min, uclamp_max, cpu);
+ }
+
+ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
+ {
+- if (!static_branch_unlikely(&sched_asym_cpucapacity))
++ if (!sched_asym_cpucap_active())
+ return;
+
+ if (!p || p->nr_cpus_allowed == 1) {
+@@ -4270,7 +4397,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
+ return;
+ }
+
+- if (task_fits_capacity(p, capacity_of(cpu_of(rq)))) {
++ if (task_fits_cpu(p, cpu_of(rq))) {
+ rq->misfit_task_load = 0;
+ return;
+ }
+@@ -5682,7 +5809,10 @@ static inline void hrtick_update(struct rq *rq)
+ #ifdef CONFIG_SMP
+ static inline bool cpu_overutilized(int cpu)
+ {
+- return !fits_capacity(cpu_util_cfs(cpu), capacity_of(cpu));
++ unsigned long rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
++ unsigned long rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
++
++ return !util_fits_cpu(cpu_util_cfs(cpu), rq_util_min, rq_util_max, cpu);
+ }
+
+ static inline void update_overutilized_status(struct rq *rq)
+@@ -6478,21 +6608,23 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+ static int
+ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
+ {
+- unsigned long task_util, best_cap = 0;
++ unsigned long task_util, util_min, util_max, best_cap = 0;
+ int cpu, best_cpu = -1;
+ struct cpumask *cpus;
+
+ cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
+ cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+
+- task_util = uclamp_task_util(p);
++ task_util = task_util_est(p);
++ util_min = uclamp_eff_value(p, UCLAMP_MIN);
++ util_max = uclamp_eff_value(p, UCLAMP_MAX);
+
+ for_each_cpu_wrap(cpu, cpus, target) {
+ unsigned long cpu_cap = capacity_of(cpu);
+
+ if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu))
+ continue;
+- if (fits_capacity(task_util, cpu_cap))
++ if (util_fits_cpu(task_util, util_min, util_max, cpu))
+ return cpu;
+
+ if (cpu_cap > best_cap) {
+@@ -6504,10 +6636,13 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
+ return best_cpu;
+ }
+
+-static inline bool asym_fits_capacity(unsigned long task_util, int cpu)
++static inline bool asym_fits_cpu(unsigned long util,
++ unsigned long util_min,
++ unsigned long util_max,
++ int cpu)
+ {
+- if (static_branch_unlikely(&sched_asym_cpucapacity))
+- return fits_capacity(task_util, capacity_of(cpu));
++ if (sched_asym_cpucap_active())
++ return util_fits_cpu(util, util_min, util_max, cpu);
+
+ return true;
+ }
+@@ -6519,16 +6654,18 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ {
+ bool has_idle_core = false;
+ struct sched_domain *sd;
+- unsigned long task_util;
++ unsigned long task_util, util_min, util_max;
+ int i, recent_used_cpu;
+
+ /*
+ * On asymmetric system, update task utilization because we will check
+ * that the task fits with cpu's capacity.
+ */
+- if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++ if (sched_asym_cpucap_active()) {
+ sync_entity_load_avg(&p->se);
+- task_util = uclamp_task_util(p);
++ task_util = task_util_est(p);
++ util_min = uclamp_eff_value(p, UCLAMP_MIN);
++ util_max = uclamp_eff_value(p, UCLAMP_MAX);
+ }
+
+ /*
+@@ -6537,7 +6674,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ lockdep_assert_irqs_disabled();
+
+ if ((available_idle_cpu(target) || sched_idle_cpu(target)) &&
+- asym_fits_capacity(task_util, target))
++ asym_fits_cpu(task_util, util_min, util_max, target))
+ return target;
+
+ /*
+@@ -6545,7 +6682,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ */
+ if (prev != target && cpus_share_cache(prev, target) &&
+ (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
+- asym_fits_capacity(task_util, prev))
++ asym_fits_cpu(task_util, util_min, util_max, prev))
+ return prev;
+
+ /*
+@@ -6560,7 +6697,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ in_task() &&
+ prev == smp_processor_id() &&
+ this_rq()->nr_running <= 1 &&
+- asym_fits_capacity(task_util, prev)) {
++ asym_fits_cpu(task_util, util_min, util_max, prev)) {
+ return prev;
+ }
+
+@@ -6572,7 +6709,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ cpus_share_cache(recent_used_cpu, target) &&
+ (available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) &&
+ cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
+- asym_fits_capacity(task_util, recent_used_cpu)) {
++ asym_fits_cpu(task_util, util_min, util_max, recent_used_cpu)) {
+ return recent_used_cpu;
+ }
+
+@@ -6580,7 +6717,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ * For asymmetric CPU capacity systems, our domain of interest is
+ * sd_asym_cpucapacity rather than sd_llc.
+ */
+- if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++ if (sched_asym_cpucap_active()) {
+ sd = rcu_dereference(per_cpu(sd_asym_cpucapacity, target));
+ /*
+ * On an asymmetric CPU capacity system where an exclusive
+@@ -6868,6 +7005,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ {
+ struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
+ unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX;
++ unsigned long p_util_min = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MIN) : 0;
++ unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024;
+ struct root_domain *rd = this_rq()->rd;
+ int cpu, best_energy_cpu, target = -1;
+ struct sched_domain *sd;
+@@ -6892,7 +7031,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ target = prev_cpu;
+
+ sync_entity_load_avg(&p->se);
+- if (!task_util_est(p))
++ if (!uclamp_task_util(p, p_util_min, p_util_max))
+ goto unlock;
+
+ eenv_task_busy_time(&eenv, p, prev_cpu);
+@@ -6900,6 +7039,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ for (; pd; pd = pd->next) {
+ unsigned long cpu_cap, cpu_thermal_cap, util;
+ unsigned long cur_delta, max_spare_cap = 0;
++ unsigned long rq_util_min, rq_util_max;
++ unsigned long util_min, util_max;
+ bool compute_prev_delta = false;
+ int max_spare_cap_cpu = -1;
+ unsigned long base_energy;
+@@ -6936,8 +7077,26 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ * much capacity we can get out of the CPU; this is
+ * aligned with sched_cpu_util().
+ */
+- util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
+- if (!fits_capacity(util, cpu_cap))
++ if (uclamp_is_used()) {
++ if (uclamp_rq_is_idle(cpu_rq(cpu))) {
++ util_min = p_util_min;
++ util_max = p_util_max;
++ } else {
++ /*
++ * Open code uclamp_rq_util_with() except for
++ * the clamp() part. Ie: apply max aggregation
++ * only. util_fits_cpu() logic requires to
++ * operate on non clamped util but must use the
++ * max-aggregated uclamp_{min, max}.
++ */
++ rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
++ rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
++
++ util_min = max(rq_util_min, p_util_min);
++ util_max = max(rq_util_max, p_util_max);
++ }
++ }
++ if (!util_fits_cpu(util, util_min, util_max, cpu))
+ continue;
+
+ lsub_positive(&cpu_cap, util);
+@@ -8108,7 +8267,7 @@ static int detach_tasks(struct lb_env *env)
+
+ case migrate_misfit:
+ /* This is not a misfit task */
+- if (task_fits_capacity(p, capacity_of(env->src_cpu)))
++ if (task_fits_cpu(p, env->src_cpu))
+ goto next;
+
+ env->imbalance = 0;
+@@ -9113,6 +9272,10 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
+
+ memset(sgs, 0, sizeof(*sgs));
+
++ /* Assume that task can't fit any CPU of the group */
++ if (sd->flags & SD_ASYM_CPUCAPACITY)
++ sgs->group_misfit_task_load = 1;
++
+ for_each_cpu(i, sched_group_span(group)) {
+ struct rq *rq = cpu_rq(i);
+ unsigned int local;
+@@ -9132,12 +9295,12 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
+ if (!nr_running && idle_cpu_without(i, p))
+ sgs->idle_cpus++;
+
+- }
++ /* Check if task fits in the CPU */
++ if (sd->flags & SD_ASYM_CPUCAPACITY &&
++ sgs->group_misfit_task_load &&
++ task_fits_cpu(p, i))
++ sgs->group_misfit_task_load = 0;
+
+- /* Check if task fits in the group */
+- if (sd->flags & SD_ASYM_CPUCAPACITY &&
+- !task_fits_capacity(p, group->sgc->max_capacity)) {
+- sgs->group_misfit_task_load = 1;
+ }
+
+ sgs->group_capacity = group->sgc->capacity;
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
+index ecb4b4ff4ce0a..559416a27c0ed 100644
+--- a/kernel/sched/psi.c
++++ b/kernel/sched/psi.c
+@@ -537,10 +537,12 @@ static u64 update_triggers(struct psi_group *group, u64 now)
+
+ /* Calculate growth since last update */
+ growth = window_update(&t->win, now, total[t->state]);
+- if (growth < t->threshold)
+- continue;
++ if (!t->pending_event) {
++ if (growth < t->threshold)
++ continue;
+
+- t->pending_event = true;
++ t->pending_event = true;
++ }
+ }
+ /* Limit event signaling to once per window */
+ if (now < t->last_event_time + t->win.size)
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 55f39c8f42032..054b6711e9619 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -509,7 +509,7 @@ static inline bool rt_task_fits_capacity(struct task_struct *p, int cpu)
+ unsigned int cpu_cap;
+
+ /* Only heterogeneous systems can benefit from this check */
+- if (!static_branch_unlikely(&sched_asym_cpucapacity))
++ if (!sched_asym_cpucap_active())
+ return true;
+
+ min_cap = uclamp_eff_value(p, UCLAMP_MIN);
+@@ -1897,7 +1897,7 @@ static int find_lowest_rq(struct task_struct *task)
+ * If we're on asym system ensure we consider the different capacities
+ * of the CPUs when searching for the lowest_mask.
+ */
+- if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++ if (sched_asym_cpucap_active()) {
+
+ ret = cpupri_find_fitness(&task_rq(task)->rd->cpupri,
+ task, lowest_mask,
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index f34b489636ffb..2fcb7eb56c018 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -1815,6 +1815,11 @@ DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing);
+ DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_cpucapacity);
+ extern struct static_key_false sched_asym_cpucapacity;
+
++static __always_inline bool sched_asym_cpucap_active(void)
++{
++ return static_branch_unlikely(&sched_asym_cpucapacity);
++}
++
+ struct sched_group_capacity {
+ atomic_t ref;
+ /*
+@@ -2963,6 +2968,23 @@ static inline unsigned long cpu_util_rt(struct rq *rq)
+ #ifdef CONFIG_UCLAMP_TASK
+ unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
+
++static inline unsigned long uclamp_rq_get(struct rq *rq,
++ enum uclamp_id clamp_id)
++{
++ return READ_ONCE(rq->uclamp[clamp_id].value);
++}
++
++static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
++ unsigned int value)
++{
++ WRITE_ONCE(rq->uclamp[clamp_id].value, value);
++}
++
++static inline bool uclamp_rq_is_idle(struct rq *rq)
++{
++ return rq->uclamp_flags & UCLAMP_FLAG_IDLE;
++}
++
+ /**
+ * uclamp_rq_util_with - clamp @util with @rq and @p effective uclamp values.
+ * @rq: The rq to clamp against. Must not be NULL.
+@@ -2998,12 +3020,12 @@ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
+ * Ignore last runnable task's max clamp, as this task will
+ * reset it. Similarly, no need to read the rq's min clamp.
+ */
+- if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
++ if (uclamp_rq_is_idle(rq))
+ goto out;
+ }
+
+- min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
+- max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
++ min_util = max_t(unsigned long, min_util, uclamp_rq_get(rq, UCLAMP_MIN));
++ max_util = max_t(unsigned long, max_util, uclamp_rq_get(rq, UCLAMP_MAX));
+ out:
+ /*
+ * Since CPU's {min,max}_util clamps are MAX aggregated considering
+@@ -3044,6 +3066,15 @@ static inline bool uclamp_is_used(void)
+ return static_branch_likely(&sched_uclamp_used);
+ }
+ #else /* CONFIG_UCLAMP_TASK */
++static inline unsigned long uclamp_eff_value(struct task_struct *p,
++ enum uclamp_id clamp_id)
++{
++ if (clamp_id == UCLAMP_MIN)
++ return 0;
++
++ return SCHED_CAPACITY_SCALE;
++}
++
+ static inline
+ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
+ struct task_struct *p)
+@@ -3057,6 +3088,25 @@ static inline bool uclamp_is_used(void)
+ {
+ return false;
+ }
++
++static inline unsigned long uclamp_rq_get(struct rq *rq,
++ enum uclamp_id clamp_id)
++{
++ if (clamp_id == UCLAMP_MIN)
++ return 0;
++
++ return SCHED_CAPACITY_SCALE;
++}
++
++static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
++ unsigned int value)
++{
++}
++
++static inline bool uclamp_rq_is_idle(struct rq *rq)
++{
++ return false;
++}
+ #endif /* CONFIG_UCLAMP_TASK */
+
+ #ifdef CONFIG_HAVE_SCHED_AVG_IRQ
+diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
+index 7f5eb295fe198..ee22a3b1c1816 100644
+--- a/kernel/trace/blktrace.c
++++ b/kernel/trace/blktrace.c
+@@ -1546,7 +1546,8 @@ blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
+
+ static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
+ {
+- if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
++ if ((iter->ent->type != TRACE_BLK) ||
++ !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+ return TRACE_TYPE_UNHANDLED;
+
+ return print_one_line(iter, true);
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 49243e8617148..d8406f6f5d399 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -6346,7 +6346,7 @@ enable:
+ if (se)
+ se->ref++;
+ out:
+- if (ret == 0)
++ if (ret == 0 && glob[0])
+ hist_err_clear();
+
+ return ret;
+diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
+index a6621c52ce454..b885b6934893f 100644
+--- a/kernel/trace/trace_events_user.c
++++ b/kernel/trace/trace_events_user.c
+@@ -1127,6 +1127,7 @@ put_user_lock:
+ put_user:
+ user_event_destroy_fields(user);
+ user_event_destroy_validators(user);
++ kfree(user->call.print_fmt);
+ kfree(user);
+ return ret;
+ }
+diff --git a/lib/debugobjects.c b/lib/debugobjects.c
+index 337d797a71416..6f8e5dd1dcd0c 100644
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -437,6 +437,7 @@ static int object_cpu_offline(unsigned int cpu)
+ struct debug_percpu_free *percpu_pool;
+ struct hlist_node *tmp;
+ struct debug_obj *obj;
++ unsigned long flags;
+
+ /* Remote access is safe as the CPU is dead already */
+ percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu);
+@@ -444,6 +445,12 @@ static int object_cpu_offline(unsigned int cpu)
+ hlist_del(&obj->node);
+ kmem_cache_free(obj_cache, obj);
+ }
++
++ raw_spin_lock_irqsave(&pool_lock, flags);
++ obj_pool_used -= percpu_pool->obj_free;
++ debug_objects_freed += percpu_pool->obj_free;
++ raw_spin_unlock_irqrestore(&pool_lock, flags);
++
+ percpu_pool->obj_free = 0;
+
+ return 0;
+@@ -1318,6 +1325,8 @@ static int __init debug_objects_replace_static_objects(void)
+ hlist_add_head(&obj->node, &objects);
+ }
+
++ debug_objects_allocated += i;
++
+ /*
+ * debug_objects_mem_init() is now called early that only one CPU is up
+ * and interrupts have been disabled, so it is safe to replace the
+@@ -1386,6 +1395,7 @@ void __init debug_objects_mem_init(void)
+ debug_objects_enabled = 0;
+ kmem_cache_destroy(obj_cache);
+ pr_warn("out of memory.\n");
++ return;
+ } else
+ debug_objects_selftest();
+
+diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c
+index 5f4b07b56cd9c..9738664386088 100644
+--- a/lib/fonts/fonts.c
++++ b/lib/fonts/fonts.c
+@@ -135,8 +135,8 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
+ if (res > 20)
+ c += 20 - res;
+
+- if ((font_w & (1 << (f->width - 1))) &&
+- (font_h & (1 << (f->height - 1))))
++ if ((font_w & (1U << (f->width - 1))) &&
++ (font_h & (1U << (f->height - 1))))
+ c += 1000;
+
+ if (c > cc) {
+diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
+index 21016b32d3131..2b24ea6c94979 100644
+--- a/lib/notifier-error-inject.c
++++ b/lib/notifier-error-inject.c
+@@ -15,7 +15,7 @@ static int debugfs_errno_get(void *data, u64 *val)
+ return 0;
+ }
+
+-DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
++DEFINE_SIMPLE_ATTRIBUTE_SIGNED(fops_errno, debugfs_errno_get, debugfs_errno_set,
+ "%lld\n");
+
+ static struct dentry *debugfs_create_errno(const char *name, umode_t mode,
+diff --git a/lib/test_firmware.c b/lib/test_firmware.c
+index c82b65947ce68..1c5a2adb16ef5 100644
+--- a/lib/test_firmware.c
++++ b/lib/test_firmware.c
+@@ -1491,6 +1491,7 @@ static int __init test_firmware_init(void)
+
+ rc = misc_register(&test_fw_misc_device);
+ if (rc) {
++ __test_firmware_config_free();
+ kfree(test_fw_config);
+ pr_err("could not register misc device: %d\n", rc);
+ return rc;
+diff --git a/mm/gup.c b/mm/gup.c
+index d7f9116fc645c..60d7213ad95b3 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1058,6 +1058,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
+ if (!(vm_flags & VM_WRITE)) {
+ if (!(gup_flags & FOLL_FORCE))
+ return -EFAULT;
++ /* hugetlb does not support FOLL_FORCE|FOLL_WRITE. */
++ if (is_vm_hugetlb_page(vma))
++ return -EFAULT;
+ /*
+ * We used to let the write,force case do COW in a
+ * VM_MAYWRITE VM_SHARED !VM_WRITE vma, so ptrace could
+diff --git a/net/802/mrp.c b/net/802/mrp.c
+index 35e04cc5390c4..c10a432a5b435 100644
+--- a/net/802/mrp.c
++++ b/net/802/mrp.c
+@@ -606,7 +606,10 @@ static void mrp_join_timer(struct timer_list *t)
+ spin_unlock(&app->lock);
+
+ mrp_queue_xmit(app);
+- mrp_join_timer_arm(app);
++ spin_lock(&app->lock);
++ if (likely(app->active))
++ mrp_join_timer_arm(app);
++ spin_unlock(&app->lock);
+ }
+
+ static void mrp_periodic_timer_arm(struct mrp_applicant *app)
+@@ -620,11 +623,12 @@ static void mrp_periodic_timer(struct timer_list *t)
+ struct mrp_applicant *app = from_timer(app, t, periodic_timer);
+
+ spin_lock(&app->lock);
+- mrp_mad_event(app, MRP_EVENT_PERIODIC);
+- mrp_pdu_queue(app);
++ if (likely(app->active)) {
++ mrp_mad_event(app, MRP_EVENT_PERIODIC);
++ mrp_pdu_queue(app);
++ mrp_periodic_timer_arm(app);
++ }
+ spin_unlock(&app->lock);
+-
+- mrp_periodic_timer_arm(app);
+ }
+
+ static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
+@@ -872,6 +876,7 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
+ app->dev = dev;
+ app->app = appl;
+ app->mad = RB_ROOT;
++ app->active = true;
+ spin_lock_init(&app->lock);
+ skb_queue_head_init(&app->queue);
+ rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
+@@ -900,6 +905,9 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
+
+ RCU_INIT_POINTER(port->applicants[appl->type], NULL);
+
++ spin_lock_bh(&app->lock);
++ app->active = false;
++ spin_unlock_bh(&app->lock);
+ /* Delete timer and generate a final TX event to flush out
+ * all pending messages before the applicant is gone.
+ */
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index 035812b0461cc..ecdb47712d956 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -712,13 +712,13 @@ static void vlan_dev_get_stats64(struct net_device *dev,
+
+ p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&p->syncp);
++ start = u64_stats_fetch_begin(&p->syncp);
+ rxpackets = u64_stats_read(&p->rx_packets);
+ rxbytes = u64_stats_read(&p->rx_bytes);
+ rxmulticast = u64_stats_read(&p->rx_multicast);
+ txpackets = u64_stats_read(&p->tx_packets);
+ txbytes = u64_stats_read(&p->tx_bytes);
+- } while (u64_stats_fetch_retry_irq(&p->syncp, start));
++ } while (u64_stats_fetch_retry(&p->syncp, start));
+
+ stats->rx_packets += rxpackets;
+ stats->rx_bytes += rxbytes;
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 0a6110e15d0f8..8464d95805d08 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -279,6 +279,11 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
+ p9pdu_reset(&req->rc);
+ req->t_err = 0;
+ req->status = REQ_STATUS_ALLOC;
++ /* refcount needs to be set to 0 before inserting into the idr
++ * so p9_tag_lookup does not accept a request that is not fully
++ * initialized. refcount_set to 2 below will mark request ready.
++ */
++ refcount_set(&req->refcount, 0);
+ init_waitqueue_head(&req->wq);
+ INIT_LIST_HEAD(&req->req_list);
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index f26ed278d9e3c..67360444eee6c 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1817,7 +1817,7 @@ static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
+ continue;
+
+ /* Check if all CIS(s) belonging to a CIG are ready */
+- if (conn->link->state != BT_CONNECTED ||
++ if (!conn->link || conn->link->state != BT_CONNECTED ||
+ conn->state != BT_CONNECT) {
+ cmd.cp.num_cis = 0;
+ break;
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index c8ea03edd081f..9f8b49ff2d339 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2653,7 +2653,7 @@ int hci_register_dev(struct hci_dev *hdev)
+
+ error = hci_register_suspend_notifier(hdev);
+ if (error)
+- goto err_wqueue;
++ BT_WARN("register suspend notifier failed error:%d\n", error);
+
+ queue_work(hdev->req_workqueue, &hdev->power_on);
+
+@@ -3978,7 +3978,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
+ *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
+ else
+ *req_complete = bt_cb(skb)->hci.req_complete;
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ }
+ spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index a5e89e1b5452a..117537f3e7ad0 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3940,7 +3940,7 @@ static int hci_read_local_pairing_opts_sync(struct hci_dev *hdev)
+ /* Get MWS transport configuration if the HCI command is supported */
+ static int hci_get_mws_transport_config_sync(struct hci_dev *hdev)
+ {
+- if (!(hdev->commands[30] & 0x08))
++ if (!mws_transport_config_capable(hdev))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_GET_MWS_TRANSPORT_CONFIG,
+diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
+index 469a0c95b6e8a..53a796ac078c3 100644
+--- a/net/bluetooth/lib.c
++++ b/net/bluetooth/lib.c
+@@ -170,7 +170,7 @@ __u8 bt_status(int err)
+ case -EMLINK:
+ return 0x09;
+
+- case EALREADY:
++ case -EALREADY:
+ return 0x0b;
+
+ case -EBUSY:
+@@ -191,7 +191,7 @@ __u8 bt_status(int err)
+ case -ECONNABORTED:
+ return 0x16;
+
+- case ELOOP:
++ case -ELOOP:
+ return 0x17;
+
+ case -EPROTONOSUPPORT:
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 3d1cd06669688..22bfeb5b2b3bb 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -8385,7 +8385,7 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
+ * extra parameters we don't know about will be ignored in this request.
+ */
+ if (data_len < MGMT_ADD_EXT_ADV_PARAMS_MIN_SIZE)
+- return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
++ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS,
+ MGMT_STATUS_INVALID_PARAMS);
+
+ flags = __le32_to_cpu(cp->flags);
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+index 7324764384b67..8d6fce9005bdd 100644
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -590,7 +590,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
+
+ ret = rfcomm_dlc_send_frag(d, frag);
+ if (ret < 0) {
+- kfree_skb(frag);
++ dev_kfree_skb_irq(frag);
+ goto unlock;
+ }
+
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index b422238f9f86c..5d53332ea3c9d 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -939,9 +939,6 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
+ {
+ struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
+
+- if (!skb->len)
+- return -EINVAL;
+-
+ if (!__skb)
+ return 0;
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index db4f2641d1cd1..7e2a9fb5786c9 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -4899,9 +4899,9 @@ void br_multicast_get_stats(const struct net_bridge *br,
+ unsigned int start;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ memcpy(&temp, &cpu_stats->mstats, sizeof(temp));
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ mcast_stats_add_dir(tdst.igmp_v1queries, temp.igmp_v1queries);
+ mcast_stats_add_dir(tdst.igmp_v2queries, temp.igmp_v2queries);
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index 9ffd40b8270c1..bc75fa1e4666a 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -1389,12 +1389,12 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
+
+ cpu_stats = per_cpu_ptr(v->stats, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ rxpackets = u64_stats_read(&cpu_stats->rx_packets);
+ rxbytes = u64_stats_read(&cpu_stats->rx_bytes);
+ txbytes = u64_stats_read(&cpu_stats->tx_bytes);
+ txpackets = u64_stats_read(&cpu_stats->tx_packets);
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ u64_stats_add(&stats->rx_packets, rxpackets);
+ u64_stats_add(&stats->rx_bytes, rxbytes);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 2c14f48d24573..25c73f9677611 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10398,24 +10398,16 @@ void netdev_run_todo(void)
+ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
+ const struct net_device_stats *netdev_stats)
+ {
+-#if BITS_PER_LONG == 64
+- BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
+- memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
+- /* zero out counters that only exist in rtnl_link_stats64 */
+- memset((char *)stats64 + sizeof(*netdev_stats), 0,
+- sizeof(*stats64) - sizeof(*netdev_stats));
+-#else
+- size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long);
+- const unsigned long *src = (const unsigned long *)netdev_stats;
++ size_t i, n = sizeof(*netdev_stats) / sizeof(atomic_long_t);
++ const atomic_long_t *src = (atomic_long_t *)netdev_stats;
+ u64 *dst = (u64 *)stats64;
+
+ BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64));
+ for (i = 0; i < n; i++)
+- dst[i] = src[i];
++ dst[i] = atomic_long_read(&src[i]);
+ /* zero out counters that only exist in rtnl_link_stats64 */
+ memset((char *)stats64 + n * sizeof(u64), 0,
+ sizeof(*stats64) - n * sizeof(u64));
+-#endif
+ }
+ EXPORT_SYMBOL(netdev_stats_to_stats64);
+
+@@ -10496,12 +10488,12 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
+
+ stats = per_cpu_ptr(netstats, cpu);
+ do {
+- start = u64_stats_fetch_begin_irq(&stats->syncp);
++ start = u64_stats_fetch_begin(&stats->syncp);
+ rx_packets = u64_stats_read(&stats->rx_packets);
+ rx_bytes = u64_stats_read(&stats->rx_bytes);
+ tx_packets = u64_stats_read(&stats->tx_packets);
+ tx_bytes = u64_stats_read(&stats->tx_bytes);
+- } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
++ } while (u64_stats_fetch_retry(&stats->syncp, start));
+
+ s->rx_packets += rx_packets;
+ s->rx_bytes += rx_bytes;
+diff --git a/net/core/devlink.c b/net/core/devlink.c
+index b50bcc18b8d9e..5f894bd20c310 100644
+--- a/net/core/devlink.c
++++ b/net/core/devlink.c
+@@ -1498,10 +1498,13 @@ static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
+ continue;
+ }
+
++ devl_lock(devlink);
+ err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI);
++ devl_unlock(devlink);
+ devlink_put(devlink);
++
+ if (err)
+ goto out;
+ idx++;
+@@ -8268,10 +8271,10 @@ static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
+
+ cpu_stats = per_cpu_ptr(trap_stats, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ rx_packets = u64_stats_read(&cpu_stats->rx_packets);
+ rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ u64_stats_add(&stats->rx_packets, rx_packets);
+ u64_stats_add(&stats->rx_bytes, rx_bytes);
+@@ -11358,8 +11361,10 @@ void devl_region_destroy(struct devlink_region *region)
+ devl_assert_locked(devlink);
+
+ /* Free all snapshots of region */
++ mutex_lock(®ion->snapshot_lock);
+ list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
+ devlink_region_snapshot_del(region, snapshot);
++ mutex_unlock(®ion->snapshot_lock);
+
+ list_del(®ion->list);
+ mutex_destroy(®ion->snapshot_lock);
+diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
+index 75501e1bdd25b..dfcaf61d972c7 100644
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -1432,9 +1432,9 @@ static void net_dm_stats_read(struct net_dm_stats *stats)
+ u64 dropped;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ dropped = u64_stats_read(&cpu_stats->dropped);
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ u64_stats_add(&stats->dropped, dropped);
+ }
+@@ -1476,9 +1476,9 @@ static void net_dm_hw_stats_read(struct net_dm_stats *stats)
+ u64 dropped;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ dropped = u64_stats_read(&cpu_stats->dropped);
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ u64_stats_add(&stats->dropped, dropped);
+ }
+diff --git a/net/core/filter.c b/net/core/filter.c
+index c191db80ce93c..3aae1885b9702 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2123,8 +2123,17 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
+ {
+ unsigned int mlen = skb_network_offset(skb);
+
++ if (unlikely(skb->len <= mlen)) {
++ kfree_skb(skb);
++ return -ERANGE;
++ }
++
+ if (mlen) {
+ __skb_pull(skb, mlen);
++ if (unlikely(!skb->len)) {
++ kfree_skb(skb);
++ return -ERANGE;
++ }
+
+ /* At ingress, the mac header has already been pulled once.
+ * At egress, skb_pospull_rcsum has to be done in case that
+@@ -2144,7 +2153,7 @@ static int __bpf_redirect_common(struct sk_buff *skb, struct net_device *dev,
+ u32 flags)
+ {
+ /* Verify that a link layer header is carried */
+- if (unlikely(skb->mac_header >= skb->network_header)) {
++ if (unlikely(skb->mac_header >= skb->network_header || skb->len == 0)) {
+ kfree_skb(skb);
+ return -ERANGE;
+ }
+diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
+index c8d137ef5980e..b71ccaec09914 100644
+--- a/net/core/gen_stats.c
++++ b/net/core/gen_stats.c
+@@ -135,10 +135,10 @@ static void gnet_stats_add_basic_cpu(struct gnet_stats_basic_sync *bstats,
+ u64 bytes, packets;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&bcpu->syncp);
++ start = u64_stats_fetch_begin(&bcpu->syncp);
+ bytes = u64_stats_read(&bcpu->bytes);
+ packets = u64_stats_read(&bcpu->packets);
+- } while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
++ } while (u64_stats_fetch_retry(&bcpu->syncp, start));
+
+ t_bytes += bytes;
+ t_packets += packets;
+@@ -162,10 +162,10 @@ void gnet_stats_add_basic(struct gnet_stats_basic_sync *bstats,
+ }
+ do {
+ if (running)
+- start = u64_stats_fetch_begin_irq(&b->syncp);
++ start = u64_stats_fetch_begin(&b->syncp);
+ bytes = u64_stats_read(&b->bytes);
+ packets = u64_stats_read(&b->packets);
+- } while (running && u64_stats_fetch_retry_irq(&b->syncp, start));
++ } while (running && u64_stats_fetch_retry(&b->syncp, start));
+
+ _bstats_update(bstats, bytes, packets);
+ }
+@@ -187,10 +187,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets,
+ u64 bytes, packets;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&bcpu->syncp);
++ start = u64_stats_fetch_begin(&bcpu->syncp);
+ bytes = u64_stats_read(&bcpu->bytes);
+ packets = u64_stats_read(&bcpu->packets);
+- } while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
++ } while (u64_stats_fetch_retry(&bcpu->syncp, start));
+
+ t_bytes += bytes;
+ t_packets += packets;
+@@ -201,10 +201,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets,
+ }
+ do {
+ if (running)
+- start = u64_stats_fetch_begin_irq(&b->syncp);
++ start = u64_stats_fetch_begin(&b->syncp);
+ *ret_bytes = u64_stats_read(&b->bytes);
+ *ret_packets = u64_stats_read(&b->packets);
+- } while (running && u64_stats_fetch_retry_irq(&b->syncp, start));
++ } while (running && u64_stats_fetch_retry(&b->syncp, start));
+ }
+
+ static int
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index d9c19ae05fe67..9460998ac6d1e 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2313,6 +2313,9 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
+ insp = list;
+ } else {
+ /* Eaten partially. */
++ if (skb_is_gso(skb) && !list->head_frag &&
++ skb_headlen(list))
++ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+
+ if (skb_shared(list)) {
+ /* Sucks! We need to fork list. :-( */
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index e6b9ced3eda82..53d0251788aa2 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -886,13 +886,16 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock,
+ ret = sk_psock_map_verd(ret, msg->sk_redir);
+ psock->apply_bytes = msg->apply_bytes;
+ if (ret == __SK_REDIRECT) {
+- if (psock->sk_redir)
++ if (psock->sk_redir) {
+ sock_put(psock->sk_redir);
+- psock->sk_redir = msg->sk_redir;
+- if (!psock->sk_redir) {
++ psock->sk_redir = NULL;
++ }
++ if (!msg->sk_redir) {
+ ret = __SK_DROP;
+ goto out;
+ }
++ psock->redir_ingress = sk_msg_to_ingress(msg);
++ psock->sk_redir = msg->sk_redir;
+ sock_hold(psock->sk_redir);
+ }
+ out:
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 788c1372663cb..f0eaa5d406b3f 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1400,7 +1400,7 @@ set_sndbuf:
+ break;
+ }
+ case SO_INCOMING_CPU:
+- WRITE_ONCE(sk->sk_incoming_cpu, val);
++ reuseport_update_incoming_cpu(sk, val);
+ break;
+
+ case SO_CNX_ADVICE:
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 632df0c525625..bfc3001032129 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -349,11 +349,13 @@ static void sock_map_free(struct bpf_map *map)
+
+ sk = xchg(psk, NULL);
+ if (sk) {
++ sock_hold(sk);
+ lock_sock(sk);
+ rcu_read_lock();
+ sock_map_unref(sk, psk);
+ rcu_read_unlock();
+ release_sock(sk);
++ sock_put(sk);
+ }
+ }
+
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index fb90e1e00773b..5a165286e4d8e 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -37,6 +37,70 @@ void reuseport_has_conns_set(struct sock *sk)
+ }
+ EXPORT_SYMBOL(reuseport_has_conns_set);
+
++static void __reuseport_get_incoming_cpu(struct sock_reuseport *reuse)
++{
++ /* Paired with READ_ONCE() in reuseport_select_sock_by_hash(). */
++ WRITE_ONCE(reuse->incoming_cpu, reuse->incoming_cpu + 1);
++}
++
++static void __reuseport_put_incoming_cpu(struct sock_reuseport *reuse)
++{
++ /* Paired with READ_ONCE() in reuseport_select_sock_by_hash(). */
++ WRITE_ONCE(reuse->incoming_cpu, reuse->incoming_cpu - 1);
++}
++
++static void reuseport_get_incoming_cpu(struct sock *sk, struct sock_reuseport *reuse)
++{
++ if (sk->sk_incoming_cpu >= 0)
++ __reuseport_get_incoming_cpu(reuse);
++}
++
++static void reuseport_put_incoming_cpu(struct sock *sk, struct sock_reuseport *reuse)
++{
++ if (sk->sk_incoming_cpu >= 0)
++ __reuseport_put_incoming_cpu(reuse);
++}
++
++void reuseport_update_incoming_cpu(struct sock *sk, int val)
++{
++ struct sock_reuseport *reuse;
++ int old_sk_incoming_cpu;
++
++ if (unlikely(!rcu_access_pointer(sk->sk_reuseport_cb))) {
++ /* Paired with REAE_ONCE() in sk_incoming_cpu_update()
++ * and compute_score().
++ */
++ WRITE_ONCE(sk->sk_incoming_cpu, val);
++ return;
++ }
++
++ spin_lock_bh(&reuseport_lock);
++
++ /* This must be done under reuseport_lock to avoid a race with
++ * reuseport_grow(), which accesses sk->sk_incoming_cpu without
++ * lock_sock() when detaching a shutdown()ed sk.
++ *
++ * Paired with READ_ONCE() in reuseport_select_sock_by_hash().
++ */
++ old_sk_incoming_cpu = sk->sk_incoming_cpu;
++ WRITE_ONCE(sk->sk_incoming_cpu, val);
++
++ reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
++ lockdep_is_held(&reuseport_lock));
++
++ /* reuseport_grow() has detached a closed sk. */
++ if (!reuse)
++ goto out;
++
++ if (old_sk_incoming_cpu < 0 && val >= 0)
++ __reuseport_get_incoming_cpu(reuse);
++ else if (old_sk_incoming_cpu >= 0 && val < 0)
++ __reuseport_put_incoming_cpu(reuse);
++
++out:
++ spin_unlock_bh(&reuseport_lock);
++}
++
+ static int reuseport_sock_index(struct sock *sk,
+ const struct sock_reuseport *reuse,
+ bool closed)
+@@ -64,6 +128,7 @@ static void __reuseport_add_sock(struct sock *sk,
+ /* paired with smp_rmb() in reuseport_(select|migrate)_sock() */
+ smp_wmb();
+ reuse->num_socks++;
++ reuseport_get_incoming_cpu(sk, reuse);
+ }
+
+ static bool __reuseport_detach_sock(struct sock *sk,
+@@ -76,6 +141,7 @@ static bool __reuseport_detach_sock(struct sock *sk,
+
+ reuse->socks[i] = reuse->socks[reuse->num_socks - 1];
+ reuse->num_socks--;
++ reuseport_put_incoming_cpu(sk, reuse);
+
+ return true;
+ }
+@@ -86,6 +152,7 @@ static void __reuseport_add_closed_sock(struct sock *sk,
+ reuse->socks[reuse->max_socks - reuse->num_closed_socks - 1] = sk;
+ /* paired with READ_ONCE() in inet_csk_bind_conflict() */
+ WRITE_ONCE(reuse->num_closed_socks, reuse->num_closed_socks + 1);
++ reuseport_get_incoming_cpu(sk, reuse);
+ }
+
+ static bool __reuseport_detach_closed_sock(struct sock *sk,
+@@ -99,6 +166,7 @@ static bool __reuseport_detach_closed_sock(struct sock *sk,
+ reuse->socks[i] = reuse->socks[reuse->max_socks - reuse->num_closed_socks];
+ /* paired with READ_ONCE() in inet_csk_bind_conflict() */
+ WRITE_ONCE(reuse->num_closed_socks, reuse->num_closed_socks - 1);
++ reuseport_put_incoming_cpu(sk, reuse);
+
+ return true;
+ }
+@@ -166,6 +234,7 @@ int reuseport_alloc(struct sock *sk, bool bind_inany)
+ reuse->bind_inany = bind_inany;
+ reuse->socks[0] = sk;
+ reuse->num_socks = 1;
++ reuseport_get_incoming_cpu(sk, reuse);
+ rcu_assign_pointer(sk->sk_reuseport_cb, reuse);
+
+ out:
+@@ -209,6 +278,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
+ more_reuse->reuseport_id = reuse->reuseport_id;
+ more_reuse->bind_inany = reuse->bind_inany;
+ more_reuse->has_conns = reuse->has_conns;
++ more_reuse->incoming_cpu = reuse->incoming_cpu;
+
+ memcpy(more_reuse->socks, reuse->socks,
+ reuse->num_socks * sizeof(struct sock *));
+@@ -458,18 +528,32 @@ static struct sock *run_bpf_filter(struct sock_reuseport *reuse, u16 socks,
+ static struct sock *reuseport_select_sock_by_hash(struct sock_reuseport *reuse,
+ u32 hash, u16 num_socks)
+ {
++ struct sock *first_valid_sk = NULL;
+ int i, j;
+
+ i = j = reciprocal_scale(hash, num_socks);
+- while (reuse->socks[i]->sk_state == TCP_ESTABLISHED) {
++ do {
++ struct sock *sk = reuse->socks[i];
++
++ if (sk->sk_state != TCP_ESTABLISHED) {
++ /* Paired with WRITE_ONCE() in __reuseport_(get|put)_incoming_cpu(). */
++ if (!READ_ONCE(reuse->incoming_cpu))
++ return sk;
++
++ /* Paired with WRITE_ONCE() in reuseport_update_incoming_cpu(). */
++ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
++ return sk;
++
++ if (!first_valid_sk)
++ first_valid_sk = sk;
++ }
++
+ i++;
+ if (i >= num_socks)
+ i = 0;
+- if (i == j)
+- return NULL;
+- }
++ } while (i != j);
+
+- return reuse->socks[i];
++ return first_valid_sk;
+ }
+
+ /**
+diff --git a/net/core/stream.c b/net/core/stream.c
+index 1105057ce00a5..2d03810841cbc 100644
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -196,6 +196,12 @@ void sk_stream_kill_queues(struct sock *sk)
+ /* First the read buffer. */
+ __skb_queue_purge(&sk->sk_receive_queue);
+
++ /* Next, the error queue.
++ * We need to use queue lock, because other threads might
++ * add packets to the queue without socket lock being held.
++ */
++ skb_queue_purge(&sk->sk_error_queue);
++
+ /* Next, the write queue. */
+ WARN_ON_ONCE(!skb_queue_empty(&sk->sk_write_queue));
+
+diff --git a/net/dsa/slave.c b/net/dsa/slave.c
+index 1291c2431d440..dcc550b871623 100644
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -934,12 +934,12 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev,
+
+ s = per_cpu_ptr(dev->tstats, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&s->syncp);
++ start = u64_stats_fetch_begin(&s->syncp);
+ tx_packets = u64_stats_read(&s->tx_packets);
+ tx_bytes = u64_stats_read(&s->tx_bytes);
+ rx_packets = u64_stats_read(&s->rx_packets);
+ rx_bytes = u64_stats_read(&s->rx_bytes);
+- } while (u64_stats_fetch_retry_irq(&s->syncp, start));
++ } while (u64_stats_fetch_retry(&s->syncp, start));
+ data[0] += tx_packets;
+ data[1] += tx_bytes;
+ data[2] += rx_packets;
+diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c
+index 01a427800797c..6de53f5b40a7a 100644
+--- a/net/dsa/tag_8021q.c
++++ b/net/dsa/tag_8021q.c
+@@ -400,6 +400,7 @@ static void dsa_tag_8021q_teardown(struct dsa_switch *ds)
+ int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto)
+ {
+ struct dsa_8021q_context *ctx;
++ int err;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+@@ -412,7 +413,15 @@ int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto)
+
+ ds->tag_8021q_ctx = ctx;
+
+- return dsa_tag_8021q_setup(ds);
++ err = dsa_tag_8021q_setup(ds);
++ if (err)
++ goto err_free;
++
++ return 0;
++
++err_free:
++ kfree(ctx);
++ return err;
+ }
+ EXPORT_SYMBOL_GPL(dsa_tag_8021q_register);
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 6a7308de192d9..6b59e7a1c9063 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2007,7 +2007,8 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
+ } else {
+ /* Driver expects to be called at twice the frequency in rc */
+ int n = rc * 2, interval = HZ / n;
+- u64 count = n * id.data, i = 0;
++ u64 count = mul_u32_u32(n, id.data);
++ u64 i = 0;
+
+ do {
+ rtnl_lock();
+diff --git a/net/hsr/hsr_debugfs.c b/net/hsr/hsr_debugfs.c
+index de476a4176314..1a195efc79cd1 100644
+--- a/net/hsr/hsr_debugfs.c
++++ b/net/hsr/hsr_debugfs.c
+@@ -9,7 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/errno.h>
+ #include <linux/debugfs.h>
+-#include <linux/jhash.h>
+ #include "hsr_main.h"
+ #include "hsr_framereg.h"
+
+@@ -21,7 +20,6 @@ hsr_node_table_show(struct seq_file *sfp, void *data)
+ {
+ struct hsr_priv *priv = (struct hsr_priv *)sfp->private;
+ struct hsr_node *node;
+- int i;
+
+ seq_printf(sfp, "Node Table entries for (%s) device\n",
+ (priv->prot_version == PRP_V1 ? "PRP" : "HSR"));
+@@ -33,28 +31,22 @@ hsr_node_table_show(struct seq_file *sfp, void *data)
+ seq_puts(sfp, "DAN-H\n");
+
+ rcu_read_lock();
+-
+- for (i = 0 ; i < priv->hash_buckets; i++) {
+- hlist_for_each_entry_rcu(node, &priv->node_db[i], mac_list) {
+- /* skip self node */
+- if (hsr_addr_is_self(priv, node->macaddress_A))
+- continue;
+- seq_printf(sfp, "%pM ", &node->macaddress_A[0]);
+- seq_printf(sfp, "%pM ", &node->macaddress_B[0]);
+- seq_printf(sfp, "%10lx, ",
+- node->time_in[HSR_PT_SLAVE_A]);
+- seq_printf(sfp, "%10lx, ",
+- node->time_in[HSR_PT_SLAVE_B]);
+- seq_printf(sfp, "%14x, ", node->addr_B_port);
+-
+- if (priv->prot_version == PRP_V1)
+- seq_printf(sfp, "%5x, %5x, %5x\n",
+- node->san_a, node->san_b,
+- (node->san_a == 0 &&
+- node->san_b == 0));
+- else
+- seq_printf(sfp, "%5x\n", 1);
+- }
++ list_for_each_entry_rcu(node, &priv->node_db, mac_list) {
++ /* skip self node */
++ if (hsr_addr_is_self(priv, node->macaddress_A))
++ continue;
++ seq_printf(sfp, "%pM ", &node->macaddress_A[0]);
++ seq_printf(sfp, "%pM ", &node->macaddress_B[0]);
++ seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_A]);
++ seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_B]);
++ seq_printf(sfp, "%14x, ", node->addr_B_port);
++
++ if (priv->prot_version == PRP_V1)
++ seq_printf(sfp, "%5x, %5x, %5x\n",
++ node->san_a, node->san_b,
++ (node->san_a == 0 && node->san_b == 0));
++ else
++ seq_printf(sfp, "%5x\n", 1);
+ }
+ rcu_read_unlock();
+ return 0;
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 6ffef47e9be55..b1e86a7265b32 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -219,7 +219,9 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+ skb->dev = master->dev;
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
++ spin_lock_bh(&hsr->seqnr_lock);
+ hsr_forward_skb(skb, master);
++ spin_unlock_bh(&hsr->seqnr_lock);
+ } else {
+ dev_core_stats_tx_dropped_inc(dev);
+ dev_kfree_skb_any(skb);
+@@ -278,7 +280,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ __u8 type = HSR_TLV_LIFE_CHECK;
+ struct hsr_sup_payload *hsr_sp;
+ struct hsr_sup_tag *hsr_stag;
+- unsigned long irqflags;
+ struct sk_buff *skb;
+
+ *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);
+@@ -299,7 +300,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+
+ /* From HSRv1 on we have separate supervision sequence numbers. */
+- spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++ spin_lock_bh(&hsr->seqnr_lock);
+ if (hsr->prot_version > 0) {
+ hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+ hsr->sup_sequence_nr++;
+@@ -307,7 +308,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ hsr_stag->sequence_nr = htons(hsr->sequence_nr);
+ hsr->sequence_nr++;
+ }
+- spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+
+ hsr_stag->tlv.HSR_TLV_type = type;
+ /* TODO: Why 12 in HSRv0? */
+@@ -318,11 +318,13 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+ ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+
+- if (skb_put_padto(skb, ETH_ZLEN))
++ if (skb_put_padto(skb, ETH_ZLEN)) {
++ spin_unlock_bh(&hsr->seqnr_lock);
+ return;
++ }
+
+ hsr_forward_skb(skb, master);
+-
++ spin_unlock_bh(&hsr->seqnr_lock);
+ return;
+ }
+
+@@ -332,7 +334,6 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ struct hsr_priv *hsr = master->hsr;
+ struct hsr_sup_payload *hsr_sp;
+ struct hsr_sup_tag *hsr_stag;
+- unsigned long irqflags;
+ struct sk_buff *skb;
+
+ skb = hsr_init_skb(master);
+@@ -347,7 +348,7 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ set_hsr_stag_HSR_ver(hsr_stag, (hsr->prot_version ? 1 : 0));
+
+ /* From HSRv1 on we have separate supervision sequence numbers. */
+- spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++ spin_lock_bh(&hsr->seqnr_lock);
+ hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+ hsr->sup_sequence_nr++;
+ hsr_stag->tlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
+@@ -358,13 +359,12 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+
+ if (skb_put_padto(skb, ETH_ZLEN)) {
+- spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
++ spin_unlock_bh(&hsr->seqnr_lock);
+ return;
+ }
+
+- spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+-
+ hsr_forward_skb(skb, master);
++ spin_unlock_bh(&hsr->seqnr_lock);
+ }
+
+ /* Announce (supervision frame) timer function
+@@ -444,7 +444,7 @@ void hsr_dev_setup(struct net_device *dev)
+ dev->header_ops = &hsr_header_ops;
+ dev->netdev_ops = &hsr_device_ops;
+ SET_NETDEV_DEVTYPE(dev, &hsr_type);
+- dev->priv_flags |= IFF_NO_QUEUE;
++ dev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
+
+ dev->needs_free_netdev = true;
+
+@@ -485,16 +485,12 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
+ {
+ bool unregister = false;
+ struct hsr_priv *hsr;
+- int res, i;
++ int res;
+
+ hsr = netdev_priv(hsr_dev);
+ INIT_LIST_HEAD(&hsr->ports);
+- INIT_HLIST_HEAD(&hsr->self_node_db);
+- hsr->hash_buckets = HSR_HSIZE;
+- get_random_bytes(&hsr->hash_seed, sizeof(hsr->hash_seed));
+- for (i = 0; i < hsr->hash_buckets; i++)
+- INIT_HLIST_HEAD(&hsr->node_db[i]);
+-
++ INIT_LIST_HEAD(&hsr->node_db);
++ INIT_LIST_HEAD(&hsr->self_node_db);
+ spin_lock_init(&hsr->list_lock);
+
+ eth_hw_addr_set(hsr_dev, slave[0]->dev_addr);
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 56bb27d67a2ee..629daacc96071 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -500,7 +500,6 @@ static void handle_std_frame(struct sk_buff *skb,
+ {
+ struct hsr_port *port = frame->port_rcv;
+ struct hsr_priv *hsr = port->hsr;
+- unsigned long irqflags;
+
+ frame->skb_hsr = NULL;
+ frame->skb_prp = NULL;
+@@ -510,10 +509,9 @@ static void handle_std_frame(struct sk_buff *skb,
+ frame->is_from_san = true;
+ } else {
+ /* Sequence nr for the master node */
+- spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
++ lockdep_assert_held(&hsr->seqnr_lock);
+ frame->sequence_nr = hsr->sequence_nr;
+ hsr->sequence_nr++;
+- spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
+ }
+ }
+
+@@ -571,23 +569,20 @@ static int fill_frame_info(struct hsr_frame_info *frame,
+ struct ethhdr *ethhdr;
+ __be16 proto;
+ int ret;
+- u32 hash;
+
+ /* Check if skb contains ethhdr */
+ if (skb->mac_len < sizeof(struct ethhdr))
+ return -EINVAL;
+
+ memset(frame, 0, sizeof(*frame));
+-
+- ethhdr = (struct ethhdr *)skb_mac_header(skb);
+- hash = hsr_mac_hash(port->hsr, ethhdr->h_source);
+ frame->is_supervision = is_supervision_frame(port->hsr, skb);
+- frame->node_src = hsr_get_node(port, &hsr->node_db[hash], skb,
++ frame->node_src = hsr_get_node(port, &hsr->node_db, skb,
+ frame->is_supervision,
+ port->type);
+ if (!frame->node_src)
+ return -1; /* Unknown node and !is_supervision, or no mem */
+
++ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ frame->is_vlan = false;
+ proto = ethhdr->h_proto;
+
+@@ -617,11 +612,13 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+ {
+ struct hsr_frame_info frame;
+
++ rcu_read_lock();
+ if (fill_frame_info(&frame, skb, port) < 0)
+ goto out_drop;
+
+ hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
+ hsr_forward_do(&frame);
++ rcu_read_unlock();
+ /* Gets called for ingress frames as well as egress from master port.
+ * So check and increment stats for master port only here.
+ */
+@@ -636,6 +633,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+ return;
+
+ out_drop:
++ rcu_read_unlock();
+ port->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
+diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
+index 584e217887997..39a6088080e93 100644
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -15,37 +15,10 @@
+ #include <linux/etherdevice.h>
+ #include <linux/slab.h>
+ #include <linux/rculist.h>
+-#include <linux/jhash.h>
+ #include "hsr_main.h"
+ #include "hsr_framereg.h"
+ #include "hsr_netlink.h"
+
+-#ifdef CONFIG_LOCKDEP
+-int lockdep_hsr_is_held(spinlock_t *lock)
+-{
+- return lockdep_is_held(lock);
+-}
+-#endif
+-
+-u32 hsr_mac_hash(struct hsr_priv *hsr, const unsigned char *addr)
+-{
+- u32 hash = jhash(addr, ETH_ALEN, hsr->hash_seed);
+-
+- return reciprocal_scale(hash, hsr->hash_buckets);
+-}
+-
+-struct hsr_node *hsr_node_get_first(struct hlist_head *head, spinlock_t *lock)
+-{
+- struct hlist_node *first;
+-
+- first = rcu_dereference_bh_check(hlist_first_rcu(head),
+- lockdep_hsr_is_held(lock));
+- if (first)
+- return hlist_entry(first, struct hsr_node, mac_list);
+-
+- return NULL;
+-}
+-
+ /* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b,
+ * false otherwise.
+ */
+@@ -67,7 +40,8 @@ bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
+ {
+ struct hsr_node *node;
+
+- node = hsr_node_get_first(&hsr->self_node_db, &hsr->list_lock);
++ node = list_first_or_null_rcu(&hsr->self_node_db, struct hsr_node,
++ mac_list);
+ if (!node) {
+ WARN_ONCE(1, "HSR: No self node\n");
+ return false;
+@@ -83,12 +57,12 @@ bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
+
+ /* Search for mac entry. Caller must hold rcu read lock.
+ */
+-static struct hsr_node *find_node_by_addr_A(struct hlist_head *node_db,
++static struct hsr_node *find_node_by_addr_A(struct list_head *node_db,
+ const unsigned char addr[ETH_ALEN])
+ {
+ struct hsr_node *node;
+
+- hlist_for_each_entry_rcu(node, node_db, mac_list) {
++ list_for_each_entry_rcu(node, node_db, mac_list) {
+ if (ether_addr_equal(node->macaddress_A, addr))
+ return node;
+ }
+@@ -103,7 +77,7 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+ const unsigned char addr_a[ETH_ALEN],
+ const unsigned char addr_b[ETH_ALEN])
+ {
+- struct hlist_head *self_node_db = &hsr->self_node_db;
++ struct list_head *self_node_db = &hsr->self_node_db;
+ struct hsr_node *node, *oldnode;
+
+ node = kmalloc(sizeof(*node), GFP_KERNEL);
+@@ -114,13 +88,14 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+ ether_addr_copy(node->macaddress_B, addr_b);
+
+ spin_lock_bh(&hsr->list_lock);
+- oldnode = hsr_node_get_first(self_node_db, &hsr->list_lock);
++ oldnode = list_first_or_null_rcu(self_node_db,
++ struct hsr_node, mac_list);
+ if (oldnode) {
+- hlist_replace_rcu(&oldnode->mac_list, &node->mac_list);
++ list_replace_rcu(&oldnode->mac_list, &node->mac_list);
+ spin_unlock_bh(&hsr->list_lock);
+ kfree_rcu(oldnode, rcu_head);
+ } else {
+- hlist_add_tail_rcu(&node->mac_list, self_node_db);
++ list_add_tail_rcu(&node->mac_list, self_node_db);
+ spin_unlock_bh(&hsr->list_lock);
+ }
+
+@@ -129,25 +104,25 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+
+ void hsr_del_self_node(struct hsr_priv *hsr)
+ {
+- struct hlist_head *self_node_db = &hsr->self_node_db;
++ struct list_head *self_node_db = &hsr->self_node_db;
+ struct hsr_node *node;
+
+ spin_lock_bh(&hsr->list_lock);
+- node = hsr_node_get_first(self_node_db, &hsr->list_lock);
++ node = list_first_or_null_rcu(self_node_db, struct hsr_node, mac_list);
+ if (node) {
+- hlist_del_rcu(&node->mac_list);
++ list_del_rcu(&node->mac_list);
+ kfree_rcu(node, rcu_head);
+ }
+ spin_unlock_bh(&hsr->list_lock);
+ }
+
+-void hsr_del_nodes(struct hlist_head *node_db)
++void hsr_del_nodes(struct list_head *node_db)
+ {
+ struct hsr_node *node;
+- struct hlist_node *tmp;
++ struct hsr_node *tmp;
+
+- hlist_for_each_entry_safe(node, tmp, node_db, mac_list)
+- kfree_rcu(node, rcu_head);
++ list_for_each_entry_safe(node, tmp, node_db, mac_list)
++ kfree(node);
+ }
+
+ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+@@ -168,7 +143,7 @@ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+ * originating from the newly added node.
+ */
+ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+- struct hlist_head *node_db,
++ struct list_head *node_db,
+ unsigned char addr[],
+ u16 seq_out, bool san,
+ enum hsr_port_type rx_port)
+@@ -182,6 +157,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+ return NULL;
+
+ ether_addr_copy(new_node->macaddress_A, addr);
++ spin_lock_init(&new_node->seq_out_lock);
+
+ /* We are only interested in time diffs here, so use current jiffies
+ * as initialization. (0 could trigger an spurious ring error warning).
+@@ -198,14 +174,14 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+ hsr->proto_ops->handle_san_frame(san, rx_port, new_node);
+
+ spin_lock_bh(&hsr->list_lock);
+- hlist_for_each_entry_rcu(node, node_db, mac_list,
+- lockdep_hsr_is_held(&hsr->list_lock)) {
++ list_for_each_entry_rcu(node, node_db, mac_list,
++ lockdep_is_held(&hsr->list_lock)) {
+ if (ether_addr_equal(node->macaddress_A, addr))
+ goto out;
+ if (ether_addr_equal(node->macaddress_B, addr))
+ goto out;
+ }
+- hlist_add_tail_rcu(&new_node->mac_list, node_db);
++ list_add_tail_rcu(&new_node->mac_list, node_db);
+ spin_unlock_bh(&hsr->list_lock);
+ return new_node;
+ out:
+@@ -225,7 +201,7 @@ void prp_update_san_info(struct hsr_node *node, bool is_sup)
+
+ /* Get the hsr_node from which 'skb' was sent.
+ */
+-struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
++struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
+ struct sk_buff *skb, bool is_sup,
+ enum hsr_port_type rx_port)
+ {
+@@ -241,7 +217,7 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+- hlist_for_each_entry_rcu(node, node_db, mac_list) {
++ list_for_each_entry_rcu(node, node_db, mac_list) {
+ if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) {
+ if (hsr->proto_ops->update_san_info)
+ hsr->proto_ops->update_san_info(node, is_sup);
+@@ -291,12 +267,11 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ struct hsr_sup_tlv *hsr_sup_tlv;
+ struct hsr_node *node_real;
+ struct sk_buff *skb = NULL;
+- struct hlist_head *node_db;
++ struct list_head *node_db;
+ struct ethhdr *ethhdr;
+ int i;
+ unsigned int pull_size = 0;
+ unsigned int total_pull_size = 0;
+- u32 hash;
+
+ /* Here either frame->skb_hsr or frame->skb_prp should be
+ * valid as supervision frame always will have protocol
+@@ -334,13 +309,11 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ hsr_sp = (struct hsr_sup_payload *)skb->data;
+
+ /* Merge node_curr (registered on macaddress_B) into node_real */
+- node_db = port_rcv->hsr->node_db;
+- hash = hsr_mac_hash(hsr, hsr_sp->macaddress_A);
+- node_real = find_node_by_addr_A(&node_db[hash], hsr_sp->macaddress_A);
++ node_db = &port_rcv->hsr->node_db;
++ node_real = find_node_by_addr_A(node_db, hsr_sp->macaddress_A);
+ if (!node_real)
+ /* No frame received from AddrA of this node yet */
+- node_real = hsr_add_node(hsr, &node_db[hash],
+- hsr_sp->macaddress_A,
++ node_real = hsr_add_node(hsr, node_db, hsr_sp->macaddress_A,
+ HSR_SEQNR_START - 1, true,
+ port_rcv->type);
+ if (!node_real)
+@@ -374,14 +347,14 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ hsr_sp = (struct hsr_sup_payload *)skb->data;
+
+ /* Check if redbox mac and node mac are equal. */
+- if (!ether_addr_equal(node_real->macaddress_A,
+- hsr_sp->macaddress_A)) {
++ if (!ether_addr_equal(node_real->macaddress_A, hsr_sp->macaddress_A)) {
+ /* This is a redbox supervision frame for a VDAN! */
+ goto done;
+ }
+ }
+
+ ether_addr_copy(node_real->macaddress_B, ethhdr->h_source);
++ spin_lock_bh(&node_real->seq_out_lock);
+ for (i = 0; i < HSR_PT_PORTS; i++) {
+ if (!node_curr->time_in_stale[i] &&
+ time_after(node_curr->time_in[i], node_real->time_in[i])) {
+@@ -392,12 +365,16 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i]))
+ node_real->seq_out[i] = node_curr->seq_out[i];
+ }
++ spin_unlock_bh(&node_real->seq_out_lock);
+ node_real->addr_B_port = port_rcv->type;
+
+ spin_lock_bh(&hsr->list_lock);
+- hlist_del_rcu(&node_curr->mac_list);
++ if (!node_curr->removed) {
++ list_del_rcu(&node_curr->mac_list);
++ node_curr->removed = true;
++ kfree_rcu(node_curr, rcu_head);
++ }
+ spin_unlock_bh(&hsr->list_lock);
+- kfree_rcu(node_curr, rcu_head);
+
+ done:
+ /* Push back here */
+@@ -433,7 +410,6 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
+ struct hsr_port *port)
+ {
+ struct hsr_node *node_dst;
+- u32 hash;
+
+ if (!skb_mac_header_was_set(skb)) {
+ WARN_ONCE(1, "%s: Mac header not set\n", __func__);
+@@ -443,8 +419,7 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
+ if (!is_unicast_ether_addr(eth_hdr(skb)->h_dest))
+ return;
+
+- hash = hsr_mac_hash(port->hsr, eth_hdr(skb)->h_dest);
+- node_dst = find_node_by_addr_A(&port->hsr->node_db[hash],
++ node_dst = find_node_by_addr_A(&port->hsr->node_db,
+ eth_hdr(skb)->h_dest);
+ if (!node_dst) {
+ if (net_ratelimit())
+@@ -484,13 +459,17 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
+ int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
+ u16 sequence_nr)
+ {
++ spin_lock_bh(&node->seq_out_lock);
+ if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]) &&
+ time_is_after_jiffies(node->time_out[port->type] +
+- msecs_to_jiffies(HSR_ENTRY_FORGET_TIME)))
++ msecs_to_jiffies(HSR_ENTRY_FORGET_TIME))) {
++ spin_unlock_bh(&node->seq_out_lock);
+ return 1;
++ }
+
+ node->time_out[port->type] = jiffies;
+ node->seq_out[port->type] = sequence_nr;
++ spin_unlock_bh(&node->seq_out_lock);
+ return 0;
+ }
+
+@@ -520,71 +499,60 @@ static struct hsr_port *get_late_port(struct hsr_priv *hsr,
+ void hsr_prune_nodes(struct timer_list *t)
+ {
+ struct hsr_priv *hsr = from_timer(hsr, t, prune_timer);
+- struct hlist_node *tmp;
+ struct hsr_node *node;
++ struct hsr_node *tmp;
+ struct hsr_port *port;
+ unsigned long timestamp;
+ unsigned long time_a, time_b;
+- int i;
+
+ spin_lock_bh(&hsr->list_lock);
++ list_for_each_entry_safe(node, tmp, &hsr->node_db, mac_list) {
++ /* Don't prune own node. Neither time_in[HSR_PT_SLAVE_A]
++ * nor time_in[HSR_PT_SLAVE_B], will ever be updated for
++ * the master port. Thus the master node will be repeatedly
++ * pruned leading to packet loss.
++ */
++ if (hsr_addr_is_self(hsr, node->macaddress_A))
++ continue;
++
++ /* Shorthand */
++ time_a = node->time_in[HSR_PT_SLAVE_A];
++ time_b = node->time_in[HSR_PT_SLAVE_B];
++
++ /* Check for timestamps old enough to risk wrap-around */
++ if (time_after(jiffies, time_a + MAX_JIFFY_OFFSET / 2))
++ node->time_in_stale[HSR_PT_SLAVE_A] = true;
++ if (time_after(jiffies, time_b + MAX_JIFFY_OFFSET / 2))
++ node->time_in_stale[HSR_PT_SLAVE_B] = true;
++
++ /* Get age of newest frame from node.
++ * At least one time_in is OK here; nodes get pruned long
++ * before both time_ins can get stale
++ */
++ timestamp = time_a;
++ if (node->time_in_stale[HSR_PT_SLAVE_A] ||
++ (!node->time_in_stale[HSR_PT_SLAVE_B] &&
++ time_after(time_b, time_a)))
++ timestamp = time_b;
++
++ /* Warn of ring error only as long as we get frames at all */
++ if (time_is_after_jiffies(timestamp +
++ msecs_to_jiffies(1.5 * MAX_SLAVE_DIFF))) {
++ rcu_read_lock();
++ port = get_late_port(hsr, node);
++ if (port)
++ hsr_nl_ringerror(hsr, node->macaddress_A, port);
++ rcu_read_unlock();
++ }
+
+- for (i = 0; i < hsr->hash_buckets; i++) {
+- hlist_for_each_entry_safe(node, tmp, &hsr->node_db[i],
+- mac_list) {
+- /* Don't prune own node.
+- * Neither time_in[HSR_PT_SLAVE_A]
+- * nor time_in[HSR_PT_SLAVE_B], will ever be updated
+- * for the master port. Thus the master node will be
+- * repeatedly pruned leading to packet loss.
+- */
+- if (hsr_addr_is_self(hsr, node->macaddress_A))
+- continue;
+-
+- /* Shorthand */
+- time_a = node->time_in[HSR_PT_SLAVE_A];
+- time_b = node->time_in[HSR_PT_SLAVE_B];
+-
+- /* Check for timestamps old enough to
+- * risk wrap-around
+- */
+- if (time_after(jiffies, time_a + MAX_JIFFY_OFFSET / 2))
+- node->time_in_stale[HSR_PT_SLAVE_A] = true;
+- if (time_after(jiffies, time_b + MAX_JIFFY_OFFSET / 2))
+- node->time_in_stale[HSR_PT_SLAVE_B] = true;
+-
+- /* Get age of newest frame from node.
+- * At least one time_in is OK here; nodes get pruned
+- * long before both time_ins can get stale
+- */
+- timestamp = time_a;
+- if (node->time_in_stale[HSR_PT_SLAVE_A] ||
+- (!node->time_in_stale[HSR_PT_SLAVE_B] &&
+- time_after(time_b, time_a)))
+- timestamp = time_b;
+-
+- /* Warn of ring error only as long as we get
+- * frames at all
+- */
+- if (time_is_after_jiffies(timestamp +
+- msecs_to_jiffies(1.5 * MAX_SLAVE_DIFF))) {
+- rcu_read_lock();
+- port = get_late_port(hsr, node);
+- if (port)
+- hsr_nl_ringerror(hsr,
+- node->macaddress_A,
+- port);
+- rcu_read_unlock();
+- }
+-
+- /* Prune old entries */
+- if (time_is_before_jiffies(timestamp +
+- msecs_to_jiffies(HSR_NODE_FORGET_TIME))) {
+- hsr_nl_nodedown(hsr, node->macaddress_A);
+- hlist_del_rcu(&node->mac_list);
+- /* Note that we need to free this
+- * entry later:
+- */
++ /* Prune old entries */
++ if (time_is_before_jiffies(timestamp +
++ msecs_to_jiffies(HSR_NODE_FORGET_TIME))) {
++ hsr_nl_nodedown(hsr, node->macaddress_A);
++ if (!node->removed) {
++ list_del_rcu(&node->mac_list);
++ node->removed = true;
++ /* Note that we need to free this entry later: */
+ kfree_rcu(node, rcu_head);
+ }
+ }
+@@ -600,20 +568,17 @@ void *hsr_get_next_node(struct hsr_priv *hsr, void *_pos,
+ unsigned char addr[ETH_ALEN])
+ {
+ struct hsr_node *node;
+- u32 hash;
+-
+- hash = hsr_mac_hash(hsr, addr);
+
+ if (!_pos) {
+- node = hsr_node_get_first(&hsr->node_db[hash],
+- &hsr->list_lock);
++ node = list_first_or_null_rcu(&hsr->node_db,
++ struct hsr_node, mac_list);
+ if (node)
+ ether_addr_copy(addr, node->macaddress_A);
+ return node;
+ }
+
+ node = _pos;
+- hlist_for_each_entry_continue_rcu(node, mac_list) {
++ list_for_each_entry_continue_rcu(node, &hsr->node_db, mac_list) {
+ ether_addr_copy(addr, node->macaddress_A);
+ return node;
+ }
+@@ -633,11 +598,8 @@ int hsr_get_node_data(struct hsr_priv *hsr,
+ struct hsr_node *node;
+ struct hsr_port *port;
+ unsigned long tdiff;
+- u32 hash;
+-
+- hash = hsr_mac_hash(hsr, addr);
+
+- node = find_node_by_addr_A(&hsr->node_db[hash], addr);
++ node = find_node_by_addr_A(&hsr->node_db, addr);
+ if (!node)
+ return -ENOENT;
+
+diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
+index f3762e9e42b54..b23556251d621 100644
+--- a/net/hsr/hsr_framereg.h
++++ b/net/hsr/hsr_framereg.h
+@@ -28,17 +28,9 @@ struct hsr_frame_info {
+ bool is_from_san;
+ };
+
+-#ifdef CONFIG_LOCKDEP
+-int lockdep_hsr_is_held(spinlock_t *lock);
+-#else
+-#define lockdep_hsr_is_held(lock) 1
+-#endif
+-
+-u32 hsr_mac_hash(struct hsr_priv *hsr, const unsigned char *addr);
+-struct hsr_node *hsr_node_get_first(struct hlist_head *head, spinlock_t *lock);
+ void hsr_del_self_node(struct hsr_priv *hsr);
+-void hsr_del_nodes(struct hlist_head *node_db);
+-struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
++void hsr_del_nodes(struct list_head *node_db);
++struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
+ struct sk_buff *skb, bool is_sup,
+ enum hsr_port_type rx_port);
+ void hsr_handle_sup_frame(struct hsr_frame_info *frame);
+@@ -76,7 +68,9 @@ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+ void prp_update_san_info(struct hsr_node *node, bool is_sup);
+
+ struct hsr_node {
+- struct hlist_node mac_list;
++ struct list_head mac_list;
++ /* Protect R/W access to seq_out */
++ spinlock_t seq_out_lock;
+ unsigned char macaddress_A[ETH_ALEN];
+ unsigned char macaddress_B[ETH_ALEN];
+ /* Local slave through which AddrB frames are received from this node */
+@@ -88,6 +82,7 @@ struct hsr_node {
+ bool san_a;
+ bool san_b;
+ u16 seq_out[HSR_PT_PORTS];
++ bool removed;
+ struct rcu_head rcu_head;
+ };
+
+diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
+index b158ba409f9a4..16ae9fb09ccd2 100644
+--- a/net/hsr/hsr_main.h
++++ b/net/hsr/hsr_main.h
+@@ -47,9 +47,6 @@
+
+ #define HSR_V1_SUP_LSDUSIZE 52
+
+-#define HSR_HSIZE_SHIFT 8
+-#define HSR_HSIZE BIT(HSR_HSIZE_SHIFT)
+-
+ /* The helper functions below assumes that 'path' occupies the 4 most
+ * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or
+ * equivalently, the 4 most significant bits of HSR tag byte 14).
+@@ -188,8 +185,8 @@ struct hsr_proto_ops {
+ struct hsr_priv {
+ struct rcu_head rcu_head;
+ struct list_head ports;
+- struct hlist_head node_db[HSR_HSIZE]; /* Known HSR nodes */
+- struct hlist_head self_node_db; /* MACs of slaves */
++ struct list_head node_db; /* Known HSR nodes */
++ struct list_head self_node_db; /* MACs of slaves */
+ struct timer_list announce_timer; /* Supervision frame dispatch */
+ struct timer_list prune_timer;
+ int announce_count;
+@@ -199,8 +196,6 @@ struct hsr_priv {
+ spinlock_t seqnr_lock; /* locking for sequence_nr */
+ spinlock_t list_lock; /* locking for node list */
+ struct hsr_proto_ops *proto_ops;
+- u32 hash_buckets;
+- u32 hash_seed;
+ #define PRP_LAN_ID 0x5 /* 0x1010 for A and 0x1011 for B. Bit 0 is set
+ * based on SLAVE_A or SLAVE_B
+ */
+diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
+index 1405c037cf7ab..f3c8f91dbe2c1 100644
+--- a/net/hsr/hsr_netlink.c
++++ b/net/hsr/hsr_netlink.c
+@@ -105,7 +105,6 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
+ static void hsr_dellink(struct net_device *dev, struct list_head *head)
+ {
+ struct hsr_priv *hsr = netdev_priv(dev);
+- int i;
+
+ del_timer_sync(&hsr->prune_timer);
+ del_timer_sync(&hsr->announce_timer);
+@@ -114,8 +113,7 @@ static void hsr_dellink(struct net_device *dev, struct list_head *head)
+ hsr_del_ports(hsr);
+
+ hsr_del_self_node(hsr);
+- for (i = 0; i < hsr->hash_buckets; i++)
+- hsr_del_nodes(&hsr->node_db[i]);
++ hsr_del_nodes(&hsr->node_db);
+
+ unregister_netdevice_queue(dev, head);
+ }
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 7f6d7c355e38e..31f463f46f6ed 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -522,9 +522,9 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
+ /* Make sure we are allowed to bind here. */
+ if (snum || !(inet->bind_address_no_port ||
+ (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
+- if (sk->sk_prot->get_port(sk, snum)) {
++ err = sk->sk_prot->get_port(sk, snum);
++ if (err) {
+ inet->inet_saddr = inet->inet_rcv_saddr = 0;
+- err = -EADDRINUSE;
+ goto out_release_sock;
+ }
+ if (!(flags & BIND_FROM_BPF)) {
+@@ -1686,9 +1686,9 @@ u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offt,
+ bhptr = per_cpu_ptr(mib, cpu);
+ syncp = (struct u64_stats_sync *)(bhptr + syncp_offset);
+ do {
+- start = u64_stats_fetch_begin_irq(syncp);
++ start = u64_stats_fetch_begin(syncp);
+ v = *(((u64 *)bhptr) + offt);
+- } while (u64_stats_fetch_retry_irq(syncp, start));
++ } while (u64_stats_fetch_retry(syncp, start));
+
+ return v;
+ }
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index eb31c7158b39c..971969cc7e17f 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -1041,7 +1041,7 @@ int inet_csk_listen_start(struct sock *sk)
+ {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ struct inet_sock *inet = inet_sk(sk);
+- int err = -EADDRINUSE;
++ int err;
+
+ reqsk_queue_alloc(&icsk->icsk_accept_queue);
+
+@@ -1057,7 +1057,8 @@ int inet_csk_listen_start(struct sock *sk)
+ * after validation is complete.
+ */
+ inet_sk_state_store(sk, TCP_LISTEN);
+- if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
++ err = sk->sk_prot->get_port(sk, inet->inet_num);
++ if (!err) {
+ inet->inet_sport = htons(inet->inet_num);
+
+ sk_dst_reset(sk);
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index 3b2420829c237..948f4801f993e 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -142,7 +142,7 @@ next_port:
+
+ fail:
+ spin_unlock(&ping_table.lock);
+- return 1;
++ return -EADDRINUSE;
+ }
+ EXPORT_SYMBOL_GPL(ping_get_port);
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index cf9c3e8f7ccbf..94aad3870c5fc 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -45,8 +45,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+ tmp->sg.end = i;
+ if (apply) {
+ apply_bytes -= size;
+- if (!apply_bytes)
++ if (!apply_bytes) {
++ if (sge->length)
++ sk_msg_iter_var_prev(i);
+ break;
++ }
+ }
+ } while (i != msg->sg.end);
+
+@@ -131,10 +134,9 @@ static int tcp_bpf_push_locked(struct sock *sk, struct sk_msg *msg,
+ return ret;
+ }
+
+-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg,
+- u32 bytes, int flags)
++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress,
++ struct sk_msg *msg, u32 bytes, int flags)
+ {
+- bool ingress = sk_msg_to_ingress(msg);
+ struct sk_psock *psock = sk_psock_get(sk);
+ int ret;
+
+@@ -276,10 +278,10 @@ msg_bytes_ready:
+ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+ struct sk_msg *msg, int *copied, int flags)
+ {
+- bool cork = false, enospc = sk_msg_full(msg);
++ bool cork = false, enospc = sk_msg_full(msg), redir_ingress;
+ struct sock *sk_redir;
+ u32 tosend, origsize, sent, delta = 0;
+- u32 eval = __SK_NONE;
++ u32 eval;
+ int ret;
+
+ more_data:
+@@ -310,6 +312,7 @@ more_data:
+ tosend = msg->sg.size;
+ if (psock->apply_bytes && psock->apply_bytes < tosend)
+ tosend = psock->apply_bytes;
++ eval = __SK_NONE;
+
+ switch (psock->eval) {
+ case __SK_PASS:
+@@ -321,6 +324,7 @@ more_data:
+ sk_msg_apply_bytes(psock, tosend);
+ break;
+ case __SK_REDIRECT:
++ redir_ingress = psock->redir_ingress;
+ sk_redir = psock->sk_redir;
+ sk_msg_apply_bytes(psock, tosend);
+ if (!psock->apply_bytes) {
+@@ -337,7 +341,8 @@ more_data:
+ release_sock(sk);
+
+ origsize = msg->sg.size;
+- ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags);
++ ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress,
++ msg, tosend, flags);
+ sent = origsize - msg->sg.size;
+
+ if (eval == __SK_REDIRECT)
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index d9099754ac69d..7fe0ba3f0933e 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -232,16 +232,16 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
+ int udp_lib_get_port(struct sock *sk, unsigned short snum,
+ unsigned int hash2_nulladdr)
+ {
+- struct udp_hslot *hslot, *hslot2;
+ struct udp_table *udptable = sk->sk_prot->h.udp_table;
+- int error = 1;
++ struct udp_hslot *hslot, *hslot2;
+ struct net *net = sock_net(sk);
++ int error = -EADDRINUSE;
+
+ if (!snum) {
++ DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
++ unsigned short first, last;
+ int low, high, remaining;
+ unsigned int rand;
+- unsigned short first, last;
+- DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
+
+ inet_get_local_port_range(net, &low, &high);
+ remaining = (high - low) + 1;
+@@ -2527,10 +2527,13 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
+ __be16 rmt_port, __be32 rmt_addr,
+ int dif, int sdif)
+ {
+- struct sock *sk, *result;
+ unsigned short hnum = ntohs(loc_port);
+- unsigned int slot = udp_hashfn(net, hnum, udp_table.mask);
+- struct udp_hslot *hslot = &udp_table.hash[slot];
++ struct sock *sk, *result;
++ struct udp_hslot *hslot;
++ unsigned int slot;
++
++ slot = udp_hashfn(net, hnum, udp_table.mask);
++ hslot = &udp_table.hash[slot];
+
+ /* Do not bother scanning a too big list */
+ if (hslot->count > 10)
+@@ -2558,14 +2561,18 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
+ __be16 rmt_port, __be32 rmt_addr,
+ int dif, int sdif)
+ {
+- unsigned short hnum = ntohs(loc_port);
+- unsigned int hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
+- unsigned int slot2 = hash2 & udp_table.mask;
+- struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
+ INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr);
+- const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
++ unsigned short hnum = ntohs(loc_port);
++ unsigned int hash2, slot2;
++ struct udp_hslot *hslot2;
++ __portpair ports;
+ struct sock *sk;
+
++ hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
++ slot2 = hash2 & udp_table.mask;
++ hslot2 = &udp_table.hash2[slot2];
++ ports = INET_COMBINED_PORTS(rmt_port, hnum);
++
+ udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+ if (inet_match(net, sk, acookie, ports, dif, sdif))
+ return sk;
+@@ -2966,10 +2973,10 @@ EXPORT_SYMBOL(udp_prot);
+
+ static struct sock *udp_get_first(struct seq_file *seq, int start)
+ {
+- struct sock *sk;
+- struct udp_seq_afinfo *afinfo;
+ struct udp_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
++ struct udp_seq_afinfo *afinfo;
++ struct sock *sk;
+
+ if (state->bpf_seq_afinfo)
+ afinfo = state->bpf_seq_afinfo;
+@@ -3000,9 +3007,9 @@ found:
+
+ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
+ {
+- struct udp_seq_afinfo *afinfo;
+ struct udp_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
++ struct udp_seq_afinfo *afinfo;
+
+ if (state->bpf_seq_afinfo)
+ afinfo = state->bpf_seq_afinfo;
+@@ -3058,8 +3065,8 @@ EXPORT_SYMBOL(udp_seq_next);
+
+ void udp_seq_stop(struct seq_file *seq, void *v)
+ {
+- struct udp_seq_afinfo *afinfo;
+ struct udp_iter_state *state = seq->private;
++ struct udp_seq_afinfo *afinfo;
+
+ if (state->bpf_seq_afinfo)
+ afinfo = state->bpf_seq_afinfo;
+diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
+index 8242c8947340e..5f8104cf082d0 100644
+--- a/net/ipv4/udp_tunnel_core.c
++++ b/net/ipv4/udp_tunnel_core.c
+@@ -176,6 +176,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
+ void udp_tunnel_sock_release(struct socket *sock)
+ {
+ rcu_assign_sk_user_data(sock->sk, NULL);
++ synchronize_rcu();
+ kernel_sock_shutdown(sock, SHUT_RDWR);
+ sock_release(sock);
+ }
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index dbb1430d6cc2e..cceda5c833021 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -403,10 +403,10 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
+ /* Make sure we are allowed to bind here. */
+ if (snum || !(inet->bind_address_no_port ||
+ (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
+- if (sk->sk_prot->get_port(sk, snum)) {
++ err = sk->sk_prot->get_port(sk, snum);
++ if (err) {
+ sk->sk_ipv6only = saved_ipv6only;
+ inet_reset_saddr(sk);
+- err = -EADDRINUSE;
+ goto out;
+ }
+ if (!(flags & BIND_FROM_BPF)) {
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index 5ecb56522f9d6..ba28aeb7cade0 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -42,24 +42,29 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
+ {
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipv6_pinfo *np = inet6_sk(sk);
++ int oif = sk->sk_bound_dev_if;
+
+ memset(fl6, 0, sizeof(*fl6));
+ fl6->flowi6_proto = sk->sk_protocol;
+ fl6->daddr = sk->sk_v6_daddr;
+ fl6->saddr = np->saddr;
+- fl6->flowi6_oif = sk->sk_bound_dev_if;
+ fl6->flowi6_mark = sk->sk_mark;
+ fl6->fl6_dport = inet->inet_dport;
+ fl6->fl6_sport = inet->inet_sport;
+ fl6->flowlabel = np->flow_label;
+ fl6->flowi6_uid = sk->sk_uid;
+
+- if (!fl6->flowi6_oif)
+- fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
++ if (!oif)
++ oif = np->sticky_pktinfo.ipi6_ifindex;
+
+- if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr))
+- fl6->flowi6_oif = np->mcast_oif;
++ if (!oif) {
++ if (ipv6_addr_is_multicast(&fl6->daddr))
++ oif = np->mcast_oif;
++ else
++ oif = np->ucast_oif;
++ }
+
++ fl6->flowi6_oif = oif;
+ security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
+ }
+
+diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
+index b7de5e46fdd8f..f84da849819cc 100644
+--- a/net/ipv6/seg6_local.c
++++ b/net/ipv6/seg6_local.c
+@@ -1508,13 +1508,13 @@ static int put_nla_counters(struct sk_buff *skb, struct seg6_local_lwt *slwt)
+
+ pcounters = per_cpu_ptr(slwt->pcpu_counters, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&pcounters->syncp);
++ start = u64_stats_fetch_begin(&pcounters->syncp);
+
+ packets = u64_stats_read(&pcounters->packets);
+ bytes = u64_stats_read(&pcounters->bytes);
+ errors = u64_stats_read(&pcounters->errors);
+
+- } while (u64_stats_fetch_retry_irq(&pcounters->syncp, start));
++ } while (u64_stats_fetch_retry(&pcounters->syncp, start));
+
+ counters.packets += packets;
+ counters.bytes += bytes;
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 59b2d9a6210c8..ccb39b1e730f8 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -694,7 +694,7 @@ static int ipip6_rcv(struct sk_buff *skb)
+ skb->dev = tunnel->dev;
+
+ if (packet_is_spoofed(skb, iph, tunnel)) {
+- tunnel->dev->stats.rx_errors++;
++ DEV_STATS_INC(tunnel->dev, rx_errors);
+ goto out;
+ }
+
+@@ -714,8 +714,8 @@ static int ipip6_rcv(struct sk_buff *skb)
+ net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
+ &iph->saddr, iph->tos);
+ if (err > 1) {
+- ++tunnel->dev->stats.rx_frame_errors;
+- ++tunnel->dev->stats.rx_errors;
++ DEV_STATS_INC(tunnel->dev, rx_frame_errors);
++ DEV_STATS_INC(tunnel->dev, rx_errors);
+ goto out;
+ }
+ }
+@@ -942,7 +942,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ if (!rt) {
+ rt = ip_route_output_flow(tunnel->net, &fl4, NULL);
+ if (IS_ERR(rt)) {
+- dev->stats.tx_carrier_errors++;
++ DEV_STATS_INC(dev, tx_carrier_errors);
+ goto tx_error_icmp;
+ }
+ dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, fl4.saddr);
+@@ -950,14 +950,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+
+ if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
+ ip_rt_put(rt);
+- dev->stats.tx_carrier_errors++;
++ DEV_STATS_INC(dev, tx_carrier_errors);
+ goto tx_error_icmp;
+ }
+ tdev = rt->dst.dev;
+
+ if (tdev == dev) {
+ ip_rt_put(rt);
+- dev->stats.collisions++;
++ DEV_STATS_INC(dev, collisions);
+ goto tx_error;
+ }
+
+@@ -970,7 +970,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+
+ if (mtu < IPV4_MIN_MTU) {
+- dev->stats.collisions++;
++ DEV_STATS_INC(dev, collisions);
+ ip_rt_put(rt);
+ goto tx_error;
+ }
+@@ -1009,7 +1009,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb) {
+ ip_rt_put(rt);
+- dev->stats.tx_dropped++;
++ DEV_STATS_INC(dev, tx_dropped);
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+@@ -1039,7 +1039,7 @@ tx_error_icmp:
+ dst_link_failure(skb);
+ tx_error:
+ kfree_skb(skb);
+- dev->stats.tx_errors++;
++ DEV_STATS_INC(dev, tx_errors);
+ return NETDEV_TX_OK;
+ }
+
+@@ -1058,7 +1058,7 @@ static netdev_tx_t sit_tunnel_xmit__(struct sk_buff *skb,
+ return NETDEV_TX_OK;
+ tx_error:
+ kfree_skb(skb);
+- dev->stats.tx_errors++;
++ DEV_STATS_INC(dev, tx_errors);
+ return NETDEV_TX_OK;
+ }
+
+@@ -1087,7 +1087,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
+ return NETDEV_TX_OK;
+
+ tx_err:
+- dev->stats.tx_errors++;
++ DEV_STATS_INC(dev, tx_errors);
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index fb667e02e9760..d917d62e662d6 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1039,12 +1039,16 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+ int dif, int sdif)
+ {
+ unsigned short hnum = ntohs(loc_port);
+- unsigned int hash2 = ipv6_portaddr_hash(net, loc_addr, hnum);
+- unsigned int slot2 = hash2 & udp_table.mask;
+- struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
+- const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
++ unsigned int hash2, slot2;
++ struct udp_hslot *hslot2;
++ __portpair ports;
+ struct sock *sk;
+
++ hash2 = ipv6_portaddr_hash(net, loc_addr, hnum);
++ slot2 = hash2 & udp_table.mask;
++ hslot2 = &udp_table.hash2[slot2];
++ ports = INET_COMBINED_PORTS(rmt_port, hnum);
++
+ udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+ if (sk->sk_state == TCP_ESTABLISHED &&
+ inet6_match(net, sk, rmt_addr, loc_addr, ports, dif, sdif))
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 65f34945a7678..538f8c0dbb2b6 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -539,7 +539,7 @@ static struct ieee80211_key *
+ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
+ u8 key_idx, bool pairwise, const u8 *mac_addr)
+ {
+- struct ieee80211_local *local = sdata->local;
++ struct ieee80211_local *local __maybe_unused = sdata->local;
+ struct ieee80211_key *key;
+ struct sta_info *sta;
+
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 9583643b70332..c7dd1f49bb351 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -389,6 +389,7 @@ struct ieee80211_mgd_auth_data {
+ bool done, waiting;
+ bool peer_confirmed;
+ bool timeout_started;
++ int link_id;
+
+ u8 ap_addr[ETH_ALEN] __aligned(2);
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 95b58c5cac07f..c3eb08b5a47e3 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -2414,6 +2414,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+
+ ret = cfg80211_register_netdevice(ndev);
+ if (ret) {
++ ieee80211_if_free(ndev);
+ free_netdev(ndev);
+ return ret;
+ }
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 654414caeb71e..0a9710747b80e 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4955,6 +4955,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_rx_assoc_resp resp = {
+ .uapsd_queues = -1,
+ };
++ u8 ap_mld_addr[ETH_ALEN] __aligned(2);
+ unsigned int link_id;
+
+ sdata_assert_lock(sdata);
+@@ -5119,6 +5120,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
+ }
+
++ if (sdata->vif.valid_links) {
++ ether_addr_copy(ap_mld_addr, sdata->vif.cfg.ap_addr);
++ resp.ap_mld_addr = ap_mld_addr;
++ }
++
+ ieee80211_destroy_assoc_data(sdata,
+ status_code == WLAN_STATUS_SUCCESS ?
+ ASSOC_SUCCESS :
+@@ -5128,8 +5134,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ resp.len = len;
+ resp.req_ies = ifmgd->assoc_req_ies;
+ resp.req_ies_len = ifmgd->assoc_req_ies_len;
+- if (sdata->vif.valid_links)
+- resp.ap_mld_addr = sdata->vif.cfg.ap_addr;
+ cfg80211_rx_assoc_resp(sdata->dev, &resp);
+ notify_driver:
+ drv_mgd_complete_tx(sdata->local, sdata, &info);
+@@ -6578,6 +6582,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+ req->ap_mld_addr ?: req->bss->bssid,
+ ETH_ALEN);
+ auth_data->bss = req->bss;
++ auth_data->link_id = req->link_id;
+
+ if (req->auth_data_len >= 4) {
+ if (req->auth_type == NL80211_AUTHTYPE_SAE) {
+@@ -6596,7 +6601,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+ * removal and re-addition of the STA entry in
+ * ieee80211_prep_connection().
+ */
+- cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss;
++ cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss &&
++ ifmgd->auth_data->link_id == req->link_id;
+
+ if (req->ie && req->ie_len) {
+ memcpy(&auth_data->data[auth_data->data_len],
+@@ -6933,7 +6939,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+
+ /* keep sta info, bssid if matching */
+ match = ether_addr_equal(ifmgd->auth_data->ap_addr,
+- assoc_data->ap_addr);
++ assoc_data->ap_addr) &&
++ ifmgd->auth_data->link_id == req->link_id;
+ ieee80211_destroy_auth_data(sdata, match);
+ }
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 9d7b238a67372..965b9cb2ef3f2 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2316,9 +2316,9 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats,
+ u64 value;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&rxstats->syncp);
++ start = u64_stats_fetch_begin(&rxstats->syncp);
+ value = rxstats->msdu[tid];
+- } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
++ } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+
+ return value;
+ }
+@@ -2384,9 +2384,9 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
+ u64 value;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&rxstats->syncp);
++ start = u64_stats_fetch_begin(&rxstats->syncp);
+ value = rxstats->bytes;
+- } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
++ } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+
+ return value;
+ }
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index d2c4f9226f947..dafd3a480f024 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -2934,7 +2934,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
+
+ if (pre_conf_link_id != link_id &&
+ link_id != IEEE80211_LINK_UNSPECIFIED) {
+-#ifdef CPTCFG_MAC80211_VERBOSE_DEBUG
++#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ net_info_ratelimited("%s: dropped frame to %pM with bad link ID request (%d vs. %d)\n",
+ sdata->name, hdr.addr1,
+ pre_conf_link_id, link_id);
+diff --git a/net/mctp/device.c b/net/mctp/device.c
+index 99a3bda8852f8..acb97b2574289 100644
+--- a/net/mctp/device.c
++++ b/net/mctp/device.c
+@@ -429,12 +429,6 @@ static void mctp_unregister(struct net_device *dev)
+ struct mctp_dev *mdev;
+
+ mdev = mctp_dev_get_rtnl(dev);
+- if (mdev && !mctp_known(dev)) {
+- // Sanity check, should match what was set in mctp_register
+- netdev_warn(dev, "%s: BUG mctp_ptr set for unknown type %d",
+- __func__, dev->type);
+- return;
+- }
+ if (!mdev)
+ return;
+
+@@ -451,14 +445,8 @@ static int mctp_register(struct net_device *dev)
+ struct mctp_dev *mdev;
+
+ /* Already registered? */
+- mdev = rtnl_dereference(dev->mctp_ptr);
+-
+- if (mdev) {
+- if (!mctp_known(dev))
+- netdev_warn(dev, "%s: BUG mctp_ptr set for unknown type %d",
+- __func__, dev->type);
++ if (rtnl_dereference(dev->mctp_ptr))
+ return 0;
+- }
+
+ /* only register specific types */
+ if (!mctp_known(dev))
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index b52afe316dc41..35b5f806fdda1 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -1079,9 +1079,9 @@ static void mpls_get_stats(struct mpls_dev *mdev,
+
+ p = per_cpu_ptr(mdev->stats, i);
+ do {
+- start = u64_stats_fetch_begin_irq(&p->syncp);
++ start = u64_stats_fetch_begin(&p->syncp);
+ local = p->stats;
+- } while (u64_stats_fetch_retry_irq(&p->syncp, start));
++ } while (u64_stats_fetch_retry(&p->syncp, start));
+
+ stats->rx_packets += local.rx_packets;
+ stats->rx_bytes += local.rx_bytes;
+diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
+index 51ad557a525b5..b5ae419661b80 100644
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -132,21 +132,21 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+
+ s = this_cpu_ptr(dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.inpkts++;
+- s->cnt.inbytes += skb->len;
++ u64_stats_inc(&s->cnt.inpkts);
++ u64_stats_add(&s->cnt.inbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ svc = rcu_dereference(dest->svc);
+ s = this_cpu_ptr(svc->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.inpkts++;
+- s->cnt.inbytes += skb->len;
++ u64_stats_inc(&s->cnt.inpkts);
++ u64_stats_add(&s->cnt.inbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.inpkts++;
+- s->cnt.inbytes += skb->len;
++ u64_stats_inc(&s->cnt.inpkts);
++ u64_stats_add(&s->cnt.inbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ local_bh_enable();
+@@ -168,21 +168,21 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+
+ s = this_cpu_ptr(dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.outpkts++;
+- s->cnt.outbytes += skb->len;
++ u64_stats_inc(&s->cnt.outpkts);
++ u64_stats_add(&s->cnt.outbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ svc = rcu_dereference(dest->svc);
+ s = this_cpu_ptr(svc->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.outpkts++;
+- s->cnt.outbytes += skb->len;
++ u64_stats_inc(&s->cnt.outpkts);
++ u64_stats_add(&s->cnt.outbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.outpkts++;
+- s->cnt.outbytes += skb->len;
++ u64_stats_inc(&s->cnt.outpkts);
++ u64_stats_add(&s->cnt.outbytes, skb->len);
+ u64_stats_update_end(&s->syncp);
+
+ local_bh_enable();
+@@ -200,17 +200,17 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
+
+ s = this_cpu_ptr(cp->dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.conns++;
++ u64_stats_inc(&s->cnt.conns);
+ u64_stats_update_end(&s->syncp);
+
+ s = this_cpu_ptr(svc->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.conns++;
++ u64_stats_inc(&s->cnt.conns);
+ u64_stats_update_end(&s->syncp);
+
+ s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+- s->cnt.conns++;
++ u64_stats_inc(&s->cnt.conns);
+ u64_stats_update_end(&s->syncp);
+
+ local_bh_enable();
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index efab2b06d3732..65bda976845da 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -2296,13 +2296,13 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v)
+ u64 conns, inpkts, outpkts, inbytes, outbytes;
+
+ do {
+- start = u64_stats_fetch_begin_irq(&u->syncp);
+- conns = u->cnt.conns;
+- inpkts = u->cnt.inpkts;
+- outpkts = u->cnt.outpkts;
+- inbytes = u->cnt.inbytes;
+- outbytes = u->cnt.outbytes;
+- } while (u64_stats_fetch_retry_irq(&u->syncp, start));
++ start = u64_stats_fetch_begin(&u->syncp);
++ conns = u64_stats_read(&u->cnt.conns);
++ inpkts = u64_stats_read(&u->cnt.inpkts);
++ outpkts = u64_stats_read(&u->cnt.outpkts);
++ inbytes = u64_stats_read(&u->cnt.inbytes);
++ outbytes = u64_stats_read(&u->cnt.outbytes);
++ } while (u64_stats_fetch_retry(&u->syncp, start));
+
+ seq_printf(seq, "%3X %8LX %8LX %8LX %16LX %16LX\n",
+ i, (u64)conns, (u64)inpkts,
+diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
+index 9a1a7af6a186a..f53150d82a92d 100644
+--- a/net/netfilter/ipvs/ip_vs_est.c
++++ b/net/netfilter/ipvs/ip_vs_est.c
+@@ -67,11 +67,11 @@ static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
+ if (add) {
+ do {
+ start = u64_stats_fetch_begin(&s->syncp);
+- conns = s->cnt.conns;
+- inpkts = s->cnt.inpkts;
+- outpkts = s->cnt.outpkts;
+- inbytes = s->cnt.inbytes;
+- outbytes = s->cnt.outbytes;
++ conns = u64_stats_read(&s->cnt.conns);
++ inpkts = u64_stats_read(&s->cnt.inpkts);
++ outpkts = u64_stats_read(&s->cnt.outpkts);
++ inbytes = u64_stats_read(&s->cnt.inbytes);
++ outbytes = u64_stats_read(&s->cnt.outbytes);
+ } while (u64_stats_fetch_retry(&s->syncp, start));
+ sum->conns += conns;
+ sum->inpkts += inpkts;
+@@ -82,11 +82,11 @@ static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
+ add = true;
+ do {
+ start = u64_stats_fetch_begin(&s->syncp);
+- sum->conns = s->cnt.conns;
+- sum->inpkts = s->cnt.inpkts;
+- sum->outpkts = s->cnt.outpkts;
+- sum->inbytes = s->cnt.inbytes;
+- sum->outbytes = s->cnt.outbytes;
++ sum->conns = u64_stats_read(&s->cnt.conns);
++ sum->inpkts = u64_stats_read(&s->cnt.inpkts);
++ sum->outpkts = u64_stats_read(&s->cnt.outpkts);
++ sum->inbytes = u64_stats_read(&s->cnt.inbytes);
++ sum->outbytes = u64_stats_read(&s->cnt.outbytes);
+ } while (u64_stats_fetch_retry(&s->syncp, start));
+ }
+ }
+diff --git a/net/netfilter/nf_conntrack_proto_icmpv6.c b/net/netfilter/nf_conntrack_proto_icmpv6.c
+index 61e3b05cf02c3..1020d67600a95 100644
+--- a/net/netfilter/nf_conntrack_proto_icmpv6.c
++++ b/net/netfilter/nf_conntrack_proto_icmpv6.c
+@@ -129,6 +129,56 @@ static void icmpv6_error_log(const struct sk_buff *skb,
+ nf_l4proto_log_invalid(skb, state, IPPROTO_ICMPV6, "%s", msg);
+ }
+
++static noinline_for_stack int
++nf_conntrack_icmpv6_redirect(struct nf_conn *tmpl, struct sk_buff *skb,
++ unsigned int dataoff,
++ const struct nf_hook_state *state)
++{
++ u8 hl = ipv6_hdr(skb)->hop_limit;
++ union nf_inet_addr outer_daddr;
++ union {
++ struct nd_opt_hdr nd_opt;
++ struct rd_msg rd_msg;
++ } tmp;
++ const struct nd_opt_hdr *nd_opt;
++ const struct rd_msg *rd_msg;
++
++ rd_msg = skb_header_pointer(skb, dataoff, sizeof(*rd_msg), &tmp.rd_msg);
++ if (!rd_msg) {
++ icmpv6_error_log(skb, state, "short redirect");
++ return -NF_ACCEPT;
++ }
++
++ if (rd_msg->icmph.icmp6_code != 0)
++ return NF_ACCEPT;
++
++ if (hl != 255 || !(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
++ icmpv6_error_log(skb, state, "invalid saddr or hoplimit for redirect");
++ return -NF_ACCEPT;
++ }
++
++ dataoff += sizeof(*rd_msg);
++
++ /* warning: rd_msg no longer usable after this call */
++ nd_opt = skb_header_pointer(skb, dataoff, sizeof(*nd_opt), &tmp.nd_opt);
++ if (!nd_opt || nd_opt->nd_opt_len == 0) {
++ icmpv6_error_log(skb, state, "redirect without options");
++ return -NF_ACCEPT;
++ }
++
++ /* We could call ndisc_parse_options(), but it would need
++ * skb_linearize() and a bit more work.
++ */
++ if (nd_opt->nd_opt_type != ND_OPT_REDIRECT_HDR)
++ return NF_ACCEPT;
++
++ memcpy(&outer_daddr.ip6, &ipv6_hdr(skb)->daddr,
++ sizeof(outer_daddr.ip6));
++ dataoff += 8;
++ return nf_conntrack_inet_error(tmpl, skb, dataoff, state,
++ IPPROTO_ICMPV6, &outer_daddr);
++}
++
+ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+ struct sk_buff *skb,
+ unsigned int dataoff,
+@@ -159,6 +209,9 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+ return NF_ACCEPT;
+ }
+
++ if (icmp6h->icmp6_type == NDISC_REDIRECT)
++ return nf_conntrack_icmpv6_redirect(tmpl, skb, dataoff, state);
++
+ /* is not error message ? */
+ if (icmp6h->icmp6_type >= 128)
+ return NF_ACCEPT;
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 0fdcdb2c9ae43..4d9b99abe37d6 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -383,12 +383,12 @@ static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
+ const __be32 *addr, const __be32 *mask)
+ {
+ struct flow_action_entry *entry;
+- int i, j;
++ int i;
+
+- for (i = 0, j = 0; i < sizeof(struct in6_addr) / sizeof(u32); i += sizeof(u32), j++) {
++ for (i = 0; i < sizeof(struct in6_addr) / sizeof(u32); i++) {
+ entry = flow_action_entry_next(flow_rule);
+ flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP6,
+- offset + i, &addr[j], mask);
++ offset + i * sizeof(u32), &addr[i], mask);
+ }
+ }
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 0a6f3c1e9ab75..7977f0422ecf6 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -1534,10 +1534,10 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
+ for_each_possible_cpu(cpu) {
+ cpu_stats = per_cpu_ptr(stats, cpu);
+ do {
+- seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++ seq = u64_stats_fetch_begin(&cpu_stats->syncp);
+ pkts = cpu_stats->pkts;
+ bytes = cpu_stats->bytes;
+- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, seq));
+ total.pkts += pkts;
+ total.bytes += bytes;
+ }
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 8a22574ed7ad6..ac66cdc7b67b8 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -715,9 +715,9 @@ static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats,
+ percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
+
+ do {
+- start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
++ start = u64_stats_fetch_begin(&percpu_stats->syncp);
+ local_stats = *percpu_stats;
+- } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
++ } while (u64_stats_fetch_retry(&percpu_stats->syncp, start));
+
+ stats->n_hit += local_stats.n_hit;
+ stats->n_missed += local_stats.n_missed;
+@@ -947,6 +947,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ struct sw_flow_mask mask;
+ struct sk_buff *reply;
+ struct datapath *dp;
++ struct sw_flow_key *key;
+ struct sw_flow_actions *acts;
+ struct sw_flow_match match;
+ u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
+@@ -974,24 +975,26 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ /* Extract key. */
+- ovs_match_init(&match, &new_flow->key, false, &mask);
++ key = kzalloc(sizeof(*key), GFP_KERNEL);
++ if (!key) {
++ error = -ENOMEM;
++ goto err_kfree_key;
++ }
++
++ ovs_match_init(&match, key, false, &mask);
+ error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
+ a[OVS_FLOW_ATTR_MASK], log);
+ if (error)
+ goto err_kfree_flow;
+
++ ovs_flow_mask_key(&new_flow->key, key, true, &mask);
++
+ /* Extract flow identifier. */
+ error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
+- &new_flow->key, log);
++ key, log);
+ if (error)
+ goto err_kfree_flow;
+
+- /* unmasked key is needed to match when ufid is not used. */
+- if (ovs_identifier_is_key(&new_flow->id))
+- match.key = new_flow->id.unmasked_key;
+-
+- ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
+-
+ /* Validate actions. */
+ error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
+ &new_flow->key, &acts, log);
+@@ -1018,7 +1021,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ if (ovs_identifier_is_ufid(&new_flow->id))
+ flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
+ if (!flow)
+- flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
++ flow = ovs_flow_tbl_lookup(&dp->table, key);
+ if (likely(!flow)) {
+ rcu_assign_pointer(new_flow->sf_acts, acts);
+
+@@ -1088,6 +1091,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+
+ if (reply)
+ ovs_notify(&dp_flow_genl_family, reply, info);
++
++ kfree(key);
+ return 0;
+
+ err_unlock_ovs:
+@@ -1097,6 +1102,8 @@ err_kfree_acts:
+ ovs_nla_free_flow_actions(acts);
+ err_kfree_flow:
+ ovs_flow_free(new_flow, false);
++err_kfree_key:
++ kfree(key);
+ error:
+ return error;
+ }
+diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c
+index d4a2db0b22998..0a0e4c283f02e 100644
+--- a/net/openvswitch/flow_table.c
++++ b/net/openvswitch/flow_table.c
+@@ -205,9 +205,9 @@ static void tbl_mask_array_reset_counters(struct mask_array *ma)
+
+ stats = per_cpu_ptr(ma->masks_usage_stats, cpu);
+ do {
+- start = u64_stats_fetch_begin_irq(&stats->syncp);
++ start = u64_stats_fetch_begin(&stats->syncp);
+ counter = stats->usage_cntrs[i];
+- } while (u64_stats_fetch_retry_irq(&stats->syncp, start));
++ } while (u64_stats_fetch_retry(&stats->syncp, start));
+
+ ma->masks_usage_zero_cntr[i] += counter;
+ }
+@@ -1136,10 +1136,9 @@ void ovs_flow_masks_rebalance(struct flow_table *table)
+
+ stats = per_cpu_ptr(ma->masks_usage_stats, cpu);
+ do {
+- start = u64_stats_fetch_begin_irq(&stats->syncp);
++ start = u64_stats_fetch_begin(&stats->syncp);
+ counter = stats->usage_cntrs[i];
+- } while (u64_stats_fetch_retry_irq(&stats->syncp,
+- start));
++ } while (u64_stats_fetch_retry(&stats->syncp, start));
+
+ masks_and_count[i].counter += counter;
+ }
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index 9683617db7049..08c117bc083ec 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -93,7 +93,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
+ *_hard_ack = hard_ack;
+ *_top = top;
+
+- pkt->ack.bufferSpace = htons(8);
++ pkt->ack.bufferSpace = htons(0);
+ pkt->ack.maxSkew = htons(0);
+ pkt->ack.firstPacket = htonl(hard_ack + 1);
+ pkt->ack.previousPacket = htonl(call->ackr_highest_seq);
+diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
+index 3c3a626459deb..d4e4e94f4f987 100644
+--- a/net/rxrpc/sendmsg.c
++++ b/net/rxrpc/sendmsg.c
+@@ -716,7 +716,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
+ if (call->tx_total_len != -1 ||
+ call->tx_pending ||
+ call->tx_top != 0)
+- goto error_put;
++ goto out_put_unlock;
+ call->tx_total_len = p.call.tx_total_len;
+ }
+ }
+diff --git a/net/sched/ematch.c b/net/sched/ematch.c
+index 4ce6813618515..5c1235e6076ae 100644
+--- a/net/sched/ematch.c
++++ b/net/sched/ematch.c
+@@ -255,6 +255,8 @@ static int tcf_em_validate(struct tcf_proto *tp,
+ * the value carried.
+ */
+ if (em_hdr->flags & TCF_EM_SIMPLE) {
++ if (em->ops->datalen > 0)
++ goto errout;
+ if (data_len < sizeof(u32))
+ goto errout;
+ em->data = *(u32 *) data;
+diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
+index b46a416787ec3..43ebf090029d7 100644
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -84,17 +84,18 @@ static struct ctl_table sctp_table[] = {
+ { /* sentinel */ }
+ };
+
++/* The following index defines are used in sctp_sysctl_net_register().
++ * If you add new items to the sctp_net_table, please ensure that
++ * the index values of these defines hold the same meaning indicated by
++ * their macro names when they appear in sctp_net_table.
++ */
++#define SCTP_RTO_MIN_IDX 0
++#define SCTP_RTO_MAX_IDX 1
++#define SCTP_PF_RETRANS_IDX 2
++#define SCTP_PS_RETRANS_IDX 3
++
+ static struct ctl_table sctp_net_table[] = {
+- {
+- .procname = "rto_initial",
+- .data = &init_net.sctp.rto_initial,
+- .maxlen = sizeof(unsigned int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ONE,
+- .extra2 = &timer_max
+- },
+- {
++ [SCTP_RTO_MIN_IDX] = {
+ .procname = "rto_min",
+ .data = &init_net.sctp.rto_min,
+ .maxlen = sizeof(unsigned int),
+@@ -103,7 +104,7 @@ static struct ctl_table sctp_net_table[] = {
+ .extra1 = SYSCTL_ONE,
+ .extra2 = &init_net.sctp.rto_max
+ },
+- {
++ [SCTP_RTO_MAX_IDX] = {
+ .procname = "rto_max",
+ .data = &init_net.sctp.rto_max,
+ .maxlen = sizeof(unsigned int),
+@@ -112,6 +113,33 @@ static struct ctl_table sctp_net_table[] = {
+ .extra1 = &init_net.sctp.rto_min,
+ .extra2 = &timer_max
+ },
++ [SCTP_PF_RETRANS_IDX] = {
++ .procname = "pf_retrans",
++ .data = &init_net.sctp.pf_retrans,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = &init_net.sctp.ps_retrans,
++ },
++ [SCTP_PS_RETRANS_IDX] = {
++ .procname = "ps_retrans",
++ .data = &init_net.sctp.ps_retrans,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = &init_net.sctp.pf_retrans,
++ .extra2 = &ps_retrans_max,
++ },
++ {
++ .procname = "rto_initial",
++ .data = &init_net.sctp.rto_initial,
++ .maxlen = sizeof(unsigned int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ONE,
++ .extra2 = &timer_max
++ },
+ {
+ .procname = "rto_alpha_exp_divisor",
+ .data = &init_net.sctp.rto_alpha,
+@@ -207,24 +235,6 @@ static struct ctl_table sctp_net_table[] = {
+ .extra1 = SYSCTL_ONE,
+ .extra2 = SYSCTL_INT_MAX,
+ },
+- {
+- .procname = "pf_retrans",
+- .data = &init_net.sctp.pf_retrans,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ZERO,
+- .extra2 = &init_net.sctp.ps_retrans,
+- },
+- {
+- .procname = "ps_retrans",
+- .data = &init_net.sctp.ps_retrans,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = &init_net.sctp.pf_retrans,
+- .extra2 = &ps_retrans_max,
+- },
+ {
+ .procname = "sndbuf_policy",
+ .data = &init_net.sctp.sndbuf_policy,
+@@ -586,6 +596,11 @@ int sctp_sysctl_net_register(struct net *net)
+ for (i = 0; table[i].data; i++)
+ table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
+
++ table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
++ table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
++ table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
++ table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
++
+ net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
+ if (net->sctp.sysctl_header == NULL) {
+ kfree(table);
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index c284efa3d1efc..0918fa4cc9330 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -1391,7 +1391,7 @@ static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
+ break;
+ default:
+ err = -EAFNOSUPPORT;
+- goto out;
++ goto out_release;
+ }
+ if (err < 0) {
+ dprintk("RPC: can't bind UDP socket (%d)\n", err);
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index 2fbe9aaeec349..efa7bcdf6b283 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -834,7 +834,7 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
+ return req;
+
+ out3:
+- kfree(req->rl_sendbuf);
++ rpcrdma_regbuf_free(req->rl_sendbuf);
+ out2:
+ kfree(req);
+ out1:
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index fe27241cd13fc..0ee1df154fee0 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -792,7 +792,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
+ struct sk_psock *psock;
+ struct sock *sk_redir;
+ struct tls_rec *rec;
+- bool enospc, policy;
++ bool enospc, policy, redir_ingress;
+ int err = 0, send;
+ u32 delta = 0;
+
+@@ -837,6 +837,7 @@ more_data:
+ }
+ break;
+ case __SK_REDIRECT:
++ redir_ingress = psock->redir_ingress;
+ sk_redir = psock->sk_redir;
+ memcpy(&msg_redir, msg, sizeof(*msg));
+ if (msg->apply_bytes < send)
+@@ -846,7 +847,8 @@ more_data:
+ sk_msg_return_zero(sk, msg, send);
+ msg->sg.size -= send;
+ release_sock(sk);
+- err = tcp_bpf_sendmsg_redir(sk_redir, &msg_redir, send, flags);
++ err = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress,
++ &msg_redir, send, flags);
+ lock_sock(sk);
+ if (err < 0) {
+ *copied -= sk_msg_free_nocharge(sk, &msg_redir);
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index d686804119c99..48cc8223b06be 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1969,13 +1969,20 @@ restart_locked:
+ unix_state_lock(sk);
+
+ err = 0;
+- if (unix_peer(sk) == other) {
++ if (sk->sk_type == SOCK_SEQPACKET) {
++ /* We are here only when racing with unix_release_sock()
++ * is clearing @other. Never change state to TCP_CLOSE
++ * unlike SOCK_DGRAM wants.
++ */
++ unix_state_unlock(sk);
++ err = -EPIPE;
++ } else if (unix_peer(sk) == other) {
+ unix_peer(sk) = NULL;
+ unix_dgram_peer_wake_disconnect_wakeup(sk, other);
+
++ sk->sk_state = TCP_CLOSE;
+ unix_state_unlock(sk);
+
+- sk->sk_state = TCP_CLOSE;
+ unix_dgram_disconnected(sk, other);
+ sock_put(other);
+ err = -ECONNREFUSED;
+@@ -3724,6 +3731,7 @@ static int __init af_unix_init(void)
+ rc = proto_register(&unix_stream_proto, 1);
+ if (rc != 0) {
+ pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
++ proto_unregister(&unix_dgram_proto);
+ goto out;
+ }
+
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index b14f0ed7427bc..a794e8b011363 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -1711,7 +1711,11 @@ static int vmci_transport_dgram_enqueue(
+ if (!dg)
+ return -ENOMEM;
+
+- memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++ err = memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++ if (err) {
++ kfree(dg);
++ return err;
++ }
+
+ dg->dst = vmci_make_handle(remote_addr->svm_cid,
+ remote_addr->svm_port);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 2705e3ee8fc4e..3e41edace1ba7 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -3849,6 +3849,9 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
+ for_each_valid_link(wdev, link_id) {
+ struct nlattr *link = nla_nest_start(msg, link_id + 1);
+
++ if (!link)
++ goto nla_put_failure;
++
+ if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
+ goto nla_put_failure;
+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index c3d950d294329..4f3f31244e8ba 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4311,8 +4311,10 @@ static int __init regulatory_init_db(void)
+ return -EINVAL;
+
+ err = load_builtin_regdb_keys();
+- if (err)
++ if (err) {
++ platform_device_unregister(reg_pdev);
+ return err;
++ }
+
+ /* We always try to get an update for the static regdomain */
+ err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
+diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c
+index ac370e638fa3d..281dc964de8da 100644
+--- a/samples/bpf/xdp1_user.c
++++ b/samples/bpf/xdp1_user.c
+@@ -51,7 +51,7 @@ static void poll_stats(int map_fd, int interval)
+
+ sleep(interval);
+
+- while (bpf_map_get_next_key(map_fd, &key, &key) != -1) {
++ while (bpf_map_get_next_key(map_fd, &key, &key) == 0) {
+ __u64 sum = 0;
+
+ assert(bpf_map_lookup_elem(map_fd, &key, values) == 0);
+diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c
+index 3332ba6bb95fb..67804ecf7ce37 100644
+--- a/samples/bpf/xdp2_kern.c
++++ b/samples/bpf/xdp2_kern.c
+@@ -112,6 +112,10 @@ int xdp_prog1(struct xdp_md *ctx)
+
+ if (ipproto == IPPROTO_UDP) {
+ swap_src_dst_mac(data);
++
++ if (bpf_xdp_store_bytes(ctx, 0, pkt, sizeof(pkt)))
++ return rc;
++
+ rc = XDP_TX;
+ }
+
+diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c
+index 9ec93d90e8a5a..4eb7aa11cfbb2 100644
+--- a/samples/vfio-mdev/mdpy-fb.c
++++ b/samples/vfio-mdev/mdpy-fb.c
+@@ -109,7 +109,7 @@ static int mdpy_fb_probe(struct pci_dev *pdev,
+
+ ret = pci_request_regions(pdev, "mdpy-fb");
+ if (ret < 0)
+- return ret;
++ goto err_disable_dev;
+
+ pci_read_config_dword(pdev, MDPY_FORMAT_OFFSET, &format);
+ pci_read_config_dword(pdev, MDPY_WIDTH_OFFSET, &width);
+@@ -191,6 +191,9 @@ err_release_fb:
+ err_release_regions:
+ pci_release_regions(pdev);
+
++err_disable_dev:
++ pci_disable_device(pdev);
++
+ return ret;
+ }
+
+@@ -199,7 +202,10 @@ static void mdpy_fb_remove(struct pci_dev *pdev)
+ struct fb_info *info = pci_get_drvdata(pdev);
+
+ unregister_framebuffer(info);
++ iounmap(info->screen_base);
+ framebuffer_release(info);
++ pci_release_regions(pdev);
++ pci_disable_device(pdev);
+ }
+
+ static struct pci_device_id mdpy_fb_pci_table[] = {
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 995bc42003e6c..254e07f34234c 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -253,6 +253,9 @@ config INIT_ON_FREE_DEFAULT_ON
+
+ config CC_HAS_ZERO_CALL_USED_REGS
+ def_bool $(cc-option,-fzero-call-used-regs=used-gpr)
++ # https://github.com/ClangBuiltLinux/linux/issues/1766
++ # https://github.com/llvm/llvm-project/issues/59242
++ depends on !CC_IS_CLANG || CLANG_VERSION > 150006
+
+ config ZERO_CALL_USED_REGS
+ bool "Enable register zeroing on function exit"
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index d066ccc219e2d..7160e7aa58b94 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -868,8 +868,10 @@ static struct multi_transaction *multi_transaction_new(struct file *file,
+ if (!t)
+ return ERR_PTR(-ENOMEM);
+ kref_init(&t->count);
+- if (copy_from_user(t->data, buf, size))
++ if (copy_from_user(t->data, buf, size)) {
++ put_multi_transaction(t);
+ return ERR_PTR(-EFAULT);
++ }
+
+ return t;
+ }
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 0f36ee9074381..a67c5897ee254 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -197,15 +197,18 @@ static bool vec_is_stale(struct aa_profile **vec, int n)
+ return false;
+ }
+
+-static long union_vec_flags(struct aa_profile **vec, int n, long mask)
++static long accum_vec_flags(struct aa_profile **vec, int n)
+ {
+- long u = 0;
++ long u = FLAG_UNCONFINED;
+ int i;
+
+ AA_BUG(!vec);
+
+ for (i = 0; i < n; i++) {
+- u |= vec[i]->label.flags & mask;
++ u |= vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
++ FLAG_STALE);
++ if (!(u & vec[i]->label.flags & FLAG_UNCONFINED))
++ u &= ~FLAG_UNCONFINED;
+ }
+
+ return u;
+@@ -1097,8 +1100,7 @@ static struct aa_label *label_merge_insert(struct aa_label *new,
+ else if (k == b->size)
+ return aa_get_label(b);
+ }
+- new->flags |= union_vec_flags(new->vec, new->size, FLAG_UNCONFINED |
+- FLAG_DEBUG1 | FLAG_DEBUG2);
++ new->flags |= accum_vec_flags(new->vec, new->size);
+ ls = labels_set(new);
+ write_lock_irqsave(&ls->lock, flags);
+ label = __label_insert(labels_set(new), new, false);
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index e29cade7b6627..9eb7972e08e49 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -1194,10 +1194,10 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb
+ #endif
+
+ /*
+- * The cred blob is a pointer to, not an instance of, an aa_task_ctx.
++ * The cred blob is a pointer to, not an instance of, an aa_label.
+ */
+ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+- .lbs_cred = sizeof(struct aa_task_ctx *),
++ .lbs_cred = sizeof(struct aa_label *),
+ .lbs_file = sizeof(struct aa_file_ctx),
+ .lbs_task = sizeof(struct aa_task_ctx),
+ };
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index 499c0209b6a46..fbdfcef91c616 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -1170,7 +1170,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
+
+ if (!name) {
+ /* remove namespace - can only happen if fqname[0] == ':' */
+- mutex_lock_nested(&ns->parent->lock, ns->level);
++ mutex_lock_nested(&ns->parent->lock, ns->parent->level);
+ __aa_bump_ns_revision(ns);
+ __aa_remove_ns(ns);
+ mutex_unlock(&ns->parent->lock);
+diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
+index 43beaad083feb..78700d94b4533 100644
+--- a/security/apparmor/policy_ns.c
++++ b/security/apparmor/policy_ns.c
+@@ -134,7 +134,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
+ return ns;
+
+ fail_unconfined:
+- kfree_sensitive(ns->base.hname);
++ aa_policy_destroy(&ns->base);
+ fail_ns:
+ kfree_sensitive(ns);
+ return NULL;
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 55d31bac4f35b..9d26bbb901338 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -972,7 +972,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
+ * if not specified use previous version
+ * Mask off everything that is not kernel abi version
+ */
+- if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
++ if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v8)) {
+ audit_iface(NULL, NULL, NULL, "unsupported interface version",
+ e, error);
+ return error;
+diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
+index 8a82a6c7f48a4..f2193c531f4a4 100644
+--- a/security/integrity/digsig.c
++++ b/security/integrity/digsig.c
+@@ -126,6 +126,7 @@ int __init integrity_init_keyring(const unsigned int id)
+ {
+ struct key_restriction *restriction;
+ key_perm_t perm;
++ int ret;
+
+ perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
+ | KEY_USR_READ | KEY_USR_SEARCH;
+@@ -154,7 +155,10 @@ int __init integrity_init_keyring(const unsigned int id)
+ perm |= KEY_USR_WRITE;
+
+ out:
+- return __integrity_init_keyring(id, perm, restriction);
++ ret = __integrity_init_keyring(id, perm, restriction);
++ if (ret)
++ kfree(restriction);
++ return ret;
+ }
+
+ static int __init integrity_add_key(const unsigned int id, const void *data,
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index a8802b8da946b..2edff7f58c25c 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -398,12 +398,6 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
+
+ nentry->lsm[i].type = entry->lsm[i].type;
+ nentry->lsm[i].args_p = entry->lsm[i].args_p;
+- /*
+- * Remove the reference from entry so that the associated
+- * memory will not be freed during a later call to
+- * ima_lsm_free_rule(entry).
+- */
+- entry->lsm[i].args_p = NULL;
+
+ ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
+ nentry->lsm[i].args_p,
+@@ -417,6 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
+
+ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
+ {
++ int i;
+ struct ima_rule_entry *nentry;
+
+ nentry = ima_lsm_copy_rule(entry);
+@@ -431,7 +426,8 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
+ * references and the entry itself. All other memory references will now
+ * be owned by nentry.
+ */
+- ima_lsm_free_rule(entry);
++ for (i = 0; i < MAX_LSM_RULES; i++)
++ ima_filter_rule_free(entry->lsm[i].rule);
+ kfree(entry);
+
+ return 0;
+@@ -549,6 +545,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ const char *func_data)
+ {
+ int i;
++ bool result = false;
++ struct ima_rule_entry *lsm_rule = rule;
++ bool rule_reinitialized = false;
+
+ if ((rule->flags & IMA_FUNC) &&
+ (rule->func != func && func != POST_SETATTR))
+@@ -610,35 +609,55 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ int rc = 0;
+ u32 osid;
+
+- if (!rule->lsm[i].rule) {
+- if (!rule->lsm[i].args_p)
++ if (!lsm_rule->lsm[i].rule) {
++ if (!lsm_rule->lsm[i].args_p)
+ continue;
+ else
+ return false;
+ }
++
++retry:
+ switch (i) {
+ case LSM_OBJ_USER:
+ case LSM_OBJ_ROLE:
+ case LSM_OBJ_TYPE:
+ security_inode_getsecid(inode, &osid);
+- rc = ima_filter_rule_match(osid, rule->lsm[i].type,
++ rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
+ Audit_equal,
+- rule->lsm[i].rule);
++ lsm_rule->lsm[i].rule);
+ break;
+ case LSM_SUBJ_USER:
+ case LSM_SUBJ_ROLE:
+ case LSM_SUBJ_TYPE:
+- rc = ima_filter_rule_match(secid, rule->lsm[i].type,
++ rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
+ Audit_equal,
+- rule->lsm[i].rule);
++ lsm_rule->lsm[i].rule);
+ break;
+ default:
+ break;
+ }
+- if (!rc)
+- return false;
++
++ if (rc == -ESTALE && !rule_reinitialized) {
++ lsm_rule = ima_lsm_copy_rule(rule);
++ if (lsm_rule) {
++ rule_reinitialized = true;
++ goto retry;
++ }
++ }
++ if (!rc) {
++ result = false;
++ goto out;
++ }
+ }
+- return true;
++ result = true;
++
++out:
++ if (rule_reinitialized) {
++ for (i = 0; i < MAX_LSM_RULES; i++)
++ ima_filter_rule_free(lsm_rule->lsm[i].rule);
++ kfree(lsm_rule);
++ }
++ return result;
+ }
+
+ /*
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index c25079faa2088..195ac18f09275 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -245,11 +245,11 @@ int template_desc_init_fields(const char *template_fmt,
+ }
+
+ if (fields && num_fields) {
+- *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
++ *fields = kmalloc_array(i, sizeof(**fields), GFP_KERNEL);
+ if (*fields == NULL)
+ return -ENOMEM;
+
+- memcpy(*fields, found_fields, i * sizeof(*fields));
++ memcpy(*fields, found_fields, i * sizeof(**fields));
+ *num_fields = i;
+ }
+
+diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
+index 44521582dcba2..d6767fddbd5a2 100644
+--- a/security/loadpin/loadpin.c
++++ b/security/loadpin/loadpin.c
+@@ -120,21 +120,11 @@ static void loadpin_sb_free_security(struct super_block *mnt_sb)
+ }
+ }
+
+-static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+- bool contents)
++static int loadpin_check(struct file *file, enum kernel_read_file_id id)
+ {
+ struct super_block *load_root;
+ const char *origin = kernel_read_file_id_str(id);
+
+- /*
+- * If we will not know that we'll be seeing the full contents
+- * then we cannot trust a load will be complete and unchanged
+- * off disk. Treat all contents=false hooks as if there were
+- * no associated file struct.
+- */
+- if (!contents)
+- file = NULL;
+-
+ /* If the file id is excluded, ignore the pinning. */
+ if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) &&
+ ignore_read_file_id[id]) {
+@@ -190,9 +180,25 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+ return 0;
+ }
+
++static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
++ bool contents)
++{
++ /*
++ * LoadPin only cares about the _origin_ of a file, not its
++ * contents, so we can ignore the "are full contents available"
++ * argument here.
++ */
++ return loadpin_check(file, id);
++}
++
+ static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
+ {
+- return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents);
++ /*
++ * LoadPin only cares about the _origin_ of a file, not its
++ * contents, so a NULL file is passed, and we can ignore the
++ * state of "contents".
++ */
++ return loadpin_check(NULL, (enum kernel_read_file_id) id);
+ }
+
+ static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index ad0541e9e8880..ac985cec5c165 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -1432,8 +1432,10 @@ static int snd_pcm_do_start(struct snd_pcm_substream *substream,
+ static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
+ snd_pcm_state_t state)
+ {
+- if (substream->runtime->trigger_master == substream)
++ if (substream->runtime->trigger_master == substream) {
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
++ substream->runtime->stop_operating = true;
++ }
+ }
+
+ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
+diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
+index d3bc9e8c407dc..f0d34cf70c3e0 100644
+--- a/sound/drivers/mts64.c
++++ b/sound/drivers/mts64.c
+@@ -815,6 +815,9 @@ static void snd_mts64_interrupt(void *private)
+ u8 status, data;
+ struct snd_rawmidi_substream *substream;
+
++ if (!mts)
++ return;
++
+ spin_lock(&mts->lock);
+ ret = mts64_read(mts->pardev->port);
+ data = ret & 0x00ff;
+diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
+index f3582012d22f3..eea22cf72aefd 100644
+--- a/sound/hda/hdac_stream.c
++++ b/sound/hda/hdac_stream.c
+@@ -142,17 +142,28 @@ void snd_hdac_stream_stop(struct hdac_stream *azx_dev)
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_stream_stop);
+
++/**
++ * snd_hdac_stop_streams - stop all streams
++ * @bus: HD-audio core bus
++ */
++void snd_hdac_stop_streams(struct hdac_bus *bus)
++{
++ struct hdac_stream *stream;
++
++ list_for_each_entry(stream, &bus->stream_list, list)
++ snd_hdac_stream_stop(stream);
++}
++EXPORT_SYMBOL_GPL(snd_hdac_stop_streams);
++
+ /**
+ * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
+ * @bus: HD-audio core bus
+ */
+ void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
+ {
+- struct hdac_stream *stream;
+
+ if (bus->chip_init) {
+- list_for_each_entry(stream, &bus->stream_list, list)
+- snd_hdac_stream_stop(stream);
++ snd_hdac_stop_streams(bus);
+ snd_hdac_bus_stop_chip(bus);
+ }
+ }
+diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
+index bb31b7fe867d6..477a5b4b50bcb 100644
+--- a/sound/pci/asihpi/hpioctl.c
++++ b/sound/pci/asihpi/hpioctl.c
+@@ -361,7 +361,7 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev,
+ pci_dev->device, pci_dev->subsystem_vendor,
+ pci_dev->subsystem_device, pci_dev->devfn);
+
+- if (pci_enable_device(pci_dev) < 0) {
++ if (pcim_enable_device(pci_dev) < 0) {
+ dev_err(&pci_dev->dev,
+ "pci_enable_device failed, disabling device\n");
+ return -EIO;
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 384426d7e9ddc..c853cba7fc2bf 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2893,7 +2893,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
+ snd_hdac_enter_pm(&codec->core);
+ if (codec->patch_ops.suspend)
+ codec->patch_ops.suspend(codec);
+- hda_cleanup_all_streams(codec);
++ if (!codec->no_stream_clean_at_suspend)
++ hda_cleanup_all_streams(codec);
+ state = hda_set_power_state(codec, AC_PWRST_D3);
+ update_power_acct(codec, true);
+ snd_hdac_leave_pm(&codec->core);
+diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
+index 75dcb14ff20ad..0ff286b7b66be 100644
+--- a/sound/pci/hda/hda_controller.c
++++ b/sound/pci/hda/hda_controller.c
+@@ -1033,10 +1033,8 @@ EXPORT_SYMBOL_GPL(azx_init_chip);
+ void azx_stop_all_streams(struct azx *chip)
+ {
+ struct hdac_bus *bus = azx_bus(chip);
+- struct hdac_stream *s;
+
+- list_for_each_entry(s, &bus->stream_list, list)
+- snd_hdac_stream_stop(s);
++ snd_hdac_stop_streams(bus);
+ }
+ EXPORT_SYMBOL_GPL(azx_stop_all_streams);
+
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 287f4f78e7b1e..913509b29f938 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -167,8 +167,6 @@ struct hdmi_spec {
+ struct hdmi_ops ops;
+
+ bool dyn_pin_out;
+- bool dyn_pcm_assign;
+- bool dyn_pcm_no_legacy;
+ /* hdmi interrupt trigger control flag for Nvidia codec */
+ bool hdmi_intr_trig_ctrl;
+ bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+@@ -1187,9 +1185,7 @@ static void pin_cvt_fixup(struct hda_codec *codec,
+ spec->ops.pin_cvt_fixup(codec, per_pin, cvt_nid);
+ }
+
+-/* called in hdmi_pcm_open when no pin is assigned to the PCM
+- * in dyn_pcm_assign mode.
+- */
++/* called in hdmi_pcm_open when no pin is assigned to the PCM */
+ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+@@ -1257,19 +1253,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+
+ mutex_lock(&spec->pcm_lock);
+ pin_idx = hinfo_to_pin_index(codec, hinfo);
+- if (!spec->dyn_pcm_assign) {
+- if (snd_BUG_ON(pin_idx < 0)) {
+- err = -EINVAL;
+- goto unlock;
+- }
+- } else {
+- /* no pin is assigned to the PCM
+- * PA need pcm open successfully when probe
+- */
+- if (pin_idx < 0) {
+- err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
+- goto unlock;
+- }
++ /* no pin is assigned to the PCM
++ * PA need pcm open successfully when probe
++ */
++ if (pin_idx < 0) {
++ err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
++ goto unlock;
+ }
+
+ err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false);
+@@ -1374,43 +1363,6 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
+ {
+ int i;
+
+- /* on the new machines, try to assign the pcm slot dynamically,
+- * not use the preferred fixed map (legacy way) anymore.
+- */
+- if (spec->dyn_pcm_no_legacy)
+- goto last_try;
+-
+- /*
+- * generic_hdmi_build_pcms() may allocate extra PCMs on some
+- * platforms (with maximum of 'num_nids + dev_num - 1')
+- *
+- * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
+- * if m==0. This guarantees that dynamic pcm assignments are compatible
+- * with the legacy static per_pin-pcm assignment that existed in the
+- * days before DP-MST.
+- *
+- * Intel DP-MST prefers this legacy behavior for compatibility, too.
+- *
+- * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
+- */
+-
+- if (per_pin->dev_id == 0 || spec->intel_hsw_fixup) {
+- if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
+- return per_pin->pin_nid_idx;
+- } else {
+- i = spec->num_nids + (per_pin->dev_id - 1);
+- if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
+- return i;
+- }
+-
+- /* have a second try; check the area over num_nids */
+- for (i = spec->num_nids; i < spec->pcm_used; i++) {
+- if (!test_bit(i, &spec->pcm_bitmap))
+- return i;
+- }
+-
+- last_try:
+- /* the last try; check the empty slots in pins */
+ for (i = 0; i < spec->pcm_used; i++) {
+ if (!test_bit(i, &spec->pcm_bitmap))
+ return i;
+@@ -1573,14 +1525,12 @@ static void update_eld(struct hda_codec *codec,
+ */
+ pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+
+- if (spec->dyn_pcm_assign) {
+- if (eld->eld_valid) {
+- hdmi_attach_hda_pcm(spec, per_pin);
+- hdmi_pcm_setup_pin(spec, per_pin);
+- } else {
+- hdmi_pcm_reset_pin(spec, per_pin);
+- hdmi_detach_hda_pcm(spec, per_pin);
+- }
++ if (eld->eld_valid) {
++ hdmi_attach_hda_pcm(spec, per_pin);
++ hdmi_pcm_setup_pin(spec, per_pin);
++ } else {
++ hdmi_pcm_reset_pin(spec, per_pin);
++ hdmi_detach_hda_pcm(spec, per_pin);
+ }
+ /* if pcm_idx == -1, it means this is in monitor connection event
+ * we can get the correct pcm_idx now.
+@@ -1788,6 +1738,7 @@ static void silent_stream_enable(struct hda_codec *codec,
+
+ switch (spec->silent_stream_type) {
+ case SILENT_STREAM_KAE:
++ silent_stream_enable_i915(codec, per_pin);
+ silent_stream_set_kae(codec, per_pin, true);
+ break;
+ case SILENT_STREAM_I915:
+@@ -1942,7 +1893,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ * structures based on worst case.
+ */
+ dev_num = spec->dev_num;
+- } else if (spec->dyn_pcm_assign && codec->dp_mst) {
++ } else if (codec->dp_mst) {
+ dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1;
+ /*
+ * spec->dev_num is the maxinum number of device entries
+@@ -1967,13 +1918,8 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ if (!per_pin)
+ return -ENOMEM;
+
+- if (spec->dyn_pcm_assign) {
+- per_pin->pcm = NULL;
+- per_pin->pcm_idx = -1;
+- } else {
+- per_pin->pcm = get_hdmi_pcm(spec, pin_idx);
+- per_pin->pcm_idx = pin_idx;
+- }
++ per_pin->pcm = NULL;
++ per_pin->pcm_idx = -1;
+ per_pin->pin_nid = pin_nid;
+ per_pin->pin_nid_idx = spec->num_nids;
+ per_pin->dev_id = i;
+@@ -1982,6 +1928,8 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ err = hdmi_read_pin_conn(codec, pin_idx);
+ if (err < 0)
+ return err;
++ if (!is_jack_detectable(codec, pin_nid))
++ codec_warn(codec, "HDMI: pin NID 0x%x - jack not detectable\n", pin_nid);
+ spec->num_pins++;
+ }
+ spec->num_nids++;
+@@ -2028,6 +1976,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
+ static const struct snd_pci_quirk force_connect_list[] = {
+ SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
+ SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
++ SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1),
+ SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1),
+ SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1),
+ {}
+@@ -2129,10 +2078,9 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+
+ mutex_lock(&spec->pcm_lock);
+ pin_idx = hinfo_to_pin_index(codec, hinfo);
+- if (spec->dyn_pcm_assign && pin_idx < 0) {
+- /* when dyn_pcm_assign and pcm is not bound to a pin
+- * skip pin setup and return 0 to make audio playback
+- * be ongoing
++ if (pin_idx < 0) {
++ /* when pcm is not bound to a pin skip pin setup and return 0
++ * to make audio playback be ongoing
+ */
+ pin_cvt_fixup(codec, NULL, cvt_nid);
+ snd_hda_codec_setup_stream(codec, cvt_nid,
+@@ -2235,7 +2183,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+ clear_bit(pcm_idx, &spec->pcm_in_use);
+ pin_idx = hinfo_to_pin_index(codec, hinfo);
+- if (spec->dyn_pcm_assign && pin_idx < 0)
++ if (pin_idx < 0)
+ goto unlock;
+
+ if (snd_BUG_ON(pin_idx < 0)) {
+@@ -2333,21 +2281,8 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+ struct hdmi_spec *spec = codec->spec;
+ int idx, pcm_num;
+
+- /*
+- * for non-mst mode, pcm number is the same as before
+- * for DP MST mode without extra PCM, pcm number is same
+- * for DP MST mode with extra PCMs, pcm number is
+- * (nid number + dev_num - 1)
+- * dev_num is the device entry number in a pin
+- */
+-
+- if (spec->dyn_pcm_no_legacy && codec->mst_no_extra_pcms)
+- pcm_num = spec->num_cvts;
+- else if (codec->mst_no_extra_pcms)
+- pcm_num = spec->num_nids;
+- else
+- pcm_num = spec->num_nids + spec->dev_num - 1;
+-
++ /* limit the PCM devices to the codec converters */
++ pcm_num = spec->num_cvts;
+ codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+
+ for (idx = 0; idx < pcm_num; idx++) {
+@@ -2386,17 +2321,12 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
+ {
+ char hdmi_str[32] = "HDMI/DP";
+ struct hdmi_spec *spec = codec->spec;
+- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pcm_idx);
+ struct snd_jack *jack;
+ int pcmdev = get_pcm_rec(spec, pcm_idx)->device;
+ int err;
+
+ if (pcmdev > 0)
+ sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
+- if (!spec->dyn_pcm_assign &&
+- !is_jack_detectable(codec, per_pin->pin_nid))
+- strncat(hdmi_str, " Phantom",
+- sizeof(hdmi_str) - strlen(hdmi_str) - 1);
+
+ err = snd_jack_new(codec->card, hdmi_str, SND_JACK_AVOUT, &jack,
+ true, false);
+@@ -2429,18 +2359,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
+ /* create the spdif for each pcm
+ * pin will be bound when monitor is connected
+ */
+- if (spec->dyn_pcm_assign)
+- err = snd_hda_create_dig_out_ctls(codec,
++ err = snd_hda_create_dig_out_ctls(codec,
+ 0, spec->cvt_nids[0],
+ HDA_PCM_TYPE_HDMI);
+- else {
+- struct hdmi_spec_per_pin *per_pin =
+- get_pin(spec, pcm_idx);
+- err = snd_hda_create_dig_out_ctls(codec,
+- per_pin->pin_nid,
+- per_pin->mux_nids[0],
+- HDA_PCM_TYPE_HDMI);
+- }
+ if (err < 0)
+ return err;
+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+@@ -2560,11 +2481,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
+ for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
+ if (spec->pcm_rec[pcm_idx].jack == NULL)
+ continue;
+- if (spec->dyn_pcm_assign)
+- snd_device_free(codec->card,
+- spec->pcm_rec[pcm_idx].jack);
+- else
+- spec->pcm_rec[pcm_idx].jack = NULL;
++ snd_device_free(codec->card, spec->pcm_rec[pcm_idx].jack);
+ }
+
+ generic_spec_free(codec);
+@@ -2963,9 +2880,33 @@ static int i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
+ hda_nid_t pin_nid, int dev_id, u32 stream_tag,
+ int format)
+ {
++ struct hdmi_spec *spec = codec->spec;
++ int pin_idx = pin_id_to_pin_index(codec, pin_nid, dev_id);
++ struct hdmi_spec_per_pin *per_pin;
++ int res;
++
++ if (pin_idx < 0)
++ per_pin = NULL;
++ else
++ per_pin = get_pin(spec, pin_idx);
++
+ haswell_verify_D0(codec, cvt_nid, pin_nid);
+- return hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
+- stream_tag, format);
++
++ if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
++ silent_stream_set_kae(codec, per_pin, false);
++ /* wait for pending transfers in codec to clear */
++ usleep_range(100, 200);
++ }
++
++ res = hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
++ stream_tag, format);
++
++ if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
++ usleep_range(100, 200);
++ silent_stream_set_kae(codec, per_pin, true);
++ }
++
++ return res;
+ }
+
+ /* pin_cvt_fixup ops override for HSW+ and VLV+ */
+@@ -2985,6 +2926,88 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
+ }
+ }
+
++#ifdef CONFIG_PM
++static int i915_adlp_hdmi_suspend(struct hda_codec *codec)
++{
++ struct hdmi_spec *spec = codec->spec;
++ bool silent_streams = false;
++ int pin_idx, res;
++
++ res = generic_hdmi_suspend(codec);
++
++ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
++ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
++
++ if (per_pin->silent_stream) {
++ silent_streams = true;
++ break;
++ }
++ }
++
++ if (silent_streams && spec->silent_stream_type == SILENT_STREAM_KAE) {
++ /*
++ * stream-id should remain programmed when codec goes
++ * to runtime suspend
++ */
++ codec->no_stream_clean_at_suspend = 1;
++
++ /*
++ * the system might go to S3, in which case keep-alive
++ * must be reprogrammed upon resume
++ */
++ codec->forced_resume = 1;
++
++ codec_dbg(codec, "HDMI: KAE active at suspend\n");
++ } else {
++ codec->no_stream_clean_at_suspend = 0;
++ codec->forced_resume = 0;
++ }
++
++ return res;
++}
++
++static int i915_adlp_hdmi_resume(struct hda_codec *codec)
++{
++ struct hdmi_spec *spec = codec->spec;
++ int pin_idx, res;
++
++ res = generic_hdmi_resume(codec);
++
++ /* KAE not programmed at suspend, nothing to do here */
++ if (!codec->no_stream_clean_at_suspend)
++ return res;
++
++ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
++ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
++
++ /*
++ * If system was in suspend with monitor connected,
++ * the codec setting may have been lost. Re-enable
++ * keep-alive.
++ */
++ if (per_pin->silent_stream) {
++ unsigned int param;
++
++ param = snd_hda_codec_read(codec, per_pin->cvt_nid, 0,
++ AC_VERB_GET_CONV, 0);
++ if (!param) {
++ codec_dbg(codec, "HDMI: KAE: restore stream id\n");
++ silent_stream_enable_i915(codec, per_pin);
++ }
++
++ param = snd_hda_codec_read(codec, per_pin->cvt_nid, 0,
++ AC_VERB_GET_DIGI_CONVERT_1, 0);
++ if (!(param & (AC_DIG3_KAE << 16))) {
++ codec_dbg(codec, "HDMI: KAE: restore DIG3_KAE\n");
++ silent_stream_set_kae(codec, per_pin, true);
++ }
++ }
++ }
++
++ return res;
++}
++#endif
++
+ /* precondition and allocation for Intel codecs */
+ static int alloc_intel_hdmi(struct hda_codec *codec)
+ {
+@@ -3038,7 +3061,6 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
+ return err;
+ spec = codec->spec;
+ codec->dp_mst = true;
+- spec->dyn_pcm_assign = true;
+ spec->vendor_nid = vendor_nid;
+ spec->port_map = port_map;
+ spec->port_num = port_num;
+@@ -3102,17 +3124,9 @@ static int patch_i915_tgl_hdmi(struct hda_codec *codec)
+ * the index indicate the port number.
+ */
+ static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+- int ret;
+-
+- ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4,
+- enable_silent_stream);
+- if (!ret) {
+- struct hdmi_spec *spec = codec->spec;
+
+- spec->dyn_pcm_no_legacy = true;
+- }
+-
+- return ret;
++ return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4,
++ enable_silent_stream);
+ }
+
+ static int patch_i915_adlp_hdmi(struct hda_codec *codec)
+@@ -3124,8 +3138,14 @@ static int patch_i915_adlp_hdmi(struct hda_codec *codec)
+ if (!res) {
+ spec = codec->spec;
+
+- if (spec->silent_stream_type)
++ if (spec->silent_stream_type) {
+ spec->silent_stream_type = SILENT_STREAM_KAE;
++
++#ifdef CONFIG_PM
++ codec->patch_ops.resume = i915_adlp_hdmi_resume;
++ codec->patch_ops.suspend = i915_adlp_hdmi_suspend;
++#endif
++ }
+ }
+
+ return res;
+@@ -3752,7 +3772,6 @@ static int patch_nvhdmi(struct hda_codec *codec)
+ codec->dp_mst = true;
+
+ spec = codec->spec;
+- spec->dyn_pcm_assign = true;
+
+ err = hdmi_parse_codec(codec);
+ if (err < 0) {
+@@ -4032,10 +4051,8 @@ static int patch_tegra234_hdmi(struct hda_codec *codec)
+ return err;
+
+ codec->dp_mst = true;
+- codec->mst_no_extra_pcms = true;
+ spec = codec->spec;
+ spec->dyn_pin_out = true;
+- spec->dyn_pcm_assign = true;
+ spec->hdmi_intr_trig_ctrl = true;
+
+ return tegra_hdmi_init(codec);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ce6ea8819562b..94fe842178947 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10984,6 +10984,17 @@ static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
+ }
+ }
+
++static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ struct alc_spec *spec = codec->spec;
++
++ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++ spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
++ spec->gen.hp_automute_hook = alc897_hp_automute_hook;
++ }
++}
++
+ static const struct coef_fw alc668_coefs[] = {
+ WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
+ WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -11067,6 +11078,8 @@ enum {
+ ALC897_FIXUP_LENOVO_HEADSET_MIC,
+ ALC897_FIXUP_HEADSET_MIC_PIN,
+ ALC897_FIXUP_HP_HSMIC_VERB,
++ ALC897_FIXUP_LENOVO_HEADSET_MODE,
++ ALC897_FIXUP_HEADSET_MIC_PIN2,
+ };
+
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -11493,6 +11506,19 @@ static const struct hda_fixup alc662_fixups[] = {
+ { }
+ },
+ },
++ [ALC897_FIXUP_LENOVO_HEADSET_MODE] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc897_fixup_lenovo_headset_mode,
++ },
++ [ALC897_FIXUP_HEADSET_MIC_PIN2] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
++ },
+ };
+
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -11545,6 +11571,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
++ SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
+ SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
+ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+ SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index d9715bea965e1..1f0b5527c5949 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -213,6 +213,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
++ }
++ },
+ {}
+ };
+
+diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c
+index ad20a3dff9b7e..61e8e9be6b8d7 100644
+--- a/sound/soc/codecs/hda.c
++++ b/sound/soc/codecs/hda.c
+@@ -224,9 +224,6 @@ static int hda_codec_probe(struct snd_soc_component *component)
+ goto err;
+ }
+
+- /* configure codec for 1:1 PCM:DAI mapping */
+- codec->mst_no_extra_pcms = 1;
+-
+ ret = snd_hda_codec_parse_pcms(codec);
+ if (ret < 0) {
+ dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
+diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
+index 8debcee592247..7876bdd558a7a 100644
+--- a/sound/soc/codecs/hdac_hda.c
++++ b/sound/soc/codecs/hdac_hda.c
+@@ -461,9 +461,6 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component)
+ dev_dbg(&hdev->dev, "no patch file found\n");
+ }
+
+- /* configure codec for 1:1 PCM:DAI mapping */
+- hcodec->mst_no_extra_pcms = 1;
+-
+ ret = snd_hda_codec_parse_pcms(hcodec);
+ if (ret < 0) {
+ dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
+diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
+index 767463e82665c..89059a673cf09 100644
+--- a/sound/soc/codecs/pcm512x.c
++++ b/sound/soc/codecs/pcm512x.c
+@@ -1634,7 +1634,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ if (val > 6) {
+ dev_err(dev, "Invalid pll-in\n");
+ ret = -EINVAL;
+- goto err_clk;
++ goto err_pm;
+ }
+ pcm512x->pll_in = val;
+ }
+@@ -1643,7 +1643,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ if (val > 6) {
+ dev_err(dev, "Invalid pll-out\n");
+ ret = -EINVAL;
+- goto err_clk;
++ goto err_pm;
+ }
+ pcm512x->pll_out = val;
+ }
+@@ -1652,12 +1652,12 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ dev_err(dev,
+ "Error: both pll-in and pll-out, or none\n");
+ ret = -EINVAL;
+- goto err_clk;
++ goto err_pm;
+ }
+ if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) {
+ dev_err(dev, "Error: pll-in == pll-out\n");
+ ret = -EINVAL;
+- goto err_clk;
++ goto err_pm;
+ }
+ }
+ #endif
+diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
+index b0b53d4f07df9..5f36064ed6e6f 100644
+--- a/sound/soc/codecs/rt298.c
++++ b/sound/soc/codecs/rt298.c
+@@ -1166,6 +1166,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
+ }
+ },
++ {
++ .ident = "Intel Kabylake R RVP",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
++ }
++ },
+ { }
+ };
+
+diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
+index 60dbfa2a54f1b..c75045e371b20 100644
+--- a/sound/soc/codecs/rt5670.c
++++ b/sound/soc/codecs/rt5670.c
+@@ -3311,8 +3311,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c)
+ if (ret < 0)
+ goto err;
+
+- pm_runtime_put(&i2c->dev);
+-
+ return 0;
+ err:
+ pm_runtime_disable(&i2c->dev);
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
+index d3cfd3788f2ab..8fe9a75d12357 100644
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -3853,7 +3853,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
+ } else {
+ dev_dbg(component->dev, "Jack not detected\n");
+
++ /* Release wm8994->accdet_lock to avoid deadlock:
++ * cancel_delayed_work_sync() takes wm8994->mic_work internal
++ * lock and wm1811_mic_work takes wm8994->accdet_lock */
++ mutex_unlock(&wm8994->accdet_lock);
+ cancel_delayed_work_sync(&wm8994->mic_work);
++ mutex_lock(&wm8994->accdet_lock);
+
+ snd_soc_component_update_bits(component, WM8958_MICBIAS2,
+ WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
+diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
+index 63e1d7aa61379..9dfa0ac08e6f0 100644
+--- a/sound/soc/codecs/wsa883x.c
++++ b/sound/soc/codecs/wsa883x.c
+@@ -7,7 +7,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -1393,7 +1393,7 @@ static int wsa883x_probe(struct sdw_slave *pdev,
+ }
+
+ wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown",
+- GPIOD_FLAGS_BIT_NONEXCLUSIVE);
++ GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH);
+ if (IS_ERR(wsa883x->sd_n)) {
+ dev_err(&pdev->dev, "Shutdown Control GPIO not found\n");
+ ret = PTR_ERR(wsa883x->sd_n);
+@@ -1411,7 +1411,7 @@ static int wsa883x_probe(struct sdw_slave *pdev,
+ pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0);
+ pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
+ pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+- gpiod_direction_output(wsa883x->sd_n, 1);
++ gpiod_direction_output(wsa883x->sd_n, 0);
+
+ wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config);
+ if (IS_ERR(wsa883x->regmap)) {
+diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
+index b327372f2e4ae..4e776c2a38a4c 100644
+--- a/sound/soc/generic/audio-graph-card.c
++++ b/sound/soc/generic/audio-graph-card.c
+@@ -485,8 +485,10 @@ static int __graph_for_each_link(struct asoc_simple_priv *priv,
+ of_node_put(codec_ep);
+ of_node_put(codec_port);
+
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(cpu_ep);
+ return ret;
++ }
+
+ codec_port_old = codec_port;
+ }
+diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c
+index b28d36872dcba..58c9d9edecf0a 100644
+--- a/sound/soc/intel/avs/boards/rt298.c
++++ b/sound/soc/intel/avs/boards/rt298.c
+@@ -6,6 +6,7 @@
+ // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ //
+
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <sound/jack.h>
+ #include <sound/pcm.h>
+@@ -14,6 +15,16 @@
+ #include <sound/soc-acpi.h>
+ #include "../../../codecs/rt298.h"
+
++static const struct dmi_system_id kblr_dmi_table[] = {
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"),
++ },
++ },
++ {}
++};
++
+ static const struct snd_kcontrol_new card_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Mic Jack"),
+@@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param
+ {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
++ unsigned int clk_freq;
+ int ret;
+
+- ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN);
++ if (dmi_first_match(kblr_dmi_table))
++ clk_freq = 24000000;
++ else
++ clk_freq = 19200000;
++
++ ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret);
+
+@@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
+ dl->platforms = platform;
+ dl->num_platforms = 1;
+ dl->id = 0;
+- dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
++ if (dmi_first_match(kblr_dmi_table))
++ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
++ else
++ dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->init = avs_rt298_codec_init;
+ dl->be_hw_params_fixup = avs_rt298_be_fixup;
+ dl->ops = &avs_rt298_ops;
+diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
+index c50c20fd681a1..58db133741662 100644
+--- a/sound/soc/intel/avs/core.c
++++ b/sound/soc/intel/avs/core.c
+@@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+ if (bus->mlcap)
+ snd_hdac_ext_bus_get_ml_capabilities(bus);
+
+- if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
++ if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ dma_set_max_seg_size(dev, UINT_MAX);
+
+diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
+index 020d85c7520de..306f0dc4eaf58 100644
+--- a/sound/soc/intel/avs/ipc.c
++++ b/sound/soc/intel/avs/ipc.c
+@@ -123,7 +123,10 @@ static void avs_dsp_recovery(struct avs_dev *adev)
+ if (!substream || !substream->runtime)
+ continue;
+
++ /* No need for _irq() as we are in nonatomic context. */
++ snd_pcm_stream_lock(substream);
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
++ snd_pcm_stream_unlock(substream);
+ }
+ }
+ }
+@@ -192,7 +195,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header)
+ /* update size in case of LARGE_CONFIG_GET */
+ if (msg.msg_target == AVS_MOD_MSG &&
+ msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET)
+- ipc->rx.size = msg.ext.large_config.data_off_size;
++ ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE,
++ msg.ext.large_config.data_off_size);
+
+ memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size);
+ trace_avs_msg_payload(ipc->rx.data, ipc->rx.size);
+diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
+index 5c218a39ca201..57adcefce043e 100644
+--- a/sound/soc/intel/boards/sof_es8336.c
++++ b/sound/soc/intel/boards/sof_es8336.c
+@@ -782,7 +782,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+
+- cancel_delayed_work(&priv->pcm_pop_work);
++ cancel_delayed_work_sync(&priv->pcm_pop_work);
+ gpiod_put(priv->gpio_speakers);
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
+diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
+index aeca58246fc77..77cd7d3e9409b 100644
+--- a/sound/soc/intel/skylake/skl.c
++++ b/sound/soc/intel/skylake/skl.c
+@@ -1097,7 +1097,10 @@ static void skl_shutdown(struct pci_dev *pci)
+ if (!skl->init_done)
+ return;
+
+- snd_hdac_stop_streams_and_chip(bus);
++ snd_hdac_stop_streams(bus);
++ snd_hdac_ext_bus_link_power_down_all(bus);
++ skl_dsp_sleep(skl->dsp);
++
+ list_for_each_entry(s, &bus->stream_list, list) {
+ stream = stream_to_hdac_ext_stream(s);
+ snd_hdac_ext_stream_decouple(bus, stream, false);
+diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
+index d884bb7c0fc74..1c28b41e43112 100644
+--- a/sound/soc/mediatek/common/mtk-btcvsd.c
++++ b/sound/soc/mediatek/common/mtk-btcvsd.c
+@@ -1038,11 +1038,9 @@ static int mtk_pcm_btcvsd_copy(struct snd_soc_component *component,
+ struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(component);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- mtk_btcvsd_snd_write(bt, buf, count);
++ return mtk_btcvsd_snd_write(bt, buf, count);
+ else
+- mtk_btcvsd_snd_read(bt, buf, count);
+-
+- return 0;
++ return mtk_btcvsd_snd_read(bt, buf, count);
+ }
+
+ /* kcontrol */
+diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+index dcaeeeb8aac70..bc155dd937e0b 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+@@ -1070,16 +1070,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+
+ afe->dev = &pdev->dev;
+
+- irq_id = platform_get_irq(pdev, 0);
+- if (irq_id <= 0)
+- return irq_id < 0 ? irq_id : -ENXIO;
+- ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
+- 0, "Afe_ISR_Handle", (void *)afe);
+- if (ret) {
+- dev_err(afe->dev, "could not request_irq\n");
+- return ret;
+- }
+-
+ afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(afe->base_addr))
+ return PTR_ERR(afe->base_addr);
+@@ -1185,6 +1175,16 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+ if (ret)
+ goto err_cleanup_components;
+
++ irq_id = platform_get_irq(pdev, 0);
++ if (irq_id <= 0)
++ return irq_id < 0 ? irq_id : -ENXIO;
++ ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
++ 0, "Afe_ISR_Handle", (void *)afe);
++ if (ret) {
++ dev_err(afe->dev, "could not request_irq\n");
++ goto err_pm_disable;
++ }
++
+ dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
+ return 0;
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+index 12f40c81b101e..f803f121659de 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+@@ -200,14 +200,16 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
+ if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto out;
+ }
+ mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+ of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
+ if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto out;
+ }
+ mt8173_rt5650_rt5514_codec_conf[0].dlc.of_node =
+ mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
+@@ -216,6 +218,7 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+
++out:
+ of_node_put(platform_node);
+ return ret;
+ }
+diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+index ab157db783350..cfb463f44af79 100644
+--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
++++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+@@ -644,8 +644,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ }
+
+ card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
+- if (!card)
++ if (!card) {
++ of_node_put(platform_node);
+ return -EINVAL;
++ }
+ card->dev = &pdev->dev;
+
+ ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0);
+@@ -734,8 +736,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
++ if (!priv) {
++ ret = -ENOMEM;
++ goto out;
++ }
+
+ snd_soc_card_set_drvdata(card, priv);
+
+@@ -743,7 +747,8 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->pinctrl)) {
+ dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
+ __func__);
+- return PTR_ERR(priv->pinctrl);
++ ret = PTR_ERR(priv->pinctrl);
++ goto out;
+ }
+
+ for (i = 0; i < PIN_STATE_MAX; i++) {
+@@ -776,6 +781,7 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+
++out:
+ of_node_put(platform_node);
+ of_node_put(ec_codec);
+ of_node_put(hdmi_codec);
+diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
+index 5d520e18e512f..99b245e3079a2 100644
+--- a/sound/soc/pxa/mmp-pcm.c
++++ b/sound/soc/pxa/mmp-pcm.c
+@@ -98,7 +98,7 @@ static bool filter(struct dma_chan *chan, void *param)
+
+ devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
+ dma_data->ssp_id);
+- if ((strcmp(dev_name(chan->device->dev), devname) == 0) &&
++ if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) &&
+ (chan->chan_id == dma_data->dma_res->start)) {
+ found = true;
+ }
+diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
+index 77a556b27cf09..24a1c121cb2e9 100644
+--- a/sound/soc/qcom/lpass-sc7180.c
++++ b/sound/soc/qcom/lpass-sc7180.c
+@@ -131,6 +131,9 @@ static int sc7180_lpass_init(struct platform_device *pdev)
+
+ drvdata->clks = devm_kcalloc(dev, variant->num_clks,
+ sizeof(*drvdata->clks), GFP_KERNEL);
++ if (!drvdata->clks)
++ return -ENOMEM;
++
+ drvdata->num_clks = variant->num_clks;
+
+ for (i = 0; i < drvdata->num_clks; i++)
+diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c
+index a7549f8272359..5b1e47bdc376b 100644
+--- a/sound/soc/rockchip/rockchip_pdm.c
++++ b/sound/soc/rockchip/rockchip_pdm.c
+@@ -431,6 +431,7 @@ static int rockchip_pdm_runtime_resume(struct device *dev)
+
+ ret = clk_prepare_enable(pdm->hclk);
+ if (ret) {
++ clk_disable_unprepare(pdm->clk);
+ dev_err(pdm->dev, "hclock enable failed %d\n", ret);
+ return ret;
+ }
+diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
+index 8bef572d3cbc1..5b4f004575879 100644
+--- a/sound/soc/rockchip/rockchip_spdif.c
++++ b/sound/soc/rockchip/rockchip_spdif.c
+@@ -88,6 +88,7 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
+
+ ret = clk_prepare_enable(spdif->hclk);
+ if (ret) {
++ clk_disable_unprepare(spdif->mclk);
+ dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
+ return ret;
+ }
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 874fcf245747f..271884e350035 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -76,6 +76,8 @@
+ { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f0a) },
+ /* E-Mu 0204 USB */
+ { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) },
++/* Ktmicro Usb_audio device */
++{ USB_DEVICE_VENDOR_SPEC(0x31b2, 0x0011) },
+
+ /*
+ * Creative Technology, Ltd Live! Cam Sync HD [VF0770]
+diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
+index 3bdbc0ce75b15..e54487e4005d3 100644
+--- a/tools/bpf/bpftool/common.c
++++ b/tools/bpf/bpftool/common.c
+@@ -499,6 +499,7 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb,
+ if (err) {
+ p_err("failed to append entry to hashmap for ID %u, path '%s': %s",
+ pinned_info.id, path, strerror(errno));
++ free(path);
+ goto out_close;
+ }
+
+diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
+index 9c50beabdd145..fddc05c667b5d 100644
+--- a/tools/lib/bpf/bpf.h
++++ b/tools/lib/bpf/bpf.h
+@@ -393,8 +393,15 @@ LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
+ __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
+ __u64 *probe_offset, __u64 *probe_addr);
+
++#ifdef __cplusplus
++/* forward-declaring enums in C++ isn't compatible with pure C enums, so
++ * instead define bpf_enable_stats() as accepting int as an input
++ */
++LIBBPF_API int bpf_enable_stats(int type);
++#else
+ enum bpf_stats_type; /* defined in up-to-date linux/bpf.h */
+ LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);
++#endif
+
+ struct bpf_prog_bind_opts {
+ size_t sz; /* size of this struct for forward/backward compatibility */
+diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
+index 2d14f1a52d7aa..9b18cf3128acc 100644
+--- a/tools/lib/bpf/btf.c
++++ b/tools/lib/bpf/btf.c
+@@ -3889,14 +3889,14 @@ static inline __u16 btf_fwd_kind(struct btf_type *t)
+ }
+
+ /* Check if given two types are identical ARRAY definitions */
+-static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
++static bool btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
+ {
+ struct btf_type *t1, *t2;
+
+ t1 = btf_type_by_id(d->btf, id1);
+ t2 = btf_type_by_id(d->btf, id2);
+ if (!btf_is_array(t1) || !btf_is_array(t2))
+- return 0;
++ return false;
+
+ return btf_equal_array(t1, t2);
+ }
+@@ -3920,7 +3920,9 @@ static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id
+ m1 = btf_members(t1);
+ m2 = btf_members(t2);
+ for (i = 0, n = btf_vlen(t1); i < n; i++, m1++, m2++) {
+- if (m1->type != m2->type)
++ if (m1->type != m2->type &&
++ !btf_dedup_identical_arrays(d, m1->type, m2->type) &&
++ !btf_dedup_identical_structs(d, m1->type, m2->type))
+ return false;
+ }
+ return true;
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 3937f66c7f8d6..0b470169729e6 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -219,6 +219,17 @@ static int btf_dump_resize(struct btf_dump *d)
+ return 0;
+ }
+
++static void btf_dump_free_names(struct hashmap *map)
++{
++ size_t bkt;
++ struct hashmap_entry *cur;
++
++ hashmap__for_each_entry(map, cur, bkt)
++ free((void *)cur->key);
++
++ hashmap__free(map);
++}
++
+ void btf_dump__free(struct btf_dump *d)
+ {
+ int i;
+@@ -237,8 +248,8 @@ void btf_dump__free(struct btf_dump *d)
+ free(d->cached_names);
+ free(d->emit_queue);
+ free(d->decl_stack);
+- hashmap__free(d->type_names);
+- hashmap__free(d->ident_names);
++ btf_dump_free_names(d->type_names);
++ btf_dump_free_names(d->ident_names);
+
+ free(d);
+ }
+@@ -1520,11 +1531,23 @@ static void btf_dump_emit_type_cast(struct btf_dump *d, __u32 id,
+ static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
+ const char *orig_name)
+ {
++ char *old_name, *new_name;
+ size_t dup_cnt = 0;
++ int err;
++
++ new_name = strdup(orig_name);
++ if (!new_name)
++ return 1;
+
+ hashmap__find(name_map, orig_name, (void **)&dup_cnt);
+ dup_cnt++;
+- hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
++
++ err = hashmap__set(name_map, new_name, (void *)dup_cnt,
++ (const void **)&old_name, NULL);
++ if (err)
++ free(new_name);
++
++ free(old_name);
+
+ return dup_cnt;
+ }
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 79ea83be21ce9..c01f57d31f89a 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -590,8 +590,7 @@ struct elf_state {
+ size_t shstrndx; /* section index for section name strings */
+ size_t strtabidx;
+ struct elf_sec_desc *secs;
+- int sec_cnt;
+- int maps_shndx;
++ size_t sec_cnt;
+ int btf_maps_shndx;
+ __u32 btf_maps_sec_btf_id;
+ int text_shndx;
+@@ -1272,7 +1271,6 @@ static struct bpf_object *bpf_object__new(const char *path,
+ */
+ obj->efile.obj_buf = obj_buf;
+ obj->efile.obj_buf_sz = obj_buf_sz;
+- obj->efile.maps_shndx = -1;
+ obj->efile.btf_maps_shndx = -1;
+ obj->efile.st_ops_shndx = -1;
+ obj->kconfig_map_idx = -1;
+@@ -1401,6 +1399,10 @@ static int bpf_object__check_endianness(struct bpf_object *obj)
+ static int
+ bpf_object__init_license(struct bpf_object *obj, void *data, size_t size)
+ {
++ if (!data) {
++ pr_warn("invalid license section in %s\n", obj->path);
++ return -LIBBPF_ERRNO__FORMAT;
++ }
+ /* libbpf_strlcpy() only copies first N - 1 bytes, so size + 1 won't
+ * go over allowed ELF data section buffer
+ */
+@@ -1414,7 +1416,7 @@ bpf_object__init_kversion(struct bpf_object *obj, void *data, size_t size)
+ {
+ __u32 kver;
+
+- if (size != sizeof(kver)) {
++ if (!data || size != sizeof(kver)) {
+ pr_warn("invalid kver section in %s\n", obj->path);
+ return -LIBBPF_ERRNO__FORMAT;
+ }
+@@ -3284,10 +3286,15 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
+ Elf64_Shdr *sh;
+
+ /* ELF section indices are 0-based, but sec #0 is special "invalid"
+- * section. e_shnum does include sec #0, so e_shnum is the necessary
+- * size of an array to keep all the sections.
++ * section. Since section count retrieved by elf_getshdrnum() does
++ * include sec #0, it is already the necessary size of an array to keep
++ * all the sections.
+ */
+- obj->efile.sec_cnt = obj->efile.ehdr->e_shnum;
++ if (elf_getshdrnum(obj->efile.elf, &obj->efile.sec_cnt)) {
++ pr_warn("elf: failed to get the number of sections for %s: %s\n",
++ obj->path, elf_errmsg(-1));
++ return -LIBBPF_ERRNO__FORMAT;
++ }
+ obj->efile.secs = calloc(obj->efile.sec_cnt, sizeof(*obj->efile.secs));
+ if (!obj->efile.secs)
+ return -ENOMEM;
+@@ -3359,7 +3366,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
+ if (err)
+ return err;
+ } else if (strcmp(name, "maps") == 0) {
+- obj->efile.maps_shndx = idx;
++ pr_warn("elf: legacy map definitions in 'maps' section are not supported by libbpf v1.0+\n");
++ return -ENOTSUP;
+ } else if (strcmp(name, MAPS_ELF_SEC) == 0) {
+ obj->efile.btf_maps_shndx = idx;
+ } else if (strcmp(name, BTF_ELF_SEC) == 0) {
+@@ -3891,8 +3899,7 @@ static bool bpf_object__shndx_is_data(const struct bpf_object *obj,
+ static bool bpf_object__shndx_is_maps(const struct bpf_object *obj,
+ int shndx)
+ {
+- return shndx == obj->efile.maps_shndx ||
+- shndx == obj->efile.btf_maps_shndx;
++ return shndx == obj->efile.btf_maps_shndx;
+ }
+
+ static enum libbpf_map_type
+@@ -4078,6 +4085,9 @@ static struct bpf_program *find_prog_by_sec_insn(const struct bpf_object *obj,
+ int l = 0, r = obj->nr_programs - 1, m;
+ struct bpf_program *prog;
+
++ if (!obj->nr_programs)
++ return NULL;
++
+ while (l < r) {
+ m = l + (r - l + 1) / 2;
+ prog = &obj->programs[m];
+diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c
+index d18e37982344c..2ade9c7969d72 100644
+--- a/tools/lib/bpf/usdt.c
++++ b/tools/lib/bpf/usdt.c
+@@ -1348,25 +1348,23 @@ static int calc_pt_regs_off(const char *reg_name)
+
+ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg)
+ {
+- char *reg_name = NULL;
++ char reg_name[16];
+ int arg_sz, len, reg_off;
+ long off;
+
+- if (sscanf(arg_str, " %d @ \[ %m[a-z0-9], %ld ] %n", &arg_sz, ®_name, &off, &len) == 3) {
++ if (sscanf(arg_str, " %d @ \[ %15[a-z0-9], %ld ] %n", &arg_sz, reg_name, &off, &len) == 3) {
+ /* Memory dereference case, e.g., -4@[sp, 96] */
+ arg->arg_type = USDT_ARG_REG_DEREF;
+ arg->val_off = off;
+ reg_off = calc_pt_regs_off(reg_name);
+- free(reg_name);
+ if (reg_off < 0)
+ return reg_off;
+ arg->reg_off = reg_off;
+- } else if (sscanf(arg_str, " %d @ \[ %m[a-z0-9] ] %n", &arg_sz, ®_name, &len) == 2) {
++ } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", &arg_sz, reg_name, &len) == 2) {
+ /* Memory dereference case, e.g., -4@[sp] */
+ arg->arg_type = USDT_ARG_REG_DEREF;
+ arg->val_off = 0;
+ reg_off = calc_pt_regs_off(reg_name);
+- free(reg_name);
+ if (reg_off < 0)
+ return reg_off;
+ arg->reg_off = reg_off;
+@@ -1375,12 +1373,11 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec
+ arg->arg_type = USDT_ARG_CONST;
+ arg->val_off = off;
+ arg->reg_off = 0;
+- } else if (sscanf(arg_str, " %d @ %m[a-z0-9] %n", &arg_sz, ®_name, &len) == 2) {
++ } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", &arg_sz, reg_name, &len) == 2) {
+ /* Register read case, e.g., -8@x4 */
+ arg->arg_type = USDT_ARG_REG;
+ arg->val_off = 0;
+ reg_off = calc_pt_regs_off(reg_name);
+- free(reg_name);
+ if (reg_off < 0)
+ return reg_off;
+ arg->reg_off = reg_off;
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index e55fdf952a3a1..67afdce3421f5 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -999,6 +999,16 @@ static const char *uaccess_safe_builtin[] = {
+ "__tsan_read_write4",
+ "__tsan_read_write8",
+ "__tsan_read_write16",
++ "__tsan_volatile_read1",
++ "__tsan_volatile_read2",
++ "__tsan_volatile_read4",
++ "__tsan_volatile_read8",
++ "__tsan_volatile_read16",
++ "__tsan_volatile_write1",
++ "__tsan_volatile_write2",
++ "__tsan_volatile_write4",
++ "__tsan_volatile_write8",
++ "__tsan_volatile_write16",
+ "__tsan_atomic8_load",
+ "__tsan_atomic16_load",
+ "__tsan_atomic32_load",
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index 0b4a62e4ff675..cab6b70e95e26 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -573,26 +573,14 @@ static int enable_counters(void)
+ return err;
+ }
+
+- if (stat_config.initial_delay < 0) {
+- pr_info(EVLIST_DISABLED_MSG);
+- return 0;
+- }
+-
+- if (stat_config.initial_delay > 0) {
+- pr_info(EVLIST_DISABLED_MSG);
+- usleep(stat_config.initial_delay * USEC_PER_MSEC);
+- }
+-
+ /*
+ * We need to enable counters only if:
+ * - we don't have tracee (attaching to task or cpu)
+ * - we have initial delay configured
+ */
+- if (!target__none(&target) || stat_config.initial_delay) {
++ if (!target__none(&target)) {
+ if (!all_counters_use_bpf)
+ evlist__enable(evsel_list);
+- if (stat_config.initial_delay > 0)
+- pr_info(EVLIST_ENABLED_MSG);
+ }
+ return 0;
+ }
+@@ -967,14 +955,27 @@ try_again_reset:
+ return err;
+ }
+
+- err = enable_counters();
+- if (err)
+- return -1;
++ if (stat_config.initial_delay) {
++ pr_info(EVLIST_DISABLED_MSG);
++ } else {
++ err = enable_counters();
++ if (err)
++ return -1;
++ }
+
+ /* Exec the command, if any */
+ if (forks)
+ evlist__start_workload(evsel_list);
+
++ if (stat_config.initial_delay > 0) {
++ usleep(stat_config.initial_delay * USEC_PER_MSEC);
++ err = enable_counters();
++ if (err)
++ return -1;
++
++ pr_info(EVLIST_ENABLED_MSG);
++ }
++
+ t0 = rdclock();
+ clock_gettime(CLOCK_MONOTONIC, &ref_time);
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 0bd9d01c0df9d..73f4a83edc443 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -88,6 +88,8 @@
+ # define F_LINUX_SPECIFIC_BASE 1024
+ #endif
+
++#define RAW_SYSCALL_ARGS_NUM 6
++
+ /*
+ * strtoul: Go from a string to a value, i.e. for msr: MSR_FS_BASE to 0xc0000100
+ */
+@@ -108,7 +110,7 @@ struct syscall_fmt {
+ const char *sys_enter,
+ *sys_exit;
+ } bpf_prog_name;
+- struct syscall_arg_fmt arg[6];
++ struct syscall_arg_fmt arg[RAW_SYSCALL_ARGS_NUM];
+ u8 nr_args;
+ bool errpid;
+ bool timeout;
+@@ -1229,7 +1231,7 @@ struct syscall {
+ */
+ struct bpf_map_syscall_entry {
+ bool enabled;
+- u16 string_args_len[6];
++ u16 string_args_len[RAW_SYSCALL_ARGS_NUM];
+ };
+
+ /*
+@@ -1661,7 +1663,7 @@ static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args)
+ {
+ int idx;
+
+- if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0)
++ if (nr_args == RAW_SYSCALL_ARGS_NUM && sc->fmt && sc->fmt->nr_args != 0)
+ nr_args = sc->fmt->nr_args;
+
+ sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt));
+@@ -1794,11 +1796,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+ #endif
+ sc = trace->syscalls.table + id;
+ if (sc->nonexistent)
+- return 0;
++ return -EEXIST;
+
+ if (name == NULL) {
+ sc->nonexistent = true;
+- return 0;
++ return -EEXIST;
+ }
+
+ sc->name = name;
+@@ -1812,11 +1814,18 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+ sc->tp_format = trace_event__tp_format("syscalls", tp_name);
+ }
+
+- if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields))
+- return -ENOMEM;
+-
+- if (IS_ERR(sc->tp_format))
++ /*
++ * Fails to read trace point format via sysfs node, so the trace point
++ * doesn't exist. Set the 'nonexistent' flag as true.
++ */
++ if (IS_ERR(sc->tp_format)) {
++ sc->nonexistent = true;
+ return PTR_ERR(sc->tp_format);
++ }
++
++ if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
++ RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
++ return -ENOMEM;
+
+ sc->args = sc->tp_format->format.fields;
+ /*
+@@ -2134,11 +2143,8 @@ static struct syscall *trace__syscall_info(struct trace *trace,
+ (err = trace__read_syscall_info(trace, id)) != 0)
+ goto out_cant_read;
+
+- if (trace->syscalls.table[id].name == NULL) {
+- if (trace->syscalls.table[id].nonexistent)
+- return NULL;
++ if (trace->syscalls.table && trace->syscalls.table[id].nonexistent)
+ goto out_cant_read;
+- }
+
+ return &trace->syscalls.table[id];
+
+diff --git a/tools/perf/tests/shell/stat_all_pmu.sh b/tools/perf/tests/shell/stat_all_pmu.sh
+index 9c9ef33e0b3c6..c779554191731 100755
+--- a/tools/perf/tests/shell/stat_all_pmu.sh
++++ b/tools/perf/tests/shell/stat_all_pmu.sh
+@@ -4,17 +4,8 @@
+
+ set -e
+
+-for p in $(perf list --raw-dump pmu); do
+- # In powerpc, skip the events for hv_24x7 and hv_gpci.
+- # These events needs input values to be filled in for
+- # core, chip, partition id based on system.
+- # Example: hv_24x7/CPM_ADJUNCT_INST,domain=?,core=?/
+- # hv_gpci/event,partition_id=?/
+- # Hence skip these events for ppc.
+- if echo "$p" |grep -Eq 'hv_24x7|hv_gpci' ; then
+- echo "Skipping: Event '$p' in powerpc"
+- continue
+- fi
++# Test all PMU events; however exclude parametrized ones (name contains '?')
++for p in $(perf list --raw-dump pmu | sed 's/[[:graph:]]\+?[[:graph:]]\+[[:space:]]//g'); do
+ echo "Testing $p"
+ result=$(perf stat -e "$p" true 2>&1)
+ if ! echo "$result" | grep -q "$p" && ! echo "$result" | grep -q "<not supported>" ; then
+diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c
+index c257813e674ef..01f70b8e705a8 100644
+--- a/tools/perf/util/bpf_off_cpu.c
++++ b/tools/perf/util/bpf_off_cpu.c
+@@ -102,7 +102,7 @@ static void check_sched_switch_args(void)
+ const struct btf_type *t1, *t2, *t3;
+ u32 type_id;
+
+- type_id = btf__find_by_name_kind(btf, "bpf_trace_sched_switch",
++ type_id = btf__find_by_name_kind(btf, "btf_trace_sched_switch",
+ BTF_KIND_TYPEDEF);
+ if ((s32)type_id < 0)
+ return;
+diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
+index 65e6c22f38e4f..190e818a07176 100644
+--- a/tools/perf/util/debug.c
++++ b/tools/perf/util/debug.c
+@@ -241,6 +241,10 @@ int perf_quiet_option(void)
+ opt++;
+ }
+
++ /* For debug variables that are used as bool types, set to 0. */
++ redirect_to_stderr = 0;
++ debug_peo_args = 0;
++
+ return 0;
+ }
+
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index 647b7dff8ef36..80345695b1360 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1303,7 +1303,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
+ (!used_opd && syms_ss->adjust_symbols)) {
+ GElf_Phdr phdr;
+
+- if (elf_read_program_header(syms_ss->elf,
++ if (elf_read_program_header(runtime_ss->elf,
+ (u64)sym.st_value, &phdr)) {
+ pr_debug4("%s: failed to find program header for "
+ "symbol: %s st_value: %#" PRIx64 "\n",
+diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+index ac5d7c1396fb4..5085fea3cac5f 100644
+--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
++++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+@@ -18,6 +18,46 @@ typedef int (*func_proto_typedef_nested1)(func_proto_typedef);
+ typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1);
+
+ DEFINE_PER_CPU(int, bpf_testmod_ksym_percpu) = 123;
++long bpf_testmod_test_struct_arg_result;
++
++struct bpf_testmod_struct_arg_1 {
++ int a;
++};
++struct bpf_testmod_struct_arg_2 {
++ long a;
++ long b;
++};
++
++noinline int
++bpf_testmod_test_struct_arg_1(struct bpf_testmod_struct_arg_2 a, int b, int c) {
++ bpf_testmod_test_struct_arg_result = a.a + a.b + b + c;
++ return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_2(int a, struct bpf_testmod_struct_arg_2 b, int c) {
++ bpf_testmod_test_struct_arg_result = a + b.a + b.b + c;
++ return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_3(int a, int b, struct bpf_testmod_struct_arg_2 c) {
++ bpf_testmod_test_struct_arg_result = a + b + c.a + c.b;
++ return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_4(struct bpf_testmod_struct_arg_1 a, int b,
++ int c, int d, struct bpf_testmod_struct_arg_2 e) {
++ bpf_testmod_test_struct_arg_result = a.a + b + c + d + e.a + e.b;
++ return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_5(void) {
++ bpf_testmod_test_struct_arg_result = 1;
++ return bpf_testmod_test_struct_arg_result;
++}
+
+ noinline void
+ bpf_testmod_test_mod_kfunc(int i)
+@@ -115,11 +155,19 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ .off = off,
+ .len = len,
+ };
++ struct bpf_testmod_struct_arg_1 struct_arg1 = {10};
++ struct bpf_testmod_struct_arg_2 struct_arg2 = {2, 3};
+ int i = 1;
+
+ while (bpf_testmod_return_ptr(i))
+ i++;
+
++ (void)bpf_testmod_test_struct_arg_1(struct_arg2, 1, 4);
++ (void)bpf_testmod_test_struct_arg_2(1, struct_arg2, 4);
++ (void)bpf_testmod_test_struct_arg_3(1, 4, struct_arg2);
++ (void)bpf_testmod_test_struct_arg_4(struct_arg1, 1, 2, 3, struct_arg2);
++ (void)bpf_testmod_test_struct_arg_5();
++
+ /* This is always true. Use the check to make sure the compiler
+ * doesn't remove bpf_testmod_loop_test.
+ */
+diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
+index fabf0c0143498..c5c5fc2a3ce7b 100644
+--- a/tools/testing/selftests/bpf/config
++++ b/tools/testing/selftests/bpf/config
+@@ -13,6 +13,7 @@ CONFIG_CRYPTO_USER_API_HASH=m
+ CONFIG_DYNAMIC_FTRACE=y
+ CONFIG_FPROBE=y
+ CONFIG_FTRACE_SYSCALLS=y
++CONFIG_FUNCTION_ERROR_INJECTION=y
+ CONFIG_FUNCTION_TRACER=y
+ CONFIG_GENEVE=y
+ CONFIG_IKCONFIG=y
+diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c
+index bec15558fd938..1f37adff7632c 100644
+--- a/tools/testing/selftests/bpf/network_helpers.c
++++ b/tools/testing/selftests/bpf/network_helpers.c
+@@ -426,6 +426,10 @@ static int setns_by_fd(int nsfd)
+ if (!ASSERT_OK(err, "mount /sys/fs/bpf"))
+ return err;
+
++ err = mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL);
++ if (!ASSERT_OK(err, "mount /sys/kernel/debug"))
++ return err;
++
+ return 0;
+ }
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/empty_skb.c b/tools/testing/selftests/bpf/prog_tests/empty_skb.c
+new file mode 100644
+index 0000000000000..0613f3bb8b5e4
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/empty_skb.c
+@@ -0,0 +1,146 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <test_progs.h>
++#include <network_helpers.h>
++#include <net/if.h>
++#include "empty_skb.skel.h"
++
++#define SYS(cmd) ({ \
++ if (!ASSERT_OK(system(cmd), (cmd))) \
++ goto out; \
++})
++
++void serial_test_empty_skb(void)
++{
++ LIBBPF_OPTS(bpf_test_run_opts, tattr);
++ struct empty_skb *bpf_obj = NULL;
++ struct nstoken *tok = NULL;
++ struct bpf_program *prog;
++ char eth_hlen_pp[15];
++ char eth_hlen[14];
++ int veth_ifindex;
++ int ipip_ifindex;
++ int err;
++ int i;
++
++ struct {
++ const char *msg;
++ const void *data_in;
++ __u32 data_size_in;
++ int *ifindex;
++ int err;
++ int ret;
++ bool success_on_tc;
++ } tests[] = {
++ /* Empty packets are always rejected. */
++
++ {
++ /* BPF_PROG_RUN ETH_HLEN size check */
++ .msg = "veth empty ingress packet",
++ .data_in = NULL,
++ .data_size_in = 0,
++ .ifindex = &veth_ifindex,
++ .err = -EINVAL,
++ },
++ {
++ /* BPF_PROG_RUN ETH_HLEN size check */
++ .msg = "ipip empty ingress packet",
++ .data_in = NULL,
++ .data_size_in = 0,
++ .ifindex = &ipip_ifindex,
++ .err = -EINVAL,
++ },
++
++ /* ETH_HLEN-sized packets:
++ * - can not be redirected at LWT_XMIT
++ * - can be redirected at TC to non-tunneling dest
++ */
++
++ {
++ /* __bpf_redirect_common */
++ .msg = "veth ETH_HLEN packet ingress",
++ .data_in = eth_hlen,
++ .data_size_in = sizeof(eth_hlen),
++ .ifindex = &veth_ifindex,
++ .ret = -ERANGE,
++ .success_on_tc = true,
++ },
++ {
++ /* __bpf_redirect_no_mac
++ *
++ * lwt: skb->len=0 <= skb_network_offset=0
++ * tc: skb->len=14 <= skb_network_offset=14
++ */
++ .msg = "ipip ETH_HLEN packet ingress",
++ .data_in = eth_hlen,
++ .data_size_in = sizeof(eth_hlen),
++ .ifindex = &ipip_ifindex,
++ .ret = -ERANGE,
++ },
++
++ /* ETH_HLEN+1-sized packet should be redirected. */
++
++ {
++ .msg = "veth ETH_HLEN+1 packet ingress",
++ .data_in = eth_hlen_pp,
++ .data_size_in = sizeof(eth_hlen_pp),
++ .ifindex = &veth_ifindex,
++ },
++ {
++ .msg = "ipip ETH_HLEN+1 packet ingress",
++ .data_in = eth_hlen_pp,
++ .data_size_in = sizeof(eth_hlen_pp),
++ .ifindex = &ipip_ifindex,
++ },
++ };
++
++ SYS("ip netns add empty_skb");
++ tok = open_netns("empty_skb");
++ SYS("ip link add veth0 type veth peer veth1");
++ SYS("ip link set dev veth0 up");
++ SYS("ip link set dev veth1 up");
++ SYS("ip addr add 10.0.0.1/8 dev veth0");
++ SYS("ip addr add 10.0.0.2/8 dev veth1");
++ veth_ifindex = if_nametoindex("veth0");
++
++ SYS("ip link add ipip0 type ipip local 10.0.0.1 remote 10.0.0.2");
++ SYS("ip link set ipip0 up");
++ SYS("ip addr add 192.168.1.1/16 dev ipip0");
++ ipip_ifindex = if_nametoindex("ipip0");
++
++ bpf_obj = empty_skb__open_and_load();
++ if (!ASSERT_OK_PTR(bpf_obj, "open skeleton"))
++ goto out;
++
++ for (i = 0; i < ARRAY_SIZE(tests); i++) {
++ bpf_object__for_each_program(prog, bpf_obj->obj) {
++ char buf[128];
++ bool at_tc = !strncmp(bpf_program__section_name(prog), "tc", 2);
++
++ tattr.data_in = tests[i].data_in;
++ tattr.data_size_in = tests[i].data_size_in;
++
++ tattr.data_size_out = 0;
++ bpf_obj->bss->ifindex = *tests[i].ifindex;
++ bpf_obj->bss->ret = 0;
++ err = bpf_prog_test_run_opts(bpf_program__fd(prog), &tattr);
++ sprintf(buf, "err: %s [%s]", tests[i].msg, bpf_program__name(prog));
++
++ if (at_tc && tests[i].success_on_tc)
++ ASSERT_GE(err, 0, buf);
++ else
++ ASSERT_EQ(err, tests[i].err, buf);
++ sprintf(buf, "ret: %s [%s]", tests[i].msg, bpf_program__name(prog));
++ if (at_tc && tests[i].success_on_tc)
++ ASSERT_GE(bpf_obj->bss->ret, 0, buf);
++ else
++ ASSERT_EQ(bpf_obj->bss->ret, tests[i].ret, buf);
++ }
++ }
++
++out:
++ if (bpf_obj)
++ empty_skb__destroy(bpf_obj);
++ if (tok)
++ close_netns(tok);
++ system("ip netns del empty_skb");
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+index d457a55ff408e..287b3ac40227a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
++++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+@@ -325,7 +325,7 @@ static bool symbol_equal(const void *key1, const void *key2, void *ctx __maybe_u
+ static int get_syms(char ***symsp, size_t *cntp)
+ {
+ size_t cap = 0, cnt = 0, i;
+- char *name, **syms = NULL;
++ char *name = NULL, **syms = NULL;
+ struct hashmap *map;
+ char buf[256];
+ FILE *f;
+@@ -352,6 +352,8 @@ static int get_syms(char ***symsp, size_t *cntp)
+ /* skip modules */
+ if (strchr(buf, '['))
+ continue;
++
++ free(name);
+ if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)
+ continue;
+ /*
+@@ -369,32 +371,32 @@ static int get_syms(char ***symsp, size_t *cntp)
+ if (!strncmp(name, "__ftrace_invalid_address__",
+ sizeof("__ftrace_invalid_address__") - 1))
+ continue;
++
+ err = hashmap__add(map, name, NULL);
+- if (err) {
+- free(name);
+- if (err == -EEXIST)
+- continue;
++ if (err == -EEXIST)
++ continue;
++ if (err)
+ goto error;
+- }
++
+ err = libbpf_ensure_mem((void **) &syms, &cap,
+ sizeof(*syms), cnt + 1);
+- if (err) {
+- free(name);
++ if (err)
+ goto error;
+- }
+- syms[cnt] = name;
+- cnt++;
++
++ syms[cnt++] = name;
++ name = NULL;
+ }
+
+ *symsp = syms;
+ *cntp = cnt;
+
+ error:
++ free(name);
+ fclose(f);
+ hashmap__free(map);
+ if (err) {
+ for (i = 0; i < cnt; i++)
+- free(syms[cnt]);
++ free(syms[i]);
+ free(syms);
+ }
+ return err;
+diff --git a/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c b/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
+index 1102e4f42d2d4..f117bfef68a14 100644
+--- a/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
++++ b/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
+@@ -173,10 +173,12 @@ static void test_lsm_cgroup_functional(void)
+ ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 4, "total prog count");
+ ASSERT_EQ(query_prog_cnt(cgroup_fd2, NULL), 1, "total prog count");
+
+- /* AF_UNIX is prohibited. */
+-
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+- ASSERT_LT(fd, 0, "socket(AF_UNIX)");
++ if (!(skel->kconfig->CONFIG_SECURITY_APPARMOR
++ || skel->kconfig->CONFIG_SECURITY_SELINUX
++ || skel->kconfig->CONFIG_SECURITY_SMACK))
++ /* AF_UNIX is prohibited. */
++ ASSERT_LT(fd, 0, "socket(AF_UNIX)");
+ close(fd);
+
+ /* AF_INET6 gets default policy (sk_priority). */
+@@ -233,11 +235,18 @@ static void test_lsm_cgroup_functional(void)
+
+ /* AF_INET6+SOCK_STREAM
+ * AF_PACKET+SOCK_RAW
++ * AF_UNIX+SOCK_RAW if already have non-bpf lsms installed
+ * listen_fd
+ * client_fd
+ * accepted_fd
+ */
+- ASSERT_EQ(skel->bss->called_socket_post_create2, 5, "called_create2");
++ if (skel->kconfig->CONFIG_SECURITY_APPARMOR
++ || skel->kconfig->CONFIG_SECURITY_SELINUX
++ || skel->kconfig->CONFIG_SECURITY_SMACK)
++ /* AF_UNIX+SOCK_RAW if already have non-bpf lsms installed */
++ ASSERT_EQ(skel->bss->called_socket_post_create2, 6, "called_create2");
++ else
++ ASSERT_EQ(skel->bss->called_socket_post_create2, 5, "called_create2");
+
+ /* start_server
+ * bind(ETH_P_ALL)
+diff --git a/tools/testing/selftests/bpf/prog_tests/map_kptr.c b/tools/testing/selftests/bpf/prog_tests/map_kptr.c
+index fdcea7a61491e..0d66b15242089 100644
+--- a/tools/testing/selftests/bpf/prog_tests/map_kptr.c
++++ b/tools/testing/selftests/bpf/prog_tests/map_kptr.c
+@@ -105,7 +105,7 @@ static void test_map_kptr_success(bool test_run)
+ ASSERT_OK(opts.retval, "test_map_kptr_ref2 retval");
+
+ if (test_run)
+- return;
++ goto exit;
+
+ ret = bpf_map__update_elem(skel->maps.array_map,
+ &key, sizeof(key), buf, sizeof(buf), 0);
+@@ -132,6 +132,7 @@ static void test_map_kptr_success(bool test_run)
+ ret = bpf_map__delete_elem(skel->maps.lru_hash_map, &key, sizeof(key), 0);
+ ASSERT_OK(ret, "lru_hash_map delete");
+
++exit:
+ map_kptr__destroy(skel);
+ }
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_struct.c b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
+new file mode 100644
+index 0000000000000..48dc9472e160a
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
+@@ -0,0 +1,64 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
++
++#include <test_progs.h>
++#include "tracing_struct.skel.h"
++
++static void test_fentry(void)
++{
++ struct tracing_struct *skel;
++ int err;
++
++ skel = tracing_struct__open_and_load();
++ if (!ASSERT_OK_PTR(skel, "tracing_struct__open_and_load"))
++ return;
++
++ err = tracing_struct__attach(skel);
++ if (!ASSERT_OK(err, "tracing_struct__attach"))
++ goto destroy_skel;
++
++ ASSERT_OK(trigger_module_test_read(256), "trigger_read");
++
++ ASSERT_EQ(skel->bss->t1_a_a, 2, "t1:a.a");
++ ASSERT_EQ(skel->bss->t1_a_b, 3, "t1:a.b");
++ ASSERT_EQ(skel->bss->t1_b, 1, "t1:b");
++ ASSERT_EQ(skel->bss->t1_c, 4, "t1:c");
++
++ ASSERT_EQ(skel->bss->t1_nregs, 4, "t1 nregs");
++ ASSERT_EQ(skel->bss->t1_reg0, 2, "t1 reg0");
++ ASSERT_EQ(skel->bss->t1_reg1, 3, "t1 reg1");
++ ASSERT_EQ(skel->bss->t1_reg2, 1, "t1 reg2");
++ ASSERT_EQ(skel->bss->t1_reg3, 4, "t1 reg3");
++ ASSERT_EQ(skel->bss->t1_ret, 10, "t1 ret");
++
++ ASSERT_EQ(skel->bss->t2_a, 1, "t2:a");
++ ASSERT_EQ(skel->bss->t2_b_a, 2, "t2:b.a");
++ ASSERT_EQ(skel->bss->t2_b_b, 3, "t2:b.b");
++ ASSERT_EQ(skel->bss->t2_c, 4, "t2:c");
++ ASSERT_EQ(skel->bss->t2_ret, 10, "t2 ret");
++
++ ASSERT_EQ(skel->bss->t3_a, 1, "t3:a");
++ ASSERT_EQ(skel->bss->t3_b, 4, "t3:b");
++ ASSERT_EQ(skel->bss->t3_c_a, 2, "t3:c.a");
++ ASSERT_EQ(skel->bss->t3_c_b, 3, "t3:c.b");
++ ASSERT_EQ(skel->bss->t3_ret, 10, "t3 ret");
++
++ ASSERT_EQ(skel->bss->t4_a_a, 10, "t4:a.a");
++ ASSERT_EQ(skel->bss->t4_b, 1, "t4:b");
++ ASSERT_EQ(skel->bss->t4_c, 2, "t4:c");
++ ASSERT_EQ(skel->bss->t4_d, 3, "t4:d");
++ ASSERT_EQ(skel->bss->t4_e_a, 2, "t4:e.a");
++ ASSERT_EQ(skel->bss->t4_e_b, 3, "t4:e.b");
++ ASSERT_EQ(skel->bss->t4_ret, 21, "t4 ret");
++
++ ASSERT_EQ(skel->bss->t5_ret, 1, "t5 ret");
++
++ tracing_struct__detach(skel);
++destroy_skel:
++ tracing_struct__destroy(skel);
++}
++
++void test_tracing_struct(void)
++{
++ test_fentry();
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+index 21ceac24e1744..8f2613267be26 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+@@ -18,7 +18,7 @@ static void test_xdp_adjust_tail_shrink(void)
+ );
+
+ err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+- if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
++ if (!ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
+ return;
+
+ err = bpf_prog_test_run_opts(prog_fd, &topts);
+@@ -53,7 +53,7 @@ static void test_xdp_adjust_tail_grow(void)
+ );
+
+ err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+- if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
++ if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
+ return;
+
+ err = bpf_prog_test_run_opts(prog_fd, &topts);
+@@ -63,6 +63,7 @@ static void test_xdp_adjust_tail_grow(void)
+ expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */
+ topts.data_in = &pkt_v6;
+ topts.data_size_in = sizeof(pkt_v6);
++ topts.data_size_out = sizeof(buf);
+ err = bpf_prog_test_run_opts(prog_fd, &topts);
+ ASSERT_OK(err, "ipv6");
+ ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
+@@ -89,7 +90,7 @@ static void test_xdp_adjust_tail_grow2(void)
+ );
+
+ err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+- if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
++ if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
+ return;
+
+ /* Test case-64 */
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
+index a50971c6cf4a5..9ac6f6a268db2 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
+@@ -85,7 +85,7 @@ static void test_max_pkt_size(int fd)
+ }
+
+ #define NUM_PKTS 10000
+-void test_xdp_do_redirect(void)
++void serial_test_xdp_do_redirect(void)
+ {
+ int err, xdp_prog_fd, tc_prog_fd, ifindex_src, ifindex_dst;
+ char data[sizeof(pkt_udp) + sizeof(__u32)];
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
+index 874a846e298ca..b49d14580e516 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
+@@ -174,7 +174,7 @@ out:
+ system("ip netns del synproxy");
+ }
+
+-void test_xdp_synproxy(void)
++void serial_test_xdp_synproxy(void)
+ {
+ if (test__start_subtest("xdp"))
+ test_synproxy(true);
+diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c b/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
+index 285c008cbf9c2..9ba14c37bbcc9 100644
+--- a/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
++++ b/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
+@@ -7,14 +7,14 @@ char _license[] SEC("license") = "GPL";
+
+ unsigned long last_sym_value = 0;
+
+-static inline char tolower(char c)
++static inline char to_lower(char c)
+ {
+ if (c >= 'A' && c <= 'Z')
+ c += ('a' - 'A');
+ return c;
+ }
+
+-static inline char toupper(char c)
++static inline char to_upper(char c)
+ {
+ if (c >= 'a' && c <= 'z')
+ c -= ('a' - 'A');
+@@ -54,7 +54,7 @@ int dump_ksym(struct bpf_iter__ksym *ctx)
+ type = iter->type;
+
+ if (iter->module_name[0]) {
+- type = iter->exported ? toupper(type) : tolower(type);
++ type = iter->exported ? to_upper(type) : to_lower(type);
+ BPF_SEQ_PRINTF(seq, "0x%llx %c %s [ %s ] ",
+ value, type, iter->name, iter->module_name);
+ } else {
+diff --git a/tools/testing/selftests/bpf/progs/empty_skb.c b/tools/testing/selftests/bpf/progs/empty_skb.c
+new file mode 100644
+index 0000000000000..4b0cd67532511
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/empty_skb.c
+@@ -0,0 +1,37 @@
++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
++#include <linux/bpf.h>
++#include <bpf/bpf_helpers.h>
++#include <bpf/bpf_endian.h>
++
++char _license[] SEC("license") = "GPL";
++
++int ifindex;
++int ret;
++
++SEC("lwt_xmit")
++int redirect_ingress(struct __sk_buff *skb)
++{
++ ret = bpf_clone_redirect(skb, ifindex, BPF_F_INGRESS);
++ return 0;
++}
++
++SEC("lwt_xmit")
++int redirect_egress(struct __sk_buff *skb)
++{
++ ret = bpf_clone_redirect(skb, ifindex, 0);
++ return 0;
++}
++
++SEC("tc")
++int tc_redirect_ingress(struct __sk_buff *skb)
++{
++ ret = bpf_clone_redirect(skb, ifindex, BPF_F_INGRESS);
++ return 0;
++}
++
++SEC("tc")
++int tc_redirect_egress(struct __sk_buff *skb)
++{
++ ret = bpf_clone_redirect(skb, ifindex, 0);
++ return 0;
++}
+diff --git a/tools/testing/selftests/bpf/progs/lsm_cgroup.c b/tools/testing/selftests/bpf/progs/lsm_cgroup.c
+index 4f2d60b87b75d..02c11d16b692a 100644
+--- a/tools/testing/selftests/bpf/progs/lsm_cgroup.c
++++ b/tools/testing/selftests/bpf/progs/lsm_cgroup.c
+@@ -7,6 +7,10 @@
+
+ char _license[] SEC("license") = "GPL";
+
++extern bool CONFIG_SECURITY_SELINUX __kconfig __weak;
++extern bool CONFIG_SECURITY_SMACK __kconfig __weak;
++extern bool CONFIG_SECURITY_APPARMOR __kconfig __weak;
++
+ #ifndef AF_PACKET
+ #define AF_PACKET 17
+ #endif
+@@ -140,6 +144,10 @@ SEC("lsm_cgroup/sk_alloc_security")
+ int BPF_PROG(socket_alloc, struct sock *sk, int family, gfp_t priority)
+ {
+ called_socket_alloc++;
++ /* if already have non-bpf lsms installed, EPERM will cause memory leak of non-bpf lsms */
++ if (CONFIG_SECURITY_SELINUX || CONFIG_SECURITY_SMACK || CONFIG_SECURITY_APPARMOR)
++ return 1;
++
+ if (family == AF_UNIX)
+ return 0; /* EPERM */
+
+diff --git a/tools/testing/selftests/bpf/progs/tracing_struct.c b/tools/testing/selftests/bpf/progs/tracing_struct.c
+new file mode 100644
+index 0000000000000..e718f0ebee7dd
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/tracing_struct.c
+@@ -0,0 +1,120 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
++
++#include <vmlinux.h>
++#include <bpf/bpf_tracing.h>
++#include <bpf/bpf_helpers.h>
++
++struct bpf_testmod_struct_arg_1 {
++ int a;
++};
++struct bpf_testmod_struct_arg_2 {
++ long a;
++ long b;
++};
++
++long t1_a_a, t1_a_b, t1_b, t1_c, t1_ret, t1_nregs;
++__u64 t1_reg0, t1_reg1, t1_reg2, t1_reg3;
++long t2_a, t2_b_a, t2_b_b, t2_c, t2_ret;
++long t3_a, t3_b, t3_c_a, t3_c_b, t3_ret;
++long t4_a_a, t4_b, t4_c, t4_d, t4_e_a, t4_e_b, t4_ret;
++long t5_ret;
++
++SEC("fentry/bpf_testmod_test_struct_arg_1")
++int BPF_PROG2(test_struct_arg_1, struct bpf_testmod_struct_arg_2, a, int, b, int, c)
++{
++ t1_a_a = a.a;
++ t1_a_b = a.b;
++ t1_b = b;
++ t1_c = c;
++ return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_1")
++int BPF_PROG2(test_struct_arg_2, struct bpf_testmod_struct_arg_2, a, int, b, int, c, int, ret)
++{
++ t1_nregs = bpf_get_func_arg_cnt(ctx);
++ /* a.a */
++ bpf_get_func_arg(ctx, 0, &t1_reg0);
++ /* a.b */
++ bpf_get_func_arg(ctx, 1, &t1_reg1);
++ /* b */
++ bpf_get_func_arg(ctx, 2, &t1_reg2);
++ t1_reg2 = (int)t1_reg2;
++ /* c */
++ bpf_get_func_arg(ctx, 3, &t1_reg3);
++ t1_reg3 = (int)t1_reg3;
++
++ t1_ret = ret;
++ return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_2")
++int BPF_PROG2(test_struct_arg_3, int, a, struct bpf_testmod_struct_arg_2, b, int, c)
++{
++ t2_a = a;
++ t2_b_a = b.a;
++ t2_b_b = b.b;
++ t2_c = c;
++ return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_2")
++int BPF_PROG2(test_struct_arg_4, int, a, struct bpf_testmod_struct_arg_2, b, int, c, int, ret)
++{
++ t2_ret = ret;
++ return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_3")
++int BPF_PROG2(test_struct_arg_5, int, a, int, b, struct bpf_testmod_struct_arg_2, c)
++{
++ t3_a = a;
++ t3_b = b;
++ t3_c_a = c.a;
++ t3_c_b = c.b;
++ return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_3")
++int BPF_PROG2(test_struct_arg_6, int, a, int, b, struct bpf_testmod_struct_arg_2, c, int, ret)
++{
++ t3_ret = ret;
++ return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_4")
++int BPF_PROG2(test_struct_arg_7, struct bpf_testmod_struct_arg_1, a, int, b,
++ int, c, int, d, struct bpf_testmod_struct_arg_2, e)
++{
++ t4_a_a = a.a;
++ t4_b = b;
++ t4_c = c;
++ t4_d = d;
++ t4_e_a = e.a;
++ t4_e_b = e.b;
++ return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_4")
++int BPF_PROG2(test_struct_arg_8, struct bpf_testmod_struct_arg_1, a, int, b,
++ int, c, int, d, struct bpf_testmod_struct_arg_2, e, int, ret)
++{
++ t4_ret = ret;
++ return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_5")
++int BPF_PROG2(test_struct_arg_9)
++{
++ return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_5")
++int BPF_PROG2(test_struct_arg_10, int, ret)
++{
++ t5_ret = ret;
++ return 0;
++}
++
++char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/bpf/xdp_synproxy.c b/tools/testing/selftests/bpf/xdp_synproxy.c
+index d874ddfb39c46..8432836f3be2d 100644
+--- a/tools/testing/selftests/bpf/xdp_synproxy.c
++++ b/tools/testing/selftests/bpf/xdp_synproxy.c
+@@ -104,7 +104,8 @@ static void parse_options(int argc, char *argv[], unsigned int *ifindex, __u32 *
+ { "tc", no_argument, NULL, 'c' },
+ { NULL, 0, NULL, 0 },
+ };
+- unsigned long mss4, mss6, wscale, ttl;
++ unsigned long mss4, wscale, ttl;
++ unsigned long long mss6;
+ unsigned int tcpipopts_mask = 0;
+
+ if (argc < 2)
+@@ -286,7 +287,7 @@ static int syncookie_open_bpf_maps(__u32 prog_id, int *values_map_fd, int *ports
+
+ prog_info = (struct bpf_prog_info) {
+ .nr_map_ids = 8,
+- .map_ids = (__u64)map_ids,
++ .map_ids = (__u64)(unsigned long)map_ids,
+ };
+ info_len = sizeof(prog_info);
+
+diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
+index 4c52cc6f2f9cc..e8bbbdb77e0d5 100644
+--- a/tools/testing/selftests/cgroup/cgroup_util.c
++++ b/tools/testing/selftests/cgroup/cgroup_util.c
+@@ -555,6 +555,7 @@ int proc_mount_contains(const char *option)
+ ssize_t proc_read_text(int pid, bool thread, const char *item, char *buf, size_t size)
+ {
+ char path[PATH_MAX];
++ ssize_t ret;
+
+ if (!pid)
+ snprintf(path, sizeof(path), "/proc/%s/%s",
+@@ -562,8 +563,8 @@ ssize_t proc_read_text(int pid, bool thread, const char *item, char *buf, size_t
+ else
+ snprintf(path, sizeof(path), "/proc/%d/%s", pid, item);
+
+- size = read_text(path, buf, size);
+- return size < 0 ? -1 : size;
++ ret = read_text(path, buf, size);
++ return ret < 0 ? -1 : ret;
+ }
+
+ int proc_read_strstr(int pid, bool thread, const char *item, const char *needle)
+diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+index 9de1d123f4f5d..a08c02abde121 100755
+--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
++++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+@@ -496,8 +496,8 @@ dummy_reporter_test()
+
+ check_reporter_info dummy healthy 3 3 10 true
+
+- echo 8192> $DEBUGFS_DIR/health/binary_len
+- check_fail $? "Failed set dummy reporter binary len to 8192"
++ echo 8192 > $DEBUGFS_DIR/health/binary_len
++ check_err $? "Failed set dummy reporter binary len to 8192"
+
+ local dump=$(devlink health dump show $DL_HANDLE reporter dummy -j)
+ check_err $? "Failed show dump of dummy reporter"
+diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh
+index a90f394f9aa90..d374878cc0ba9 100755
+--- a/tools/testing/selftests/efivarfs/efivarfs.sh
++++ b/tools/testing/selftests/efivarfs/efivarfs.sh
+@@ -87,6 +87,11 @@ test_create_read()
+ {
+ local file=$efivarfs_mount/$FUNCNAME-$test_guid
+ ./create-read $file
++ if [ $? -ne 0 ]; then
++ echo "create and read $file failed"
++ file_cleanup $file
++ exit 1
++ fi
+ file_cleanup $file
+ }
+
+diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+index 3145b0f1835c3..27a68bbe778be 100644
+--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
++++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+@@ -38,11 +38,18 @@ cnt_trace() {
+
+ test_event_enabled() {
+ val=$1
++ check_times=10 # wait for 10 * SLEEP_TIME at most
+
+- e=`cat $EVENT_ENABLE`
+- if [ "$e" != $val ]; then
+- fail "Expected $val but found $e"
+- fi
++ while [ $check_times -ne 0 ]; do
++ e=`cat $EVENT_ENABLE`
++ if [ "$e" == $val ]; then
++ return 0
++ fi
++ sleep $SLEEP_TIME
++ check_times=$((check_times - 1))
++ done
++
++ fail "Expected $val but found $e"
+ }
+
+ run_enable_disable() {
+diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+index b48e1833bc896..76645aaf2b58f 100755
+--- a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
++++ b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+@@ -35,6 +35,8 @@ cleanup() {
+ for i in 1 2;do ip netns del nsrouter$i;done
+ }
+
++trap cleanup EXIT
++
+ ipv4() {
+ echo -n 192.168.$1.2
+ }
+@@ -146,11 +148,17 @@ ip netns exec nsclient1 nft -f - <<EOF
+ table inet filter {
+ counter unknown { }
+ counter related { }
++ counter redir4 { }
++ counter redir6 { }
+ chain input {
+ type filter hook input priority 0; policy accept;
+- meta l4proto { icmp, icmpv6 } ct state established,untracked accept
+
++ icmp type "redirect" ct state "related" counter name "redir4" accept
++ icmpv6 type "nd-redirect" ct state "related" counter name "redir6" accept
++
++ meta l4proto { icmp, icmpv6 } ct state established,untracked accept
+ meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
++
+ counter name "unknown" drop
+ }
+ }
+@@ -279,5 +287,29 @@ else
+ echo "ERROR: icmp error RELATED state test has failed"
+ fi
+
+-cleanup
++# add 'bad' route, expect icmp REDIRECT to be generated
++ip netns exec nsclient1 ip route add 192.168.1.42 via 192.168.1.1
++ip netns exec nsclient1 ip route add dead:1::42 via dead:1::1
++
++ip netns exec "nsclient1" ping -q -c 2 192.168.1.42 > /dev/null
++
++expect="packets 1 bytes 112"
++check_counter nsclient1 "redir4" "$expect"
++if [ $? -ne 0 ];then
++ ret=1
++fi
++
++ip netns exec "nsclient1" ping -c 1 dead:1::42 > /dev/null
++expect="packets 1 bytes 192"
++check_counter nsclient1 "redir6" "$expect"
++if [ $? -ne 0 ];then
++ ret=1
++fi
++
++if [ $ret -eq 0 ];then
++ echo "PASS: icmp redirects had RELATED state"
++else
++ echo "ERROR: icmp redirect RELATED state test has failed"
++fi
++
+ exit $ret
+diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+index fbbdffdb2e5d2..f20d1c166d1e4 100644
+--- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
++++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+@@ -24,6 +24,7 @@ static int check_cpu_dscr_default(char *file, unsigned long val)
+ rc = read(fd, buf, sizeof(buf));
+ if (rc == -1) {
+ perror("read() failed");
++ close(fd);
+ return 1;
+ }
+ close(fd);
+@@ -65,8 +66,10 @@ static int check_all_cpu_dscr_defaults(unsigned long val)
+ if (access(file, F_OK))
+ continue;
+
+- if (check_cpu_dscr_default(file, val))
++ if (check_cpu_dscr_default(file, val)) {
++ closedir(sysfs);
+ return 1;
++ }
+ }
+ closedir(sysfs);
+ return 0;
+diff --git a/tools/testing/selftests/proc/proc-uptime-002.c b/tools/testing/selftests/proc/proc-uptime-002.c
+index e7ceabed7f51f..7d0aa22bdc12b 100644
+--- a/tools/testing/selftests/proc/proc-uptime-002.c
++++ b/tools/testing/selftests/proc/proc-uptime-002.c
+@@ -17,6 +17,7 @@
+ // while shifting across CPUs.
+ #undef NDEBUG
+ #include <assert.h>
++#include <errno.h>
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <stdlib.h>
+@@ -54,7 +55,7 @@ int main(void)
+ len += sizeof(unsigned long);
+ free(m);
+ m = malloc(len);
+- } while (sys_sched_getaffinity(0, len, m) == -EINVAL);
++ } while (sys_sched_getaffinity(0, len, m) == -1 && errno == EINVAL);
+
+ fd = open("/proc/uptime", O_RDONLY);
+ assert(fd >= 0);
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-04 11:38 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-04 11:38 UTC (permalink / raw
To: gentoo-commits
commit: fef50508c3386cf852a065b4ef6d4f5b723cc859
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 4 11:38:19 2023 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Jan 4 11:38:19 2023 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=fef50508
Linux patch 6.0.17
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1016_linux-6.0.17.patch | 2726 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 2730 insertions(+)
diff --git a/0000_README b/0000_README
index 44fc4c7e..b0d2c4b3 100644
--- a/0000_README
+++ b/0000_README
@@ -107,6 +107,10 @@ Patch: 1015_linux-6.0.16.patch
From: http://www.kernel.org
Desc: Linux 6.0.16
+Patch: 1016_linux-6.0.17.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.17
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1016_linux-6.0.17.patch b/1016_linux-6.0.17.patch
new file mode 100644
index 00000000..c6bffa77
--- /dev/null
+++ b/1016_linux-6.0.17.patch
@@ -0,0 +1,2726 @@
+diff --git a/Documentation/trace/kprobes.rst b/Documentation/trace/kprobes.rst
+index f318bceda1e67..97d086b23ce85 100644
+--- a/Documentation/trace/kprobes.rst
++++ b/Documentation/trace/kprobes.rst
+@@ -131,8 +131,7 @@ For example, if the function is non-recursive and is called with a
+ spinlock held, maxactive = 1 should be enough. If the function is
+ non-recursive and can never relinquish the CPU (e.g., via a semaphore
+ or preemption), NR_CPUS should be enough. If maxactive <= 0, it is
+-set to a default value. If CONFIG_PREEMPT is enabled, the default
+-is max(10, 2*NR_CPUS). Otherwise, the default is NR_CPUS.
++set to a default value: max(10, 2*NR_CPUS).
+
+ It's not a disaster if you set maxactive too low; you'll just miss
+ some probes. In the kretprobe struct, the nmissed field is set to
+diff --git a/Makefile b/Makefile
+index ff8d88b113919..a0ddac5b7cafb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 16
++SUBLEVEL = 17
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 0b8a858aa8479..5a873d4fbd7b9 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -875,6 +875,7 @@ void __noreturn rtas_halt(void)
+
+ /* Must be in the RMO region, so we place it here */
+ static char rtas_os_term_buf[2048];
++static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE;
+
+ void rtas_os_term(char *str)
+ {
+@@ -886,16 +887,20 @@ void rtas_os_term(char *str)
+ * this property may terminate the partition which we want to avoid
+ * since it interferes with panic_timeout.
+ */
+- if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
+- RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
++ if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE)
+ return;
+
+ snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
+
++ /*
++ * Keep calling as long as RTAS returns a "try again" status,
++ * but don't use rtas_busy_delay(), which potentially
++ * schedules.
++ */
+ do {
+- status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
++ status = rtas_call(ibm_os_term_token, 1, 1, NULL,
+ __pa(rtas_os_term_buf));
+- } while (rtas_busy_delay(status));
++ } while (rtas_busy_delay_time(status));
+
+ if (status != 0)
+ printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
+@@ -1255,6 +1260,13 @@ void __init rtas_initialize(void)
+ no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry);
+ rtas.entry = no_entry ? rtas.base : entry;
+
++ /*
++ * Discover these now to avoid device tree lookups in the
++ * panic path.
++ */
++ if (of_property_read_bool(rtas.dev, "ibm,extended-os-term"))
++ ibm_os_term_token = rtas_token("ibm,os-term");
++
+ /* If RTAS was found, allocate the RMO buffer for it and look for
+ * the stop-self token if any
+ */
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 528ca21044a57..7d2ca122362fa 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -5385,8 +5385,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfqd->lock, flags);
+- bfq_exit_bfqq(bfqd, bfqq);
+ bic_set_bfqq(bic, NULL, is_sync);
++ bfq_exit_bfqq(bfqd, bfqq);
+ spin_unlock_irqrestore(&bfqd->lock, flags);
+ }
+ }
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index c8f0c865bf4ed..ee517fb06aa6f 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -33,6 +33,7 @@
+ #include "blk-cgroup.h"
+ #include "blk-ioprio.h"
+ #include "blk-throttle.h"
++#include "blk-rq-qos.h"
+
+ /*
+ * blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
+@@ -263,29 +264,13 @@ err_free:
+ return NULL;
+ }
+
+-struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
+- struct request_queue *q, bool update_hint)
++static void blkg_update_hint(struct blkcg *blkcg, struct blkcg_gq *blkg)
+ {
+- struct blkcg_gq *blkg;
+-
+- /*
+- * Hint didn't match. Look up from the radix tree. Note that the
+- * hint can only be updated under queue_lock as otherwise @blkg
+- * could have already been removed from blkg_tree. The caller is
+- * responsible for grabbing queue_lock if @update_hint.
+- */
+- blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
+- if (blkg && blkg->q == q) {
+- if (update_hint) {
+- lockdep_assert_held(&q->queue_lock);
+- rcu_assign_pointer(blkcg->blkg_hint, blkg);
+- }
+- return blkg;
+- }
++ lockdep_assert_held(&blkg->q->queue_lock);
+
+- return NULL;
++ if (blkcg != &blkcg_root && blkg != rcu_dereference(blkcg->blkg_hint))
++ rcu_assign_pointer(blkcg->blkg_hint, blkg);
+ }
+-EXPORT_SYMBOL_GPL(blkg_lookup_slowpath);
+
+ /*
+ * If @new_blkg is %NULL, this function tries to allocate a new one as
+@@ -324,7 +309,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
+
+ /* link parent */
+ if (blkcg_parent(blkcg)) {
+- blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
++ blkg->parent = blkg_lookup(blkcg_parent(blkcg), q);
+ if (WARN_ON_ONCE(!blkg->parent)) {
+ ret = -ENODEV;
+ goto err_put_css;
+@@ -397,9 +382,11 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
+ return blkg;
+
+ spin_lock_irqsave(&q->queue_lock, flags);
+- blkg = __blkg_lookup(blkcg, q, true);
+- if (blkg)
++ blkg = blkg_lookup(blkcg, q);
++ if (blkg) {
++ blkg_update_hint(blkcg, blkg);
+ goto found;
++ }
+
+ /*
+ * Create blkgs walking down from blkcg_root to @blkcg, so that all
+@@ -412,7 +399,7 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
+ struct blkcg_gq *ret_blkg = q->root_blkg;
+
+ while (parent) {
+- blkg = __blkg_lookup(parent, q, false);
++ blkg = blkg_lookup(parent, q);
+ if (blkg) {
+ /* remember closest blkg */
+ ret_blkg = blkg;
+@@ -476,14 +463,9 @@ static void blkg_destroy(struct blkcg_gq *blkg)
+ percpu_ref_kill(&blkg->refcnt);
+ }
+
+-/**
+- * blkg_destroy_all - destroy all blkgs associated with a request_queue
+- * @q: request_queue of interest
+- *
+- * Destroy all blkgs associated with @q.
+- */
+-static void blkg_destroy_all(struct request_queue *q)
++static void blkg_destroy_all(struct gendisk *disk)
+ {
++ struct request_queue *q = disk->queue;
+ struct blkcg_gq *blkg, *n;
+ int count = BLKG_DESTROY_BATCH_SIZE;
+
+@@ -621,12 +603,18 @@ static struct blkcg_gq *blkg_lookup_check(struct blkcg *blkcg,
+ const struct blkcg_policy *pol,
+ struct request_queue *q)
+ {
++ struct blkcg_gq *blkg;
++
+ WARN_ON_ONCE(!rcu_read_lock_held());
+ lockdep_assert_held(&q->queue_lock);
+
+ if (!blkcg_policy_enabled(q, pol))
+ return ERR_PTR(-EOPNOTSUPP);
+- return __blkg_lookup(blkcg, q, true /* update_hint */);
++
++ blkg = blkg_lookup(blkcg, q);
++ if (blkg)
++ blkg_update_hint(blkcg, blkg);
++ return blkg;
+ }
+
+ /**
+@@ -724,7 +712,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ struct blkcg_gq *new_blkg;
+
+ parent = blkcg_parent(blkcg);
+- while (parent && !__blkg_lookup(parent, q, false)) {
++ while (parent && !blkg_lookup(parent, q)) {
+ pos = parent;
+ parent = blkcg_parent(parent);
+ }
+@@ -915,8 +903,7 @@ static void blkcg_fill_root_iostats(void)
+ class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
+ while ((dev = class_dev_iter_next(&iter))) {
+ struct block_device *bdev = dev_to_bdev(dev);
+- struct blkcg_gq *blkg =
+- blk_queue_root_blkg(bdev_get_queue(bdev));
++ struct blkcg_gq *blkg = bdev->bd_disk->queue->root_blkg;
+ struct blkg_iostat tmp;
+ int cpu;
+ unsigned long flags;
+@@ -1255,18 +1242,9 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
+ return 0;
+ }
+
+-/**
+- * blkcg_init_queue - initialize blkcg part of request queue
+- * @q: request_queue to initialize
+- *
+- * Called from blk_alloc_queue(). Responsible for initializing blkcg
+- * part of new request_queue @q.
+- *
+- * RETURNS:
+- * 0 on success, -errno on failure.
+- */
+-int blkcg_init_queue(struct request_queue *q)
++int blkcg_init_disk(struct gendisk *disk)
+ {
++ struct request_queue *q = disk->queue;
+ struct blkcg_gq *new_blkg, *blkg;
+ bool preloaded;
+ int ret;
+@@ -1295,21 +1273,22 @@ int blkcg_init_queue(struct request_queue *q)
+ if (ret)
+ goto err_destroy_all;
+
+- ret = blk_throtl_init(q);
++ ret = blk_throtl_init(disk);
+ if (ret)
+- goto err_destroy_all;
++ goto err_ioprio_exit;
+
+ ret = blk_iolatency_init(q);
+- if (ret) {
+- blk_throtl_exit(q);
+- blk_ioprio_exit(q);
+- goto err_destroy_all;
+- }
++ if (ret)
++ goto err_throtl_exit;
+
+ return 0;
+
++err_throtl_exit:
++ blk_throtl_exit(disk);
++err_ioprio_exit:
++ blk_ioprio_exit(q);
+ err_destroy_all:
+- blkg_destroy_all(q);
++ blkg_destroy_all(disk);
+ return ret;
+ err_unlock:
+ spin_unlock_irq(&q->queue_lock);
+@@ -1318,16 +1297,11 @@ err_unlock:
+ return PTR_ERR(blkg);
+ }
+
+-/**
+- * blkcg_exit_queue - exit and release blkcg part of request_queue
+- * @q: request_queue being released
+- *
+- * Called from blk_exit_queue(). Responsible for exiting blkcg part.
+- */
+-void blkcg_exit_queue(struct request_queue *q)
++void blkcg_exit_disk(struct gendisk *disk)
+ {
+- blkg_destroy_all(q);
+- blk_throtl_exit(q);
++ blkg_destroy_all(disk);
++ rq_qos_exit(disk->queue);
++ blk_throtl_exit(disk);
+ }
+
+ static void blkcg_bind(struct cgroup_subsys_state *root_css)
+diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
+index d2724d1dd7c9b..aa2b286bc825f 100644
+--- a/block/blk-cgroup.h
++++ b/block/blk-cgroup.h
+@@ -178,10 +178,8 @@ struct blkcg_policy {
+ extern struct blkcg blkcg_root;
+ extern bool blkcg_debug_stats;
+
+-struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
+- struct request_queue *q, bool update_hint);
+-int blkcg_init_queue(struct request_queue *q);
+-void blkcg_exit_queue(struct request_queue *q);
++int blkcg_init_disk(struct gendisk *disk);
++void blkcg_exit_disk(struct gendisk *disk);
+
+ /* Blkio controller policy registration */
+ int blkcg_policy_register(struct blkcg_policy *pol);
+@@ -227,22 +225,21 @@ static inline bool bio_issue_as_root_blkg(struct bio *bio)
+ }
+
+ /**
+- * __blkg_lookup - internal version of blkg_lookup()
++ * blkg_lookup - lookup blkg for the specified blkcg - q pair
+ * @blkcg: blkcg of interest
+ * @q: request_queue of interest
+- * @update_hint: whether to update lookup hint with the result or not
+ *
+- * This is internal version and shouldn't be used by policy
+- * implementations. Looks up blkgs for the @blkcg - @q pair regardless of
+- * @q's bypass state. If @update_hint is %true, the caller should be
+- * holding @q->queue_lock and lookup hint is updated on success.
++ * Lookup blkg for the @blkcg - @q pair.
++
++ * Must be called in a RCU critical section.
+ */
+-static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
+- struct request_queue *q,
+- bool update_hint)
++static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
++ struct request_queue *q)
+ {
+ struct blkcg_gq *blkg;
+
++ WARN_ON_ONCE(!rcu_read_lock_held());
++
+ if (blkcg == &blkcg_root)
+ return q->root_blkg;
+
+@@ -250,33 +247,10 @@ static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
+ if (blkg && blkg->q == q)
+ return blkg;
+
+- return blkg_lookup_slowpath(blkcg, q, update_hint);
+-}
+-
+-/**
+- * blkg_lookup - lookup blkg for the specified blkcg - q pair
+- * @blkcg: blkcg of interest
+- * @q: request_queue of interest
+- *
+- * Lookup blkg for the @blkcg - @q pair. This function should be called
+- * under RCU read lock.
+- */
+-static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
+- struct request_queue *q)
+-{
+- WARN_ON_ONCE(!rcu_read_lock_held());
+- return __blkg_lookup(blkcg, q, false);
+-}
+-
+-/**
+- * blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair
+- * @q: request_queue of interest
+- *
+- * Lookup blkg for @q at the root level. See also blkg_lookup().
+- */
+-static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+-{
+- return q->root_blkg;
++ blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
++ if (blkg && blkg->q != q)
++ blkg = NULL;
++ return blkg;
+ }
+
+ /**
+@@ -373,8 +347,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
+ */
+ #define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \
+ css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \
+- if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
+- (p_blkg)->q, false)))
++ if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css), \
++ (p_blkg)->q)))
+
+ /**
+ * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
+@@ -388,8 +362,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
+ */
+ #define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \
+ css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \
+- if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
+- (p_blkg)->q, false)))
++ if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css), \
++ (p_blkg)->q)))
+
+ bool __blkcg_punt_bio_submit(struct bio *bio);
+
+@@ -507,10 +481,8 @@ struct blkcg {
+ };
+
+ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
+-static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+-{ return NULL; }
+-static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
+-static inline void blkcg_exit_queue(struct request_queue *q) { }
++static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
++static inline void blkcg_exit_disk(struct gendisk *disk) { }
+ static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
+ static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
+ static inline int blkcg_activate_policy(struct request_queue *q,
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 35cf744ea9d11..f84a6ed440c93 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -2276,8 +2276,9 @@ void blk_throtl_bio_endio(struct bio *bio)
+ }
+ #endif
+
+-int blk_throtl_init(struct request_queue *q)
++int blk_throtl_init(struct gendisk *disk)
+ {
++ struct request_queue *q = disk->queue;
+ struct throtl_data *td;
+ int ret;
+
+@@ -2319,8 +2320,10 @@ int blk_throtl_init(struct request_queue *q)
+ return ret;
+ }
+
+-void blk_throtl_exit(struct request_queue *q)
++void blk_throtl_exit(struct gendisk *disk)
+ {
++ struct request_queue *q = disk->queue;
++
+ BUG_ON(!q->td);
+ del_timer_sync(&q->td->service_queue.pending_timer);
+ throtl_shutdown_wq(q);
+diff --git a/block/blk-throttle.h b/block/blk-throttle.h
+index ee7299e6dea91..e8c2b3d4a18b8 100644
+--- a/block/blk-throttle.h
++++ b/block/blk-throttle.h
+@@ -159,14 +159,14 @@ static inline struct throtl_grp *blkg_to_tg(struct blkcg_gq *blkg)
+ * Internal throttling interface
+ */
+ #ifndef CONFIG_BLK_DEV_THROTTLING
+-static inline int blk_throtl_init(struct request_queue *q) { return 0; }
+-static inline void blk_throtl_exit(struct request_queue *q) { }
++static inline int blk_throtl_init(struct gendisk *disk) { return 0; }
++static inline void blk_throtl_exit(struct gendisk *disk) { }
+ static inline void blk_throtl_register_queue(struct request_queue *q) { }
+ static inline bool blk_throtl_bio(struct bio *bio) { return false; }
+ static inline void blk_throtl_cancel_bios(struct request_queue *q) { }
+ #else /* CONFIG_BLK_DEV_THROTTLING */
+-int blk_throtl_init(struct request_queue *q);
+-void blk_throtl_exit(struct request_queue *q);
++int blk_throtl_init(struct gendisk *disk);
++void blk_throtl_exit(struct gendisk *disk);
+ void blk_throtl_register_queue(struct request_queue *q);
+ bool __blk_throtl_bio(struct bio *bio);
+ void blk_throtl_cancel_bios(struct request_queue *q);
+diff --git a/block/blk.h b/block/blk.h
+index ff0bec16f0fa0..c24afffc36780 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -429,7 +429,7 @@ static inline struct kmem_cache *blk_get_queue_kmem_cache(bool srcu)
+ }
+ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu);
+
+-int disk_scan_partitions(struct gendisk *disk, fmode_t mode);
++int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner);
+
+ int disk_alloc_events(struct gendisk *disk);
+ void disk_add_events(struct gendisk *disk);
+diff --git a/block/genhd.c b/block/genhd.c
+index 28654723bc2b2..a7b9623031957 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -356,7 +356,7 @@ void disk_uevent(struct gendisk *disk, enum kobject_action action)
+ }
+ EXPORT_SYMBOL_GPL(disk_uevent);
+
+-int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
++int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner)
+ {
+ struct block_device *bdev;
+
+@@ -366,6 +366,9 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
+ return -EINVAL;
+ if (disk->open_partitions)
+ return -EBUSY;
++ /* Someone else has bdev exclusively open? */
++ if (disk->part0->bd_holder && disk->part0->bd_holder != owner)
++ return -EBUSY;
+
+ set_bit(GD_NEED_PART_SCAN, &disk->state);
+ bdev = blkdev_get_by_dev(disk_devt(disk), mode, NULL);
+@@ -499,7 +502,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
+
+ bdev_add(disk->part0, ddev->devt);
+ if (get_capacity(disk))
+- disk_scan_partitions(disk, FMODE_READ);
++ disk_scan_partitions(disk, FMODE_READ, NULL);
+
+ /*
+ * Announce the disk and partitions after all partitions are
+@@ -1154,7 +1157,8 @@ static void disk_release(struct device *dev)
+ !test_bit(GD_ADDED, &disk->state))
+ blk_mq_exit_queue(disk->queue);
+
+- blkcg_exit_queue(disk->queue);
++ blkcg_exit_disk(disk);
++
+ bioset_exit(&disk->bio_split);
+
+ disk_release_events(disk);
+@@ -1367,7 +1371,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
+ if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
+ goto out_destroy_part_tbl;
+
+- if (blkcg_init_queue(q))
++ if (blkcg_init_disk(disk))
+ goto out_erase_part0;
+
+ rand_initialize_disk(disk);
+diff --git a/block/ioctl.c b/block/ioctl.c
+index 60121e89052bc..96617512982e5 100644
+--- a/block/ioctl.c
++++ b/block/ioctl.c
+@@ -467,9 +467,10 @@ static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
+ * user space. Note the separate arg/argp parameters that are needed
+ * to deal with the compat_ptr() conversion.
+ */
+-static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
+- unsigned cmd, unsigned long arg, void __user *argp)
++static int blkdev_common_ioctl(struct file *file, fmode_t mode, unsigned cmd,
++ unsigned long arg, void __user *argp)
+ {
++ struct block_device *bdev = I_BDEV(file->f_mapping->host);
+ unsigned int max_sectors;
+
+ switch (cmd) {
+@@ -527,7 +528,8 @@ static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
+ return -EACCES;
+ if (bdev_is_partition(bdev))
+ return -EINVAL;
+- return disk_scan_partitions(bdev->bd_disk, mode & ~FMODE_EXCL);
++ return disk_scan_partitions(bdev->bd_disk, mode & ~FMODE_EXCL,
++ file);
+ case BLKTRACESTART:
+ case BLKTRACESTOP:
+ case BLKTRACETEARDOWN:
+@@ -605,7 +607,7 @@ long blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ break;
+ }
+
+- ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
++ ret = blkdev_common_ioctl(file, mode, cmd, arg, argp);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+
+@@ -674,7 +676,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ break;
+ }
+
+- ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
++ ret = blkdev_common_ioctl(file, mode, cmd, arg, argp);
+ if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
+ ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 510cdec375c4d..98daea0db9798 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -399,16 +399,68 @@ static const struct dmi_system_id medion_laptop[] = {
+ { }
+ };
+
++static const struct dmi_system_id asus_laptop[] = {
++ {
++ .ident = "Asus Vivobook K3402ZA",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
++ },
++ },
++ {
++ .ident = "Asus Vivobook K3502ZA",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
++ },
++ },
++ { }
++};
++
++static const struct dmi_system_id lenovo_laptop[] = {
++ {
++ .ident = "LENOVO IdeaPad Flex 5 14ALC7",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82R9"),
++ },
++ },
++ {
++ .ident = "LENOVO IdeaPad Flex 5 16ALC7",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82RA"),
++ },
++ },
++ { }
++};
++
++static const struct dmi_system_id schenker_gm_rg[] = {
++ {
++ .ident = "XMG CORE 15 (M22)",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
++ DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
++ },
++ },
++ { }
++};
++
+ struct irq_override_cmp {
+ const struct dmi_system_id *system;
+ unsigned char irq;
+ unsigned char triggering;
+ unsigned char polarity;
+ unsigned char shareable;
++ bool override;
+ };
+
+-static const struct irq_override_cmp skip_override_table[] = {
+- { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
++static const struct irq_override_cmp override_table[] = {
++ { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++ { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++ { lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++ { lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++ { schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
+ };
+
+ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+@@ -416,6 +468,17 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ {
+ int i;
+
++ for (i = 0; i < ARRAY_SIZE(override_table); i++) {
++ const struct irq_override_cmp *entry = &override_table[i];
++
++ if (dmi_check_system(entry->system) &&
++ entry->irq == gsi &&
++ entry->triggering == triggering &&
++ entry->polarity == polarity &&
++ entry->shareable == shareable)
++ return entry->override;
++ }
++
+ #ifdef CONFIG_X86
+ /*
+ * IRQ override isn't needed on modern AMD Zen systems and
+@@ -426,17 +489,6 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ return false;
+ #endif
+
+- for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
+- const struct irq_override_cmp *entry = &skip_override_table[i];
+-
+- if (dmi_check_system(entry->system) &&
+- entry->irq == gsi &&
+- entry->triggering == triggering &&
+- entry->polarity == polarity &&
+- entry->shareable == shareable)
+- return false;
+- }
+-
+ return true;
+ }
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index c1eca72b4575d..28d8c56cb4ddf 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -84,6 +84,7 @@ enum board_ids {
+ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void ahci_remove_one(struct pci_dev *dev);
+ static void ahci_shutdown_one(struct pci_dev *dev);
++static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
+ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+@@ -677,6 +678,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ ahci_save_initial_config(&pdev->dev, hpriv);
+ }
+
++static int ahci_pci_reset_controller(struct ata_host *host)
++{
++ struct pci_dev *pdev = to_pci_dev(host->dev);
++ struct ahci_host_priv *hpriv = host->private_data;
++ int rc;
++
++ rc = ahci_reset_controller(host);
++ if (rc)
++ return rc;
++
++ /*
++ * If platform firmware failed to enable ports, try to enable
++ * them here.
++ */
++ ahci_intel_pcs_quirk(pdev, hpriv);
++
++ return 0;
++}
++
+ static void ahci_pci_init_controller(struct ata_host *host)
+ {
+ struct ahci_host_priv *hpriv = host->private_data;
+@@ -871,7 +891,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
+ struct ata_host *host = pci_get_drvdata(pdev);
+ int rc;
+
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+ ahci_pci_init_controller(host);
+@@ -907,7 +927,7 @@ static int ahci_pci_device_resume(struct device *dev)
+ ahci_mcp89_apple_enable(pdev);
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+
+@@ -1788,12 +1808,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ /* save initial config */
+ ahci_pci_save_initial_config(pdev, hpriv);
+
+- /*
+- * If platform firmware failed to enable ports, try to enable
+- * them here.
+- */
+- ahci_intel_pcs_quirk(pdev, hpriv);
+-
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ) {
+ pi.flags |= ATA_FLAG_NCQ;
+@@ -1903,7 +1917,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ if (rc)
+ return rc;
+
+- rc = ahci_reset_controller(host);
++ rc = ahci_pci_reset_controller(host);
+ if (rc)
+ return rc;
+
+diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
+index 1b18ce5ebab1e..0913d3eb8d518 100644
+--- a/drivers/char/tpm/eventlog/acpi.c
++++ b/drivers/char/tpm/eventlog/acpi.c
+@@ -90,16 +90,21 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ return -ENODEV;
+
+ if (tbl->header.length <
+- sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
++ sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
++ acpi_put_table((struct acpi_table_header *)tbl);
+ return -ENODEV;
++ }
+
+ tpm2_phy = (void *)tbl + sizeof(*tbl);
+ len = tpm2_phy->log_area_minimum_length;
+
+ start = tpm2_phy->log_area_start_address;
+- if (!start || !len)
++ if (!start || !len) {
++ acpi_put_table((struct acpi_table_header *)tbl);
+ return -ENODEV;
++ }
+
++ acpi_put_table((struct acpi_table_header *)tbl);
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
+ } else {
+ /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
+@@ -120,8 +125,10 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ break;
+ }
+
++ acpi_put_table((struct acpi_table_header *)buff);
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+ }
++
+ if (!len) {
+ dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
+ return -EIO;
+@@ -156,5 +163,4 @@ err:
+ kfree(log->bios_event_log);
+ log->bios_event_log = NULL;
+ return ret;
+-
+ }
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 65f8f179a27f0..16fc481d60950 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -676,12 +676,16 @@ static int crb_acpi_add(struct acpi_device *device)
+
+ /* Should the FIFO driver handle this? */
+ sm = buf->start_method;
+- if (sm == ACPI_TPM2_MEMORY_MAPPED)
+- return -ENODEV;
++ if (sm == ACPI_TPM2_MEMORY_MAPPED) {
++ rc = -ENODEV;
++ goto out;
++ }
+
+ priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
++ if (!priv) {
++ rc = -ENOMEM;
++ goto out;
++ }
+
+ if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
+ if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) {
+@@ -689,7 +693,8 @@ static int crb_acpi_add(struct acpi_device *device)
+ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
+ buf->header.length,
+ ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
+- return -EINVAL;
++ rc = -EINVAL;
++ goto out;
+ }
+ crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
+ priv->smc_func_id = crb_smc->smc_func_id;
+@@ -700,17 +705,23 @@ static int crb_acpi_add(struct acpi_device *device)
+
+ rc = crb_map_io(device, priv, buf);
+ if (rc)
+- return rc;
++ goto out;
+
+ chip = tpmm_chip_alloc(dev, &tpm_crb);
+- if (IS_ERR(chip))
+- return PTR_ERR(chip);
++ if (IS_ERR(chip)) {
++ rc = PTR_ERR(chip);
++ goto out;
++ }
+
+ dev_set_drvdata(&chip->dev, priv);
+ chip->acpi_dev_handle = device->handle;
+ chip->flags = TPM_CHIP_FLAG_TPM2;
+
+- return tpm_chip_register(chip);
++ rc = tpm_chip_register(chip);
++
++out:
++ acpi_put_table((struct acpi_table_header *)buf);
++ return rc;
+ }
+
+ static int crb_acpi_remove(struct acpi_device *device)
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index bcff6429e0b4f..ed5dabd3c72d6 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -125,6 +125,7 @@ static int check_acpi_tpm2(struct device *dev)
+ const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev);
+ struct acpi_table_tpm2 *tbl;
+ acpi_status st;
++ int ret = 0;
+
+ if (!aid || aid->driver_data != DEVICE_IS_TPM2)
+ return 0;
+@@ -132,8 +133,7 @@ static int check_acpi_tpm2(struct device *dev)
+ /* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2
+ * table is mandatory
+ */
+- st =
+- acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
++ st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
+ if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
+ dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
+ return -EINVAL;
+@@ -141,9 +141,10 @@ static int check_acpi_tpm2(struct device *dev)
+
+ /* The tpm2_crb driver handles this device */
+ if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
+- return -ENODEV;
++ ret = -ENODEV;
+
+- return 0;
++ acpi_put_table((struct acpi_table_header *)tbl);
++ return ret;
+ }
+ #else
+ static int check_acpi_tpm2(struct device *dev)
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 86e754b9400ff..5680543e97fdc 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -995,7 +995,10 @@
+ #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
+
+ #define USB_VENDOR_ID_PLANTRONICS 0x047f
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055
+ #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
+
+ #define USB_VENDOR_ID_PANASONIC 0x04da
+ #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 91a4d3fc30e08..372cbdd223e09 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1967,6 +1967,10 @@ static const struct hid_device_id mt_devices[] = {
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+ USB_VENDOR_ID_ELAN, 0x313a) },
+
++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
++ USB_VENDOR_ID_ELAN, 0x3148) },
++
+ /* Elitegroup panel */
+ { .driver_data = MT_CLS_SERIAL,
+ MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
+diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
+index e81b7cec2d124..3d414ae194acb 100644
+--- a/drivers/hid/hid-plantronics.c
++++ b/drivers/hid/hid-plantronics.c
+@@ -198,9 +198,18 @@ err:
+ }
+
+ static const struct hid_device_id plantronics_devices[] = {
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
+ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++ USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
++ .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+ { }
+ };
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index ec73720e239b2..15fa380b1f84b 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -452,7 +452,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
+ fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
+ }
+
+- if (report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova,
++ if (!dom || report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova,
+ write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
+ dev_err_ratelimited(
+ bank->parent_dev,
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 470a975e4be9b..cd7f8e6cfc717 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -509,13 +509,14 @@ static void md_end_flush(struct bio *bio)
+ struct md_rdev *rdev = bio->bi_private;
+ struct mddev *mddev = rdev->mddev;
+
++ bio_put(bio);
++
+ rdev_dec_pending(rdev, mddev);
+
+ if (atomic_dec_and_test(&mddev->flush_pending)) {
+ /* The pre-request flush has finished */
+ queue_work(md_wq, &mddev->flush_work);
+ }
+- bio_put(bio);
+ }
+
+ static void md_submit_flush_data(struct work_struct *ws);
+@@ -913,10 +914,12 @@ static void super_written(struct bio *bio)
+ } else
+ clear_bit(LastDev, &rdev->flags);
+
++ bio_put(bio);
++
++ rdev_dec_pending(rdev, mddev);
++
+ if (atomic_dec_and_test(&mddev->pending_writes))
+ wake_up(&mddev->sb_wait);
+- rdev_dec_pending(rdev, mddev);
+- bio_put(bio);
+ }
+
+ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
+diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
+index 6eaa6775b8885..d3b32eb798377 100644
+--- a/drivers/mfd/mt6360-core.c
++++ b/drivers/mfd/mt6360-core.c
+@@ -402,7 +402,7 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ struct mt6360_ddata *ddata = context;
+ u8 bank = *(u8 *)reg;
+ u8 reg_addr = *(u8 *)(reg + 1);
+- struct i2c_client *i2c = ddata->i2c[bank];
++ struct i2c_client *i2c;
+ bool crc_needed = false;
+ u8 *buf;
+ int buf_len = MT6360_ALLOC_READ_SIZE(val_size);
+@@ -410,6 +410,11 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ u8 crc;
+ int ret;
+
++ if (bank >= MT6360_SLAVE_MAX)
++ return -EINVAL;
++
++ i2c = ddata->i2c[bank];
++
+ if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ crc_needed = true;
+ ret = mt6360_xlate_pmicldo_addr(®_addr, val_size);
+@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *context, const void *val, size_t val_size)
+ struct mt6360_ddata *ddata = context;
+ u8 bank = *(u8 *)val;
+ u8 reg_addr = *(u8 *)(val + 1);
+- struct i2c_client *i2c = ddata->i2c[bank];
++ struct i2c_client *i2c;
+ bool crc_needed = false;
+ u8 *buf;
+ int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size);
+ int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE;
+ int ret;
+
++ if (bank >= MT6360_SLAVE_MAX)
++ return -EINVAL;
++
++ i2c = ddata->i2c[bank];
++
+ if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ crc_needed = true;
+ ret = mt6360_xlate_pmicldo_addr(®_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE);
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index ab36ec4797478..72f65f32abbc7 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2049,6 +2049,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ return;
+ kref_get(&vub300->kref);
+ if (enable) {
++ set_current_state(TASK_RUNNING);
+ mutex_lock(&vub300->irq_mutex);
+ if (vub300->irqs_queued) {
+ vub300->irqs_queued -= 1;
+@@ -2064,6 +2065,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ vub300_queue_poll_work(vub300, 0);
+ }
+ mutex_unlock(&vub300->irq_mutex);
++ set_current_state(TASK_INTERRUPTIBLE);
+ } else {
+ vub300->irq_enabled = 0;
+ }
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 6867620bcc986..529b424ef9b26 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -35,7 +35,7 @@
+ #define SQ_SIZE(q) ((q)->q_depth << (q)->sqes)
+ #define CQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_completion))
+
+-#define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc))
++#define SGES_PER_PAGE (NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+
+ /*
+ * These can be higher, but we need to ensure that any command doesn't
+@@ -144,9 +144,9 @@ struct nvme_dev {
+ mempool_t *iod_mempool;
+
+ /* shadow doorbell buffer support: */
+- u32 *dbbuf_dbs;
++ __le32 *dbbuf_dbs;
+ dma_addr_t dbbuf_dbs_dma_addr;
+- u32 *dbbuf_eis;
++ __le32 *dbbuf_eis;
+ dma_addr_t dbbuf_eis_dma_addr;
+
+ /* host memory buffer support: */
+@@ -210,10 +210,10 @@ struct nvme_queue {
+ #define NVMEQ_SQ_CMB 1
+ #define NVMEQ_DELETE_ERROR 2
+ #define NVMEQ_POLLED 3
+- u32 *dbbuf_sq_db;
+- u32 *dbbuf_cq_db;
+- u32 *dbbuf_sq_ei;
+- u32 *dbbuf_cq_ei;
++ __le32 *dbbuf_sq_db;
++ __le32 *dbbuf_cq_db;
++ __le32 *dbbuf_sq_ei;
++ __le32 *dbbuf_cq_ei;
+ struct completion delete_done;
+ };
+
+@@ -340,11 +340,11 @@ static inline int nvme_dbbuf_need_event(u16 event_idx, u16 new_idx, u16 old)
+ }
+
+ /* Update dbbuf and return true if an MMIO is required */
+-static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+- volatile u32 *dbbuf_ei)
++static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
++ volatile __le32 *dbbuf_ei)
+ {
+ if (dbbuf_db) {
+- u16 old_value;
++ u16 old_value, event_idx;
+
+ /*
+ * Ensure that the queue is written before updating
+@@ -352,8 +352,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ wmb();
+
+- old_value = *dbbuf_db;
+- *dbbuf_db = value;
++ old_value = le32_to_cpu(*dbbuf_db);
++ *dbbuf_db = cpu_to_le32(value);
+
+ /*
+ * Ensure that the doorbell is updated before reading the event
+@@ -363,7 +363,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ mb();
+
+- if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
++ event_idx = le32_to_cpu(*dbbuf_ei);
++ if (!nvme_dbbuf_need_event(event_idx, value, old_value))
+ return false;
+ }
+
+@@ -377,9 +378,9 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ */
+ static int nvme_pci_npages_prp(void)
+ {
+- unsigned nprps = DIV_ROUND_UP(NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE,
+- NVME_CTRL_PAGE_SIZE);
+- return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
++ unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
++ unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
++ return DIV_ROUND_UP(8 * nprps, NVME_CTRL_PAGE_SIZE - 8);
+ }
+
+ /*
+@@ -389,7 +390,7 @@ static int nvme_pci_npages_prp(void)
+ static int nvme_pci_npages_sgl(void)
+ {
+ return DIV_ROUND_UP(NVME_MAX_SEGS * sizeof(struct nvme_sgl_desc),
+- PAGE_SIZE);
++ NVME_CTRL_PAGE_SIZE);
+ }
+
+ static size_t nvme_pci_iod_alloc_size(void)
+@@ -720,7 +721,7 @@ static void nvme_pci_sgl_set_seg(struct nvme_sgl_desc *sge,
+ sge->length = cpu_to_le32(entries * sizeof(*sge));
+ sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
+ } else {
+- sge->length = cpu_to_le32(PAGE_SIZE);
++ sge->length = cpu_to_le32(NVME_CTRL_PAGE_SIZE);
+ sge->type = NVME_SGL_FMT_SEG_DESC << 4;
+ }
+ }
+diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
+index 94d3153bae54d..09537000d817d 100644
+--- a/drivers/nvme/target/passthru.c
++++ b/drivers/nvme/target/passthru.c
+@@ -333,14 +333,13 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
+ }
+
+ /*
+- * If there are effects for the command we are about to execute, or
+- * an end_req function we need to use nvme_execute_passthru_rq()
+- * synchronously in a work item seeing the end_req function and
+- * nvme_passthru_end() can't be called in the request done callback
+- * which is typically in interrupt context.
++ * If a command needs post-execution fixups, or there are any
++ * non-trivial effects, make sure to execute the command synchronously
++ * in a workqueue so that nvme_passthru_end gets called.
+ */
+ effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode);
+- if (req->p.use_workqueue || effects) {
++ if (req->p.use_workqueue ||
++ (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))) {
+ INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work);
+ req->p.rq = rq;
+ queue_work(nvmet_wq, &req->p.work);
+diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
+index f3fde013c4b8b..8d7737e0e2e02 100644
+--- a/drivers/rtc/rtc-msc313.c
++++ b/drivers/rtc/rtc-msc313.c
+@@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- clk = devm_clk_get(dev, NULL);
++ clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "No input reference clock\n");
+ return PTR_ERR(clk);
+ }
+
+- ret = clk_prepare_enable(clk);
+- if (ret) {
+- dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
+- return ret;
+- }
+-
+- ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
+- if (ret)
+- return ret;
+-
+ rate = clk_get_rate(clk);
+ writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+ writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index f81cdd83ec26e..7969881f126dc 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -90,6 +90,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ },
+ .driver_data = (void *)intel_tgl_bios,
+ },
++ {
++ /* quirk used for NUC15 LAPBC710 skew */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
++ },
++ .driver_data = (void *)intel_tgl_bios,
++ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index d3f3937d70052..e7d37b6000ad9 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -260,7 +260,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+ if (IS_ERR(qcom->icc_path_apps)) {
+ dev_err(dev, "failed to get apps-usb path: %ld\n",
+ PTR_ERR(qcom->icc_path_apps));
+- return PTR_ERR(qcom->icc_path_apps);
++ ret = PTR_ERR(qcom->icc_path_apps);
++ goto put_path_ddr;
+ }
+
+ if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
+@@ -273,17 +274,23 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+
+ if (ret) {
+ dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
+- return ret;
++ goto put_path_apps;
+ }
+
+ ret = icc_set_bw(qcom->icc_path_apps,
+ APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
+ if (ret) {
+ dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
+- return ret;
++ goto put_path_apps;
+ }
+
+ return 0;
++
++put_path_apps:
++ icc_put(qcom->icc_path_apps);
++put_path_ddr:
++ icc_put(qcom->icc_path_ddr);
++ return ret;
+ }
+
+ /**
+diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
+index 08d0c8797828c..9ce5e1f41c26f 100644
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -434,8 +434,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
+ current->mm->start_stack = current->mm->start_brk + stack_size;
+ #endif
+
+- if (create_elf_fdpic_tables(bprm, current->mm,
+- &exec_params, &interp_params) < 0)
++ retval = create_elf_fdpic_tables(bprm, current->mm, &exec_params,
++ &interp_params);
++ if (retval < 0)
+ goto error;
+
+ kdebug("- start_code %lx", current->mm->start_code);
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index 4992b43616a7a..ba6cc50af390f 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -122,8 +122,8 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
+ struct smb2_hdr *hdr = err_iov.iov_base;
+
+ if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER))
+- rc = -ENOMEM;
+- else if (hdr->Status == STATUS_STOPPED_ON_SYMLINK && oparms->cifs_sb) {
++ goto out;
++ if (hdr->Status == STATUS_STOPPED_ON_SYMLINK) {
+ rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
+ &data->symlink_target);
+ if (!rc) {
+diff --git a/fs/eventfd.c b/fs/eventfd.c
+index c0ffee99ad238..249ca6c0b7843 100644
+--- a/fs/eventfd.c
++++ b/fs/eventfd.c
+@@ -43,21 +43,7 @@ struct eventfd_ctx {
+ int id;
+ };
+
+-/**
+- * eventfd_signal - Adds @n to the eventfd counter.
+- * @ctx: [in] Pointer to the eventfd context.
+- * @n: [in] Value of the counter to be added to the eventfd internal counter.
+- * The value cannot be negative.
+- *
+- * This function is supposed to be called by the kernel in paths that do not
+- * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
+- * value, and we signal this as overflow condition by returning a EPOLLERR
+- * to poll(2).
+- *
+- * Returns the amount by which the counter was incremented. This will be less
+- * than @n if the counter has overflowed.
+- */
+-__u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
++__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask)
+ {
+ unsigned long flags;
+
+@@ -78,12 +64,31 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ n = ULLONG_MAX - ctx->count;
+ ctx->count += n;
+ if (waitqueue_active(&ctx->wqh))
+- wake_up_locked_poll(&ctx->wqh, EPOLLIN);
++ wake_up_locked_poll(&ctx->wqh, EPOLLIN | mask);
+ current->in_eventfd = 0;
+ spin_unlock_irqrestore(&ctx->wqh.lock, flags);
+
+ return n;
+ }
++
++/**
++ * eventfd_signal - Adds @n to the eventfd counter.
++ * @ctx: [in] Pointer to the eventfd context.
++ * @n: [in] Value of the counter to be added to the eventfd internal counter.
++ * The value cannot be negative.
++ *
++ * This function is supposed to be called by the kernel in paths that do not
++ * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
++ * value, and we signal this as overflow condition by returning a EPOLLERR
++ * to poll(2).
++ *
++ * Returns the amount by which the counter was incremented. This will be less
++ * than @n if the counter has overflowed.
++ */
++__u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
++{
++ return eventfd_signal_mask(ctx, n, 0);
++}
+ EXPORT_SYMBOL_GPL(eventfd_signal);
+
+ static void eventfd_free_ctx(struct eventfd_ctx *ctx)
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 8b56b94e2f56f..1b23cc16f957f 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -491,7 +491,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
+ */
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+-static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
++static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi,
++ unsigned pollflags)
+ {
+ struct eventpoll *ep_src;
+ unsigned long flags;
+@@ -522,16 +523,17 @@ static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
+ }
+ spin_lock_irqsave_nested(&ep->poll_wait.lock, flags, nests);
+ ep->nests = nests + 1;
+- wake_up_locked_poll(&ep->poll_wait, EPOLLIN);
++ wake_up_locked_poll(&ep->poll_wait, EPOLLIN | pollflags);
+ ep->nests = 0;
+ spin_unlock_irqrestore(&ep->poll_wait.lock, flags);
+ }
+
+ #else
+
+-static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
++static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi,
++ unsigned pollflags)
+ {
+- wake_up_poll(&ep->poll_wait, EPOLLIN);
++ wake_up_poll(&ep->poll_wait, EPOLLIN | pollflags);
+ }
+
+ #endif
+@@ -742,7 +744,7 @@ static void ep_free(struct eventpoll *ep)
+
+ /* We need to release all tasks waiting for these file */
+ if (waitqueue_active(&ep->poll_wait))
+- ep_poll_safewake(ep, NULL);
++ ep_poll_safewake(ep, NULL, 0);
+
+ /*
+ * We need to lock this because we could be hit by
+@@ -1208,7 +1210,7 @@ out_unlock:
+
+ /* We have to call this outside the lock */
+ if (pwake)
+- ep_poll_safewake(ep, epi);
++ ep_poll_safewake(ep, epi, pollflags & EPOLL_URING_WAKE);
+
+ if (!(epi->event.events & EPOLLEXCLUSIVE))
+ ewake = 1;
+@@ -1553,7 +1555,7 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
+
+ /* We have to call this outside the lock */
+ if (pwake)
+- ep_poll_safewake(ep, NULL);
++ ep_poll_safewake(ep, NULL, 0);
+
+ return 0;
+ }
+@@ -1629,7 +1631,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
+
+ /* We have to call this outside the lock */
+ if (pwake)
+- ep_poll_safewake(ep, NULL);
++ ep_poll_safewake(ep, NULL, 0);
+
+ return 0;
+ }
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 68eb1d33128be..d58100dc6e898 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1109,6 +1109,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ if (ofs_in_node >= max_addrs) {
+ f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
+ ofs_in_node, dni->ino, dni->nid, max_addrs);
++ f2fs_put_page(node_page, 1);
+ return false;
+ }
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index e06a0c478b39a..f168dce9b5861 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1358,8 +1358,7 @@ static int read_node_page(struct page *page, blk_opf_t op_flags)
+ return err;
+
+ /* NEW_ADDR can be seen, after cp_error drops some dirty node pages */
+- if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR) ||
+- is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
++ if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR)) {
+ ClearPageUptodate(page);
+ return -ENOENT;
+ }
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index a5db2e3b29801..6aa919e594834 100644
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -198,6 +198,8 @@ struct hfsplus_sb_info {
+ #define HFSPLUS_SB_HFSX 3
+ #define HFSPLUS_SB_CASEFOLD 4
+ #define HFSPLUS_SB_NOBARRIER 5
++#define HFSPLUS_SB_UID 6
++#define HFSPLUS_SB_GID 7
+
+ static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
+ {
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+index aeab83ed1c9c6..b675581aa9d0f 100644
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -192,11 +192,11 @@ static void hfsplus_get_perms(struct inode *inode,
+ mode = be16_to_cpu(perms->mode);
+
+ i_uid_write(inode, be32_to_cpu(perms->owner));
+- if (!i_uid_read(inode) && !mode)
++ if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode))
+ inode->i_uid = sbi->uid;
+
+ i_gid_write(inode, be32_to_cpu(perms->group));
+- if (!i_gid_read(inode) && !mode)
++ if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode))
+ inode->i_gid = sbi->gid;
+
+ if (dir) {
+diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
+index 047e05c575601..c94a58762ad6d 100644
+--- a/fs/hfsplus/options.c
++++ b/fs/hfsplus/options.c
+@@ -140,6 +140,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ if (!uid_valid(sbi->uid)) {
+ pr_err("invalid uid specified\n");
+ return 0;
++ } else {
++ set_bit(HFSPLUS_SB_UID, &sbi->flags);
+ }
+ break;
+ case opt_gid:
+@@ -151,6 +153,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ if (!gid_valid(sbi->gid)) {
+ pr_err("invalid gid specified\n");
+ return 0;
++ } else {
++ set_bit(HFSPLUS_SB_GID, &sbi->flags);
+ }
+ break;
+ case opt_part:
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index 71f870d497aed..578c2bcfb1d93 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -101,6 +101,10 @@ static int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
+
+ asize = le32_to_cpu(attr->size);
+ run_off = le16_to_cpu(attr->nres.run_off);
++
++ if (run_off > asize)
++ return -EINVAL;
++
+ err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn,
+ vcn ? *vcn : svcn, Add2Ptr(attr, run_off),
+ asize - run_off);
+@@ -1217,6 +1221,11 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ CLST svcn, evcn;
+ u16 ro;
+
++ if (!ni) {
++ /* Is record corrupted? */
++ return -ENOENT;
++ }
++
+ attr = ni_find_attr(ni, NULL, NULL, type, name, name_len, &vcn, NULL);
+ if (!attr) {
+ /* Is record corrupted? */
+@@ -1232,6 +1241,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ }
+
+ ro = le16_to_cpu(attr->nres.run_off);
++
++ if (ro > le32_to_cpu(attr->size))
++ return -EINVAL;
++
+ err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
+ if (err < 0)
+@@ -1901,6 +1914,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
+ u16 le_sz;
+ u16 roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
+ evcn1 - 1, svcn, Add2Ptr(attr, roff),
+ le32_to_cpu(attr->size) - roff);
+diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c
+index bad6d8a849a24..c0c6bcbc8c05c 100644
+--- a/fs/ntfs3/attrlist.c
++++ b/fs/ntfs3/attrlist.c
+@@ -68,6 +68,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
+
+ run_init(&ni->attr_list.run);
+
++ if (run_off > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = run_unpack_ex(&ni->attr_list.run, ni->mi.sbi, ni->mi.rno,
+ 0, le64_to_cpu(attr->nres.evcn), 0,
+ Add2Ptr(attr, run_off),
+diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
+index 087282cb130b7..bb29bc1782fb2 100644
+--- a/fs/ntfs3/bitmap.c
++++ b/fs/ntfs3/bitmap.c
+@@ -661,7 +661,7 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
+ if (!wnd->bits_last)
+ wnd->bits_last = wbits;
+
+- wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS);
++ wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
+ if (!wnd->free_bits)
+ return -ENOMEM;
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 381a38a06ec22..b1b476fb7229b 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -568,6 +568,12 @@ static int ni_repack(struct ntfs_inode *ni)
+ }
+
+ roff = le16_to_cpu(attr->nres.run_off);
++
++ if (roff > le32_to_cpu(attr->size)) {
++ err = -EINVAL;
++ break;
++ }
++
+ err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff),
+ le32_to_cpu(attr->size) - roff);
+@@ -1589,6 +1595,9 @@ int ni_delete_all(struct ntfs_inode *ni)
+ asize = le32_to_cpu(attr->size);
+ roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > asize)
++ return -EINVAL;
++
+ /* run==1 means unpack and deallocate. */
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff), asize - roff);
+@@ -2291,6 +2300,11 @@ remove_wof:
+ asize = le32_to_cpu(attr->size);
+ roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > asize) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ /*run==1 Means unpack and deallocate. */
+ run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ Add2Ptr(attr, roff), asize - roff);
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index e7c494005122c..4236194af35ee 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -1132,7 +1132,7 @@ static int read_log_page(struct ntfs_log *log, u32 vbo,
+ return -EINVAL;
+
+ if (!*buffer) {
+- to_free = kmalloc(bytes, GFP_NOFS);
++ to_free = kmalloc(log->page_size, GFP_NOFS);
+ if (!to_free)
+ return -ENOMEM;
+ *buffer = to_free;
+@@ -1180,10 +1180,7 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ struct restart_info *info)
+ {
+ u32 skip, vbo;
+- struct RESTART_HDR *r_page = kmalloc(DefaultLogPageSize, GFP_NOFS);
+-
+- if (!r_page)
+- return -ENOMEM;
++ struct RESTART_HDR *r_page = NULL;
+
+ /* Determine which restart area we are looking for. */
+ if (first) {
+@@ -1197,7 +1194,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ /* Loop continuously until we succeed. */
+ for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
+ bool usa_error;
+- u32 sys_page_size;
+ bool brst, bchk;
+ struct RESTART_AREA *ra;
+
+@@ -1251,24 +1247,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ goto check_result;
+ }
+
+- /* Read the entire restart area. */
+- sys_page_size = le32_to_cpu(r_page->sys_page_size);
+- if (DefaultLogPageSize != sys_page_size) {
+- kfree(r_page);
+- r_page = kzalloc(sys_page_size, GFP_NOFS);
+- if (!r_page)
+- return -ENOMEM;
+-
+- if (read_log_page(log, vbo,
+- (struct RECORD_PAGE_HDR **)&r_page,
+- &usa_error)) {
+- /* Ignore any errors. */
+- kfree(r_page);
+- r_page = NULL;
+- continue;
+- }
+- }
+-
+ if (is_client_area_valid(r_page, usa_error)) {
+ info->valid_page = true;
+ ra = Add2Ptr(r_page, le16_to_cpu(r_page->ra_off));
+@@ -2727,6 +2705,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
+ return false;
+ }
+
++ if (run_off > asize)
++ return false;
++
+ if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
+ Add2Ptr(attr, run_off), asize - run_off) < 0) {
+ return false;
+@@ -4771,6 +4752,12 @@ fake_attr:
+ u16 roff = le16_to_cpu(attr->nres.run_off);
+ CLST svcn = le64_to_cpu(attr->nres.svcn);
+
++ if (roff > t32) {
++ kfree(oa->attr);
++ oa->attr = NULL;
++ goto fake_attr;
++ }
++
+ err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
+ le64_to_cpu(attr->nres.evcn), svcn,
+ Add2Ptr(attr, roff), t32 - roff);
+diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
+index 4ed15f64b17f6..b6e22bcb929ba 100644
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -1849,9 +1849,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ goto out;
+ }
+
+- root_sdh = resident_data(attr);
++ root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ if (root_sdh->type != ATTR_ZERO ||
+- root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH) {
++ root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH ||
++ offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) {
+ err = -EINVAL;
+ goto out;
+ }
+@@ -1867,9 +1868,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ goto out;
+ }
+
+- root_sii = resident_data(attr);
++ root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ if (root_sii->type != ATTR_ZERO ||
+- root_sii->rule != NTFS_COLLATION_TYPE_UINT) {
++ root_sii->rule != NTFS_COLLATION_TYPE_UINT ||
++ offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) {
+ err = -EINVAL;
+ goto out;
+ }
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 440328147e7e3..c27b4fe575136 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -1017,6 +1017,12 @@ ok:
+ err = 0;
+ }
+
++ /* check for index header length */
++ if (offsetof(struct INDEX_BUFFER, ihdr) + ib->ihdr.used > bytes) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ in->index = ib;
+ *node = in;
+
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 26a76ebfe58fc..471ea4d813ad8 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -129,6 +129,9 @@ next_attr:
+ rsize = attr->non_res ? 0 : le32_to_cpu(attr->res.data_size);
+ asize = le32_to_cpu(attr->size);
+
++ if (le16_to_cpu(attr->name_off) + attr->name_len > asize)
++ goto out;
++
+ switch (attr->type) {
+ case ATTR_STD:
+ if (attr->non_res ||
+@@ -364,7 +367,13 @@ next_attr:
+ attr_unpack_run:
+ roff = le16_to_cpu(attr->nres.run_off);
+
++ if (roff > asize) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ t64 = le64_to_cpu(attr->nres.svcn);
++
+ err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
+ t64, Add2Ptr(attr, roff), asize - roff);
+ if (err < 0)
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index 7d2fac5ee2156..af1e4b364ea8e 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -220,6 +220,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ return NULL;
+ }
+
++ if (off + asize < off) {
++ /* overflow check */
++ return NULL;
++ }
++
+ attr = Add2Ptr(attr, asize);
+ off += asize;
+ }
+@@ -260,6 +265,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ if (t16 + t32 > asize)
+ return NULL;
+
++ if (attr->name_len &&
++ le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) {
++ return NULL;
++ }
++
+ return attr;
+ }
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index adc4f73722b7c..8e2fe0f69203b 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -789,7 +789,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
+ : (u32)boot->record_size
+ << sbi->cluster_bits;
+
+- if (record_size > MAXIMUM_BYTES_PER_MFT)
++ if (record_size > MAXIMUM_BYTES_PER_MFT || record_size < SECTOR_SIZE)
+ goto out;
+
+ sbi->record_bits = blksize_bits(record_size);
+@@ -1141,7 +1141,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+ goto put_inode_out;
+ }
+ bytes = inode->i_size;
+- sbi->def_table = t = kmalloc(bytes, GFP_NOFS);
++ sbi->def_table = t = kmalloc(bytes, GFP_NOFS | __GFP_NOWARN);
+ if (!t) {
+ err = -ENOMEM;
+ goto put_inode_out;
+@@ -1260,9 +1260,9 @@ load_root:
+ ref.low = cpu_to_le32(MFT_REC_ROOT);
+ ref.seq = cpu_to_le16(MFT_REC_ROOT);
+ inode = ntfs_iget5(sb, &ref, &NAME_ROOT);
+- if (IS_ERR(inode)) {
++ if (IS_ERR(inode) || !inode->i_op) {
+ ntfs_err(sb, "Failed to load root.");
+- err = PTR_ERR(inode);
++ err = IS_ERR(inode) ? PTR_ERR(inode) : -EINVAL;
+ goto out;
+ }
+
+@@ -1281,6 +1281,7 @@ out:
+ * Free resources here.
+ * ntfs_fs_free will be called with fc->s_fs_info = NULL
+ */
++ put_mount_options(sbi->options);
+ put_ntfs(sbi);
+ sb->s_fs_info = NULL;
+
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 6b03457f72bb1..c3032cef391ef 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -592,28 +592,42 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ goto out_revert_creds;
+ }
+
+- err = -ENOMEM;
+- override_cred = prepare_creds();
+- if (override_cred) {
++ if (!attr->hardlink) {
++ err = -ENOMEM;
++ override_cred = prepare_creds();
++ if (!override_cred)
++ goto out_revert_creds;
++ /*
++ * In the creation cases(create, mkdir, mknod, symlink),
++ * ovl should transfer current's fs{u,g}id to underlying
++ * fs. Because underlying fs want to initialize its new
++ * inode owner using current's fs{u,g}id. And in this
++ * case, the @inode is a new inode that is initialized
++ * in inode_init_owner() to current's fs{u,g}id. So use
++ * the inode's i_{u,g}id to override the cred's fs{u,g}id.
++ *
++ * But in the other hardlink case, ovl_link() does not
++ * create a new inode, so just use the ovl mounter's
++ * fs{u,g}id.
++ */
+ override_cred->fsuid = inode->i_uid;
+ override_cred->fsgid = inode->i_gid;
+- if (!attr->hardlink) {
+- err = security_dentry_create_files_as(dentry,
+- attr->mode, &dentry->d_name, old_cred,
+- override_cred);
+- if (err) {
+- put_cred(override_cred);
+- goto out_revert_creds;
+- }
++ err = security_dentry_create_files_as(dentry,
++ attr->mode, &dentry->d_name, old_cred,
++ override_cred);
++ if (err) {
++ put_cred(override_cred);
++ goto out_revert_creds;
+ }
+ put_cred(override_creds(override_cred));
+ put_cred(override_cred);
+-
+- if (!ovl_dentry_is_whiteout(dentry))
+- err = ovl_create_upper(dentry, inode, attr);
+- else
+- err = ovl_create_over_whiteout(dentry, inode, attr);
+ }
++
++ if (!ovl_dentry_is_whiteout(dentry))
++ err = ovl_create_upper(dentry, inode, attr);
++ else
++ err = ovl_create_over_whiteout(dentry, inode, attr);
++
+ out_revert_creds:
+ revert_creds(old_cred);
+ return err;
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index a34f8042724ce..172cde9d2e569 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -96,6 +96,7 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
+
+ spin_lock(&file->f_lock);
+ file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
++ file->f_iocb_flags = iocb_flags(file);
+ spin_unlock(&file->f_lock);
+
+ return 0;
+diff --git a/fs/pnode.c b/fs/pnode.c
+index 1106137c747a3..468e4e65a615d 100644
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -244,7 +244,7 @@ static int propagate_one(struct mount *m)
+ }
+ do {
+ struct mount *parent = last_source->mnt_parent;
+- if (last_source == first_source)
++ if (peers(last_source, first_source))
+ break;
+ done = parent->mnt_master == p;
+ if (done && peers(n, parent))
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index 74e4d93f3e08d..f3fa3625d772c 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -670,7 +670,7 @@ static int ramoops_parse_dt(struct platform_device *pdev,
+ field = value; \
+ }
+
+- parse_u32("mem-type", pdata->record_size, pdata->mem_type);
++ parse_u32("mem-type", pdata->mem_type, pdata->mem_type);
+ parse_u32("record-size", pdata->record_size, 0);
+ parse_u32("console-size", pdata->console_size, 0);
+ parse_u32("ftrace-size", pdata->ftrace_size, 0);
+diff --git a/fs/pstore/zone.c b/fs/pstore/zone.c
+index 017d0d4ad3295..2770746bb7aa1 100644
+--- a/fs/pstore/zone.c
++++ b/fs/pstore/zone.c
+@@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
+ /* avoid destroying old data, allocate a new one */
+ len = zone->buffer_size + sizeof(*zone->buffer);
+ zone->oldbuf = zone->buffer;
+- zone->buffer = kzalloc(len, GFP_KERNEL);
++ zone->buffer = kzalloc(len, GFP_ATOMIC);
+ if (!zone->buffer) {
+ zone->buffer = zone->oldbuf;
+ return -ENOMEM;
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 3cd202d3eefb3..36a486505b081 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -40,6 +40,7 @@ struct file *eventfd_fget(int fd);
+ struct eventfd_ctx *eventfd_ctx_fdget(int fd);
+ struct eventfd_ctx *eventfd_ctx_fileget(struct file *file);
+ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n);
++__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask);
+ int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait,
+ __u64 *cnt);
+ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt);
+@@ -66,6 +67,12 @@ static inline int eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ return -ENOSYS;
+ }
+
++static inline int eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n,
++ unsigned mask)
++{
++ return -ENOSYS;
++}
++
+ static inline void eventfd_ctx_put(struct eventfd_ctx *ctx)
+ {
+
+diff --git a/include/linux/nvme.h b/include/linux/nvme.h
+index ae53d74f3696a..e2dbb9755ccac 100644
+--- a/include/linux/nvme.h
++++ b/include/linux/nvme.h
+@@ -7,6 +7,7 @@
+ #ifndef _LINUX_NVME_H
+ #define _LINUX_NVME_H
+
++#include <linux/bits.h>
+ #include <linux/types.h>
+ #include <linux/uuid.h>
+
+@@ -639,7 +640,7 @@ enum {
+ NVME_CMD_EFFECTS_NCC = 1 << 2,
+ NVME_CMD_EFFECTS_NIC = 1 << 3,
+ NVME_CMD_EFFECTS_CCC = 1 << 4,
+- NVME_CMD_EFFECTS_CSE_MASK = 3 << 16,
++ NVME_CMD_EFFECTS_CSE_MASK = GENMASK(18, 16),
+ NVME_CMD_EFFECTS_UUID_SEL = 1 << 19,
+ };
+
+diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
+index 8a3432d0f0dcb..e687658843b1c 100644
+--- a/include/uapi/linux/eventpoll.h
++++ b/include/uapi/linux/eventpoll.h
+@@ -41,6 +41,12 @@
+ #define EPOLLMSG (__force __poll_t)0x00000400
+ #define EPOLLRDHUP (__force __poll_t)0x00002000
+
++/*
++ * Internal flag - wakeup generated by io_uring, used to detect recursion back
++ * into the io_uring poll handler.
++ */
++#define EPOLL_URING_WAKE ((__force __poll_t)(1U << 27))
++
+ /* Set exclusive wakeup mode for the target file descriptor */
+ #define EPOLLEXCLUSIVE ((__force __poll_t)(1U << 28))
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 1b6c25dc3f0c5..b8a39be3bcb4c 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1607,7 +1607,7 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
+ return ret;
+
+ /* If the op doesn't have a file, we're not polling for it */
+- if ((req->ctx->flags & IORING_SETUP_IOPOLL) && req->file)
++ if ((req->ctx->flags & IORING_SETUP_IOPOLL) && def->iopoll_queue)
+ io_iopoll_req_issued(req, issue_flags);
+
+ return 0;
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 080867143f287..a49ccab262d53 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -169,9 +169,5 @@ done:
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+- /* put file to avoid an attempt to IOPOLL the req */
+- if (!(req->flags & REQ_F_FIXED_FILE))
+- io_put_file(req->file);
+- req->file = NULL;
+ return IOU_OK;
+ }
+diff --git a/io_uring/opdef.c b/io_uring/opdef.c
+index 3b15cdb6dbbc5..b3746458741b8 100644
+--- a/io_uring/opdef.c
++++ b/io_uring/opdef.c
+@@ -63,6 +63,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "READV",
+ .prep = io_prep_rw,
+@@ -80,6 +81,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "WRITEV",
+ .prep = io_prep_rw,
+@@ -103,6 +105,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "READ_FIXED",
+ .prep = io_prep_rw,
+@@ -118,6 +121,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "WRITE_FIXED",
+ .prep = io_prep_rw,
+@@ -275,6 +279,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "READ",
+ .prep = io_prep_rw,
+@@ -290,6 +295,7 @@ const struct io_op_def io_op_defs[] = {
+ .audit_skip = 1,
+ .ioprio = 1,
+ .iopoll = 1,
++ .iopoll_queue = 1,
+ .async_size = sizeof(struct io_async_rw),
+ .name = "WRITE",
+ .prep = io_prep_rw,
+@@ -475,6 +481,7 @@ const struct io_op_def io_op_defs[] = {
+ .needs_file = 1,
+ .plug = 1,
+ .name = "URING_CMD",
++ .iopoll_queue = 1,
+ .async_size = uring_cmd_pdu_size(1),
+ .prep = io_uring_cmd_prep,
+ .issue = io_uring_cmd,
+diff --git a/io_uring/opdef.h b/io_uring/opdef.h
+index 3efe06d25473a..df7e13d9bfba7 100644
+--- a/io_uring/opdef.h
++++ b/io_uring/opdef.h
+@@ -25,6 +25,8 @@ struct io_op_def {
+ unsigned ioprio : 1;
+ /* supports iopoll */
+ unsigned iopoll : 1;
++ /* have to be put into the iopoll list */
++ unsigned iopoll_queue : 1;
+ /* opcode specific path will handle ->async_data allocation if needed */
+ unsigned manual_alloc : 1;
+ /* size of async data needed, if any */
+diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
+index 086a22d1adb78..a8074079b09e8 100644
+--- a/kernel/futex/syscalls.c
++++ b/kernel/futex/syscalls.c
+@@ -286,19 +286,22 @@ SYSCALL_DEFINE5(futex_waitv, struct futex_waitv __user *, waiters,
+ }
+
+ futexv = kcalloc(nr_futexes, sizeof(*futexv), GFP_KERNEL);
+- if (!futexv)
+- return -ENOMEM;
++ if (!futexv) {
++ ret = -ENOMEM;
++ goto destroy_timer;
++ }
+
+ ret = futex_parse_waitv(futexv, waiters, nr_futexes);
+ if (!ret)
+ ret = futex_wait_multiple(futexv, nr_futexes, timeout ? &to : NULL);
+
++ kfree(futexv);
++
++destroy_timer:
+ if (timeout) {
+ hrtimer_cancel(&to.timer);
+ destroy_hrtimer_on_stack(&to.timer);
+ }
+-
+- kfree(futexv);
+ return ret;
+ }
+
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index fe12dfe254ecf..54d077e1a2dc7 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -14,10 +14,12 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
++#include <linux/minmax.h>
+ #include <linux/moduleparam.h>
+ #include <linux/percpu.h>
+ #include <linux/preempt.h>
+ #include <linux/sched.h>
++#include <linux/string.h>
+ #include <linux/uaccess.h>
+
+ #include "encoding.h"
+@@ -1308,3 +1310,51 @@ noinline void __tsan_atomic_signal_fence(int memorder)
+ }
+ }
+ EXPORT_SYMBOL(__tsan_atomic_signal_fence);
++
++#ifdef __HAVE_ARCH_MEMSET
++void *__tsan_memset(void *s, int c, size_t count);
++noinline void *__tsan_memset(void *s, int c, size_t count)
++{
++ /*
++ * Instead of not setting up watchpoints where accessed size is greater
++ * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
++ */
++ size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);
++
++ check_access(s, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++ return memset(s, c, count);
++}
++#else
++void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
++#endif
++EXPORT_SYMBOL(__tsan_memset);
++
++#ifdef __HAVE_ARCH_MEMMOVE
++void *__tsan_memmove(void *dst, const void *src, size_t len);
++noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
++{
++ size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++ check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++ check_access(src, check_len, 0, _RET_IP_);
++ return memmove(dst, src, len);
++}
++#else
++void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
++#endif
++EXPORT_SYMBOL(__tsan_memmove);
++
++#ifdef __HAVE_ARCH_MEMCPY
++void *__tsan_memcpy(void *dst, const void *src, size_t len);
++noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
++{
++ size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++ check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++ check_access(src, check_len, 0, _RET_IP_);
++ return memcpy(dst, src, len);
++}
++#else
++void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
++#endif
++EXPORT_SYMBOL(__tsan_memcpy);
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 771fcce54fac0..fb88278978fe7 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2209,13 +2209,9 @@ int register_kretprobe(struct kretprobe *rp)
+ rp->kp.post_handler = NULL;
+
+ /* Pre-allocate memory for max kretprobe instances */
+- if (rp->maxactive <= 0) {
+-#ifdef CONFIG_PREEMPTION
++ if (rp->maxactive <= 0)
+ rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
+-#else
+- rp->maxactive = num_possible_cpus();
+-#endif
+- }
++
+ #ifdef CONFIG_KRETPROBE_ON_RETHOOK
+ rp->rh = rethook_alloc((void *)rp, kretprobe_rethook_handler);
+ if (!rp->rh)
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 7779ee8abc2a0..010cf4e6d0b8f 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -89,15 +89,31 @@ static inline int __ww_mutex_check_kill(struct rt_mutex *lock,
+ * set this bit before looking at the lock.
+ */
+
+-static __always_inline void
+-rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner)
++static __always_inline struct task_struct *
++rt_mutex_owner_encode(struct rt_mutex_base *lock, struct task_struct *owner)
+ {
+ unsigned long val = (unsigned long)owner;
+
+ if (rt_mutex_has_waiters(lock))
+ val |= RT_MUTEX_HAS_WAITERS;
+
+- WRITE_ONCE(lock->owner, (struct task_struct *)val);
++ return (struct task_struct *)val;
++}
++
++static __always_inline void
++rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner)
++{
++ /*
++ * lock->wait_lock is held but explicit acquire semantics are needed
++ * for a new lock owner so WRITE_ONCE is insufficient.
++ */
++ xchg_acquire(&lock->owner, rt_mutex_owner_encode(lock, owner));
++}
++
++static __always_inline void rt_mutex_clear_owner(struct rt_mutex_base *lock)
++{
++ /* lock->wait_lock is held so the unlock provides release semantics. */
++ WRITE_ONCE(lock->owner, rt_mutex_owner_encode(lock, NULL));
+ }
+
+ static __always_inline void clear_rt_mutex_waiters(struct rt_mutex_base *lock)
+@@ -106,7 +122,8 @@ static __always_inline void clear_rt_mutex_waiters(struct rt_mutex_base *lock)
+ ((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS);
+ }
+
+-static __always_inline void fixup_rt_mutex_waiters(struct rt_mutex_base *lock)
++static __always_inline void
++fixup_rt_mutex_waiters(struct rt_mutex_base *lock, bool acquire_lock)
+ {
+ unsigned long owner, *p = (unsigned long *) &lock->owner;
+
+@@ -172,8 +189,21 @@ static __always_inline void fixup_rt_mutex_waiters(struct rt_mutex_base *lock)
+ * still set.
+ */
+ owner = READ_ONCE(*p);
+- if (owner & RT_MUTEX_HAS_WAITERS)
+- WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
++ if (owner & RT_MUTEX_HAS_WAITERS) {
++ /*
++ * See rt_mutex_set_owner() and rt_mutex_clear_owner() on
++ * why xchg_acquire() is used for updating owner for
++ * locking and WRITE_ONCE() for unlocking.
++ *
++ * WRITE_ONCE() would work for the acquire case too, but
++ * in case that the lock acquisition failed it might
++ * force other lockers into the slow path unnecessarily.
++ */
++ if (acquire_lock)
++ xchg_acquire(p, owner & ~RT_MUTEX_HAS_WAITERS);
++ else
++ WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
++ }
+ }
+
+ /*
+@@ -208,6 +238,13 @@ static __always_inline void mark_rt_mutex_waiters(struct rt_mutex_base *lock)
+ owner = *p;
+ } while (cmpxchg_relaxed(p, owner,
+ owner | RT_MUTEX_HAS_WAITERS) != owner);
++
++ /*
++ * The cmpxchg loop above is relaxed to avoid back-to-back ACQUIRE
++ * operations in the event of contention. Ensure the successful
++ * cmpxchg is visible.
++ */
++ smp_mb__after_atomic();
+ }
+
+ /*
+@@ -1243,7 +1280,7 @@ static int __sched __rt_mutex_slowtrylock(struct rt_mutex_base *lock)
+ * try_to_take_rt_mutex() sets the lock waiters bit
+ * unconditionally. Clean this up.
+ */
+- fixup_rt_mutex_waiters(lock);
++ fixup_rt_mutex_waiters(lock, true);
+
+ return ret;
+ }
+@@ -1604,7 +1641,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
+ * try_to_take_rt_mutex() sets the waiter bit
+ * unconditionally. We might have to fix that up.
+ */
+- fixup_rt_mutex_waiters(lock);
++ fixup_rt_mutex_waiters(lock, true);
+
+ trace_contention_end(lock, ret);
+
+@@ -1719,7 +1756,7 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock)
+ * try_to_take_rt_mutex() sets the waiter bit unconditionally.
+ * We might have to fix that up:
+ */
+- fixup_rt_mutex_waiters(lock);
++ fixup_rt_mutex_waiters(lock, true);
+ debug_rt_mutex_free_waiter(&waiter);
+
+ trace_contention_end(lock, 0);
+diff --git a/kernel/locking/rtmutex_api.c b/kernel/locking/rtmutex_api.c
+index 900220941caac..cb9fdff76a8a3 100644
+--- a/kernel/locking/rtmutex_api.c
++++ b/kernel/locking/rtmutex_api.c
+@@ -267,7 +267,7 @@ void __sched rt_mutex_init_proxy_locked(struct rt_mutex_base *lock,
+ void __sched rt_mutex_proxy_unlock(struct rt_mutex_base *lock)
+ {
+ debug_rt_mutex_proxy_unlock(lock);
+- rt_mutex_set_owner(lock, NULL);
++ rt_mutex_clear_owner(lock);
+ }
+
+ /**
+@@ -382,7 +382,7 @@ int __sched rt_mutex_wait_proxy_lock(struct rt_mutex_base *lock,
+ * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might
+ * have to fix that up.
+ */
+- fixup_rt_mutex_waiters(lock);
++ fixup_rt_mutex_waiters(lock, true);
+ raw_spin_unlock_irq(&lock->wait_lock);
+
+ return ret;
+@@ -438,7 +438,7 @@ bool __sched rt_mutex_cleanup_proxy_lock(struct rt_mutex_base *lock,
+ * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might
+ * have to fix that up.
+ */
+- fixup_rt_mutex_waiters(lock);
++ fixup_rt_mutex_waiters(lock, false);
+
+ raw_spin_unlock_irq(&lock->wait_lock);
+
+diff --git a/mm/compaction.c b/mm/compaction.c
+index 88fea74c3a86b..8552f5ea358de 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -1346,7 +1346,7 @@ move_freelist_tail(struct list_head *freelist, struct page *freepage)
+ }
+
+ static void
+-fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
++fast_isolate_around(struct compact_control *cc, unsigned long pfn)
+ {
+ unsigned long start_pfn, end_pfn;
+ struct page *page;
+@@ -1367,21 +1367,13 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
+ if (!page)
+ return;
+
+- /* Scan before */
+- if (start_pfn != pfn) {
+- isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
+- if (cc->nr_freepages >= cc->nr_migratepages)
+- return;
+- }
+-
+- /* Scan after */
+- start_pfn = pfn + nr_isolated;
+- if (start_pfn < end_pfn)
+- isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
++ isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
+
+ /* Skip this pageblock in the future as it's full or nearly full */
+ if (cc->nr_freepages < cc->nr_migratepages)
+ set_pageblock_skip(page);
++
++ return;
+ }
+
+ /* Search orders in round-robin fashion */
+@@ -1558,7 +1550,7 @@ fast_isolate_freepages(struct compact_control *cc)
+ return cc->free_pfn;
+
+ low_pfn = page_to_pfn(page);
+- fast_isolate_around(cc, low_pfn, nr_isolated);
++ fast_isolate_around(cc, low_pfn);
+ return low_pfn;
+ }
+
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index b73d3248d976a..dd385d7749470 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -1525,6 +1525,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
+ * the home node for vmas we already updated before.
+ */
+ if (new->mode != MPOL_BIND && new->mode != MPOL_PREFERRED_MANY) {
++ mpol_put(new);
+ err = -EOPNOTSUPP;
+ break;
+ }
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index bcd74dddbe2db..9a5db285d4ae5 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -1162,18 +1162,23 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp,
+ return res;
+
+ inlen = svc_getnl(argv);
+- if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
++ if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
++ kfree(in_handle->data);
+ return SVC_DENIED;
++ }
+
+ pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
+ in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
+- if (!in_token->pages)
++ if (!in_token->pages) {
++ kfree(in_handle->data);
+ return SVC_DENIED;
++ }
+ in_token->page_base = 0;
+ in_token->page_len = inlen;
+ for (i = 0; i < pages; i++) {
+ in_token->pages[i] = alloc_page(GFP_KERNEL);
+ if (!in_token->pages[i]) {
++ kfree(in_handle->data);
+ gss_free_in_token_pages(in_token);
+ return SVC_DENIED;
+ }
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 913509b29f938..8c0668304cbb8 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -167,6 +167,7 @@ struct hdmi_spec {
+ struct hdmi_ops ops;
+
+ bool dyn_pin_out;
++ bool static_pcm_mapping;
+ /* hdmi interrupt trigger control flag for Nvidia codec */
+ bool hdmi_intr_trig_ctrl;
+ bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+@@ -1525,13 +1526,16 @@ static void update_eld(struct hda_codec *codec,
+ */
+ pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+
+- if (eld->eld_valid) {
+- hdmi_attach_hda_pcm(spec, per_pin);
+- hdmi_pcm_setup_pin(spec, per_pin);
+- } else {
+- hdmi_pcm_reset_pin(spec, per_pin);
+- hdmi_detach_hda_pcm(spec, per_pin);
++ if (!spec->static_pcm_mapping) {
++ if (eld->eld_valid) {
++ hdmi_attach_hda_pcm(spec, per_pin);
++ hdmi_pcm_setup_pin(spec, per_pin);
++ } else {
++ hdmi_pcm_reset_pin(spec, per_pin);
++ hdmi_detach_hda_pcm(spec, per_pin);
++ }
+ }
++
+ /* if pcm_idx == -1, it means this is in monitor connection event
+ * we can get the correct pcm_idx now.
+ */
+@@ -2281,8 +2285,8 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+ struct hdmi_spec *spec = codec->spec;
+ int idx, pcm_num;
+
+- /* limit the PCM devices to the codec converters */
+- pcm_num = spec->num_cvts;
++ /* limit the PCM devices to the codec converters or available PINs */
++ pcm_num = min(spec->num_cvts, spec->num_pins);
+ codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+
+ for (idx = 0; idx < pcm_num; idx++) {
+@@ -2379,6 +2383,11 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
+ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+ struct hdmi_eld *pin_eld = &per_pin->sink_eld;
+
++ if (spec->static_pcm_mapping) {
++ hdmi_attach_hda_pcm(spec, per_pin);
++ hdmi_pcm_setup_pin(spec, per_pin);
++ }
++
+ pin_eld->eld_valid = false;
+ hdmi_present_sense(per_pin, 0);
+ }
+@@ -4419,6 +4428,8 @@ static int patch_atihdmi(struct hda_codec *codec)
+
+ spec = codec->spec;
+
++ spec->static_pcm_mapping = true;
++
+ spec->ops.pin_get_eld = atihdmi_pin_get_eld;
+ spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;
+ spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 59faa5a9a7141..b67617b68e509 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -304,7 +304,8 @@ static void line6_data_received(struct urb *urb)
+ for (;;) {
+ done =
+ line6_midibuf_read(mb, line6->buffer_message,
+- LINE6_MIDI_MESSAGE_MAXLEN);
++ LINE6_MIDI_MESSAGE_MAXLEN,
++ LINE6_MIDIBUF_READ_RX);
+
+ if (done <= 0)
+ break;
+diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
+index ba0e2b7e8fe19..0838632c788e4 100644
+--- a/sound/usb/line6/midi.c
++++ b/sound/usb/line6/midi.c
+@@ -44,7 +44,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+ int req, done;
+
+ for (;;) {
+- req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
++ req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
++ LINE6_FALLBACK_MAXPACKETSIZE);
+ done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+ if (done == 0)
+@@ -56,7 +57,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+
+ for (;;) {
+ done = line6_midibuf_read(mb, chunk,
+- LINE6_FALLBACK_MAXPACKETSIZE);
++ LINE6_FALLBACK_MAXPACKETSIZE,
++ LINE6_MIDIBUF_READ_TX);
+
+ if (done == 0)
+ break;
+diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c
+index 6a70463f82c4e..e7f830f7526c9 100644
+--- a/sound/usb/line6/midibuf.c
++++ b/sound/usb/line6/midibuf.c
+@@ -9,6 +9,7 @@
+
+ #include "midibuf.h"
+
++
+ static int midibuf_message_length(unsigned char code)
+ {
+ int message_length;
+@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)
+
+ message_length = length[(code >> 4) - 8];
+ } else {
+- /*
+- Note that according to the MIDI specification 0xf2 is
+- the "Song Position Pointer", but this is used by Line 6
+- to send sysex messages to the host.
+- */
+- static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
++ static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
+ 1, 1, 1, -1, 1, 1
+ };
+ message_length = length[code & 0x0f];
+@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
+ }
+
+ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+- int length)
++ int length, int read_type)
+ {
+ int bytes_used;
+ int length1, length2;
+@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+
+ length1 = this->size - this->pos_read;
+
+- /* check MIDI command length */
+ command = this->buf[this->pos_read];
++ /*
++ PODxt always has status byte lower nibble set to 0010,
++ when it means to send 0000, so we correct if here so
++ that control/program changes come on channel 1 and
++ sysex message status byte is correct
++ */
++ if (read_type == LINE6_MIDIBUF_READ_RX) {
++ if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
++ unsigned char fixed = command & 0xf0;
++ this->buf[this->pos_read] = fixed;
++ command = fixed;
++ }
++ }
+
++ /* check MIDI command length */
+ if (command & 0x80) {
+ midi_length = midibuf_message_length(command);
+ this->command_prev = command;
+diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h
+index 124a8f9f7e96c..542e8d836f87d 100644
+--- a/sound/usb/line6/midibuf.h
++++ b/sound/usb/line6/midibuf.h
+@@ -8,6 +8,9 @@
+ #ifndef MIDIBUF_H
+ #define MIDIBUF_H
+
++#define LINE6_MIDIBUF_READ_TX 0
++#define LINE6_MIDIBUF_READ_RX 1
++
+ struct midi_buffer {
+ unsigned char *buf;
+ int size;
+@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
+ extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
+ extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
+ extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
+- int length);
++ int length, int read_type);
+ extern void line6_midibuf_reset(struct midi_buffer *mb);
+ extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
+ int length);
+diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
+index cd41aa7f03851..d173971e5f029 100644
+--- a/sound/usb/line6/pod.c
++++ b/sound/usb/line6/pod.c
+@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
+ .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
+ };
+
++
+ static const char pod_version_header[] = {
+- 0xf2, 0x7e, 0x7f, 0x06, 0x02
++ 0xf0, 0x7e, 0x7f, 0x06, 0x02
+ };
+
+ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 67afdce3421f5..274bc3d4bc3f8 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -207,7 +207,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
+ return false;
+
+ insn = find_insn(file, func->sec, func->offset);
+- if (!insn->func)
++ if (!insn || !insn->func)
+ return false;
+
+ func_for_each_insn(file, func, insn) {
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-07 11:11 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-07 11:11 UTC (permalink / raw
To: gentoo-commits
commit: 8927b6ad937d813e8fb6f22e58847532153288b4
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 7 11:11:26 2023 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jan 7 11:11:26 2023 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8927b6ad
Linux patch 6.0.18
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1017_linux-6.0.18.patch | 6477 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 6481 insertions(+)
diff --git a/0000_README b/0000_README
index b0d2c4b3..569afe2e 100644
--- a/0000_README
+++ b/0000_README
@@ -111,6 +111,10 @@ Patch: 1016_linux-6.0.17.patch
From: http://www.kernel.org
Desc: Linux 6.0.17
+Patch: 1017_linux-6.0.19.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.18
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1017_linux-6.0.18.patch b/1017_linux-6.0.18.patch
new file mode 100644
index 00000000..f58d7b4f
--- /dev/null
+++ b/1017_linux-6.0.18.patch
@@ -0,0 +1,6477 @@
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 2bc11a61c4d01..0fb8f99e59257 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -2294,7 +2294,13 @@
+ Provide an override to the IOAPIC-ID<->DEVICE-ID
+ mapping provided in the IVRS ACPI table.
+ By default, PCI segment is 0, and can be omitted.
+- For example:
++
++ For example, to map IOAPIC-ID decimal 10 to
++ PCI segment 0x1 and PCI device 00:14.0,
++ write the parameter as:
++ ivrs_ioapic=10@0001:00:14.0
++
++ Deprecated formats:
+ * To map IOAPIC-ID decimal 10 to PCI device 00:14.0
+ write the parameter as:
+ ivrs_ioapic[10]=00:14.0
+@@ -2306,7 +2312,13 @@
+ Provide an override to the HPET-ID<->DEVICE-ID
+ mapping provided in the IVRS ACPI table.
+ By default, PCI segment is 0, and can be omitted.
+- For example:
++
++ For example, to map HPET-ID decimal 10 to
++ PCI segment 0x1 and PCI device 00:14.0,
++ write the parameter as:
++ ivrs_hpet=10@0001:00:14.0
++
++ Deprecated formats:
+ * To map HPET-ID decimal 0 to PCI device 00:14.0
+ write the parameter as:
+ ivrs_hpet[0]=00:14.0
+@@ -2317,15 +2329,20 @@
+ ivrs_acpihid [HW,X86-64]
+ Provide an override to the ACPI-HID:UID<->DEVICE-ID
+ mapping provided in the IVRS ACPI table.
++ By default, PCI segment is 0, and can be omitted.
+
+ For example, to map UART-HID:UID AMD0020:0 to
+ PCI segment 0x1 and PCI device ID 00:14.5,
+ write the parameter as:
+- ivrs_acpihid[0001:00:14.5]=AMD0020:0
++ ivrs_acpihid=AMD0020:0@0001:00:14.5
+
+- By default, PCI segment is 0, and can be omitted.
+- For example, PCI device 00:14.5 write the parameter as:
++ Deprecated formats:
++ * To map UART-HID:UID AMD0020:0 to PCI segment is 0,
++ PCI device ID 00:14.5, write the parameter as:
+ ivrs_acpihid[00:14.5]=AMD0020:0
++ * To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
++ PCI device ID 00:14.5, write the parameter as:
++ ivrs_acpihid[0001:00:14.5]=AMD0020:0
+
+ js= [HW,JOY] Analog joystick
+ See Documentation/input/joydev/joystick.rst.
+diff --git a/Documentation/filesystems/mount_api.rst b/Documentation/filesystems/mount_api.rst
+index eb358a00be279..1d16787a00e95 100644
+--- a/Documentation/filesystems/mount_api.rst
++++ b/Documentation/filesystems/mount_api.rst
+@@ -814,6 +814,7 @@ process the parameters it is given.
+ int fs_lookup_param(struct fs_context *fc,
+ struct fs_parameter *value,
+ bool want_bdev,
++ unsigned int flags,
+ struct path *_path);
+
+ This takes a parameter that carries a string or filename type and attempts
+diff --git a/Makefile b/Makefile
+index a0ddac5b7cafb..0104f69d30bbd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 17
++SUBLEVEL = 18
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
+index 303400fa2cdf7..2aec85ab1e8b9 100644
+--- a/arch/arm/nwfpe/Makefile
++++ b/arch/arm/nwfpe/Makefile
+@@ -11,3 +11,9 @@ nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
+ entry.o
+
+ nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o
++
++# Try really hard to avoid generating calls to __aeabi_uldivmod() from
++# float64_rem() due to loop elision.
++ifdef CONFIG_CC_IS_CLANG
++CFLAGS_softfloat.o += -mllvm -replexitval=never
++endif
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+index 4fbd99eb496a2..dec85d2548384 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+@@ -56,10 +56,10 @@
+ #size-cells = <2>;
+ ranges;
+
+- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
++ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ bl31_secmon_reserved: secmon@54600000 {
+ no-map;
+- reg = <0 0x54600000 0x0 0x30000>;
++ reg = <0 0x54600000 0x0 0x200000>;
+ };
+
+ /* 12 MiB reserved for OP-TEE (BL32)
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 6d82dea3675b1..40dfa70436002 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -855,12 +855,13 @@
+ required-opps = <&rpmhpd_opp_nom>;
+
+ iommus = <&apps_smmu 0xe0 0x0>;
++ dma-coherent;
+
+ clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_UFS_PHY_AHB_CLK>,
+ <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+- <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+ <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+ <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+@@ -891,7 +892,7 @@
+ ranges;
+ clock-names = "ref",
+ "ref_aux";
+- clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
++ clocks = <&gcc GCC_UFS_CARD_CLKREF_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+
+ resets = <&ufs_mem_hc 0>;
+@@ -923,12 +924,13 @@
+ power-domains = <&gcc UFS_CARD_GDSC>;
+
+ iommus = <&apps_smmu 0x4a0 0x0>;
++ dma-coherent;
+
+ clocks = <&gcc GCC_UFS_CARD_AXI_CLK>,
+ <&gcc GCC_AGGRE_UFS_CARD_AXI_CLK>,
+ <&gcc GCC_UFS_CARD_AHB_CLK>,
+ <&gcc GCC_UFS_CARD_UNIPRO_CORE_CLK>,
+- <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ <&gcc GCC_UFS_CARD_TX_SYMBOL_0_CLK>,
+ <&gcc GCC_UFS_CARD_RX_SYMBOL_0_CLK>,
+ <&gcc GCC_UFS_CARD_RX_SYMBOL_1_CLK>;
+@@ -959,7 +961,7 @@
+ ranges;
+ clock-names = "ref",
+ "ref_aux";
+- clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
++ clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
+ <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
+
+ resets = <&ufs_card_hc 0>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index b2eddcd875069..a2eda0f67cfb0 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -1123,7 +1123,10 @@
+
+ /* PINCTRL - additions to nodes defined in sdm845.dtsi */
+ &qup_spi2_default {
+- drive-strength = <16>;
++ pinconf {
++ pins = "gpio27", "gpio28", "gpio29", "gpio30";
++ drive-strength = <16>;
++ };
+ };
+
+ &qup_uart3_default{
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index be59a8ba9c1fe..74f43da51fa50 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -487,8 +487,10 @@
+ };
+
+ &qup_i2c12_default {
+- drive-strength = <2>;
+- bias-disable;
++ pinmux {
++ drive-strength = <2>;
++ bias-disable;
++ };
+ };
+
+ &qup_uart6_default {
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+index f954fe5cb61ab..d028a7eb364a6 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+@@ -415,8 +415,10 @@
+ };
+
+ &qup_i2c12_default {
+- drive-strength = <2>;
+- bias-disable;
++ pinmux {
++ drive-strength = <2>;
++ bias-disable;
++ };
+ };
+
+ &qup_uart6_default {
+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
+index ce190ee18a201..7e5140d894eaf 100644
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -23,8 +23,8 @@
+ *
+ * The regs must be on a stack currently owned by the calling task.
+ */
+-static inline void unwind_init_from_regs(struct unwind_state *state,
+- struct pt_regs *regs)
++static __always_inline void unwind_init_from_regs(struct unwind_state *state,
++ struct pt_regs *regs)
+ {
+ unwind_init_common(state, current);
+
+@@ -58,8 +58,8 @@ static __always_inline void unwind_init_from_caller(struct unwind_state *state)
+ * duration of the unwind, or the unwind will be bogus. It is never valid to
+ * call this for the current task.
+ */
+-static inline void unwind_init_from_task(struct unwind_state *state,
+- struct task_struct *task)
++static __always_inline void unwind_init_from_task(struct unwind_state *state,
++ struct task_struct *task)
+ {
+ unwind_init_common(state, task);
+
+@@ -190,7 +190,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
+ barrier();
+ }
+
+-noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
++noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
+ void *cookie, struct task_struct *task,
+ struct pt_regs *regs)
+ {
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index ecd0288544698..68ae77069d23f 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -166,8 +166,8 @@ extern void __update_cache(pte_t pte);
+
+ /* This calculates the number of initial pages we need for the initial
+ * page tables */
+-#if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT)
+-# define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT))
++#if (KERNEL_INITIAL_ORDER) >= (PLD_SHIFT + BITS_PER_PTE)
++# define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PLD_SHIFT - BITS_PER_PTE))
+ #else
+ # define PT_INITIAL (1) /* all initial PTEs fit into one page */
+ #endif
+diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
+index 6a7e315bcc2e5..a115315d88e69 100644
+--- a/arch/parisc/kernel/firmware.c
++++ b/arch/parisc/kernel/firmware.c
+@@ -1288,9 +1288,8 @@ void pdc_io_reset_devices(void)
+
+ #endif /* defined(BOOTLOADER) */
+
+-/* locked by pdc_console_lock */
+-static int __attribute__((aligned(8))) iodc_retbuf[32];
+-static char __attribute__((aligned(64))) iodc_dbuf[4096];
++/* locked by pdc_lock */
++static char iodc_dbuf[4096] __page_aligned_bss;
+
+ /**
+ * pdc_iodc_print - Console print using IODC.
+@@ -1307,6 +1306,9 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
+ unsigned int i;
+ unsigned long flags;
+
++ count = min_t(unsigned int, count, sizeof(iodc_dbuf));
++
++ spin_lock_irqsave(&pdc_lock, flags);
+ for (i = 0; i < count;) {
+ switch(str[i]) {
+ case '\n':
+@@ -1322,12 +1324,11 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
+ }
+
+ print:
+- spin_lock_irqsave(&pdc_lock, flags);
+- real32_call(PAGE0->mem_cons.iodc_io,
+- (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+- PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+- __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
+- spin_unlock_irqrestore(&pdc_lock, flags);
++ real32_call(PAGE0->mem_cons.iodc_io,
++ (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
++ PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
++ __pa(pdc_result), 0, __pa(iodc_dbuf), i, 0);
++ spin_unlock_irqrestore(&pdc_lock, flags);
+
+ return i;
+ }
+@@ -1354,10 +1355,11 @@ int pdc_iodc_getc(void)
+ real32_call(PAGE0->mem_kbd.iodc_io,
+ (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+ PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
+- __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
++ __pa(pdc_result), 0, __pa(iodc_dbuf), 1, 0);
+
+ ch = *iodc_dbuf;
+- status = *iodc_retbuf;
++ /* like convert_to_wide() but for first return value only: */
++ status = *(int *)&pdc_result;
+ spin_unlock_irqrestore(&pdc_lock, flags);
+
+ if (status == 0)
+diff --git a/arch/parisc/kernel/vdso32/Makefile b/arch/parisc/kernel/vdso32/Makefile
+index 85b1c6d261d12..4459a48d23033 100644
+--- a/arch/parisc/kernel/vdso32/Makefile
++++ b/arch/parisc/kernel/vdso32/Makefile
+@@ -26,7 +26,7 @@ $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so FORCE
+
+ # Force dependency (incbin is bad)
+ # link rule for the .so file, .lds has to be first
+-$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC)
++$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE
+ $(call if_changed,vdso32ld)
+
+ # assembly rules for the .S files
+@@ -38,7 +38,7 @@ $(obj-cvdso32): %.o: %.c FORCE
+
+ # actual build commands
+ quiet_cmd_vdso32ld = VDSO32L $@
+- cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@
++ cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
+ quiet_cmd_vdso32as = VDSO32A $@
+ cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
+ quiet_cmd_vdso32cc = VDSO32C $@
+diff --git a/arch/parisc/kernel/vdso64/Makefile b/arch/parisc/kernel/vdso64/Makefile
+index a30f5ec5eb4bf..f3d6045793f4c 100644
+--- a/arch/parisc/kernel/vdso64/Makefile
++++ b/arch/parisc/kernel/vdso64/Makefile
+@@ -26,7 +26,7 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so FORCE
+
+ # Force dependency (incbin is bad)
+ # link rule for the .so file, .lds has to be first
+-$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC)
++$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) FORCE
+ $(call if_changed,vdso64ld)
+
+ # assembly rules for the .S files
+@@ -35,7 +35,7 @@ $(obj-vdso64): %.o: %.S FORCE
+
+ # actual build commands
+ quiet_cmd_vdso64ld = VDSO64L $@
+- cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
++ cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
+ quiet_cmd_vdso64as = VDSO64A $@
+ cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
+
+diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
+index 3cee7115441b4..e3d1f377bc5b5 100644
+--- a/arch/powerpc/include/asm/ftrace.h
++++ b/arch/powerpc/include/asm/ftrace.h
+@@ -64,17 +64,6 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
+ * those.
+ */
+ #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
+-#ifdef CONFIG_PPC64_ELF_ABI_V1
+-static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
+-{
+- /* We need to skip past the initial dot, and the __se_sys alias */
+- return !strcmp(sym + 1, name) ||
+- (!strncmp(sym, ".__se_sys", 9) && !strcmp(sym + 6, name)) ||
+- (!strncmp(sym, ".ppc_", 5) && !strcmp(sym + 5, name + 4)) ||
+- (!strncmp(sym, ".ppc32_", 7) && !strcmp(sym + 7, name + 4)) ||
+- (!strncmp(sym, ".ppc64_", 7) && !strcmp(sym + 7, name + 4));
+-}
+-#else
+ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
+ {
+ return !strcmp(sym, name) ||
+@@ -83,7 +72,6 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
+ (!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) ||
+ (!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4));
+ }
+-#endif /* CONFIG_PPC64_ELF_ABI_V1 */
+ #endif /* CONFIG_FTRACE_SYSCALLS */
+
+ #if defined(CONFIG_PPC64) && defined(CONFIG_FUNCTION_TRACER)
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 9d5b7fa1b6225..76a3d8280e67e 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -493,7 +493,7 @@ config KEXEC_FILE
+ select KEXEC_CORE
+ select KEXEC_ELF
+ select HAVE_IMA_KEXEC if IMA
+- depends on 64BIT
++ depends on 64BIT && MMU
+ help
+ This is new version of kexec system call. This system call is
+ file based and takes file descriptors as system call argument
+diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
+index eee260e8ab308..2b56769cb530c 100644
+--- a/arch/riscv/include/asm/kexec.h
++++ b/arch/riscv/include/asm/kexec.h
+@@ -39,6 +39,7 @@ crash_setup_regs(struct pt_regs *newregs,
+ #define ARCH_HAS_KIMAGE_ARCH
+
+ struct kimage_arch {
++ void *fdt; /* For CONFIG_KEXEC_FILE */
+ unsigned long fdt_addr;
+ };
+
+@@ -62,6 +63,10 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+ const Elf_Shdr *relsec,
+ const Elf_Shdr *symtab);
+ #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add
++
++struct kimage;
++int arch_kimage_file_post_load_cleanup(struct kimage *image);
++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
+ #endif
+
+ #endif
+diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
+index 0099dc1161683..5ff1f19fd45c2 100644
+--- a/arch/riscv/include/asm/mmu.h
++++ b/arch/riscv/include/asm/mmu.h
+@@ -19,6 +19,8 @@ typedef struct {
+ #ifdef CONFIG_SMP
+ /* A local icache flush is needed before user execution can resume. */
+ cpumask_t icache_stale_mask;
++ /* A local tlb flush is needed before user execution can resume. */
++ cpumask_t tlb_stale_mask;
+ #endif
+ } mm_context_t;
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 7ec936910a96e..330f75fe12787 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -415,7 +415,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ * Relying on flush_tlb_fix_spurious_fault would suffice, but
+ * the extra traps reduce performance. So, eagerly SFENCE.VMA.
+ */
+- local_flush_tlb_page(address);
++ flush_tlb_page(vma, address);
+ }
+
+ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
+index 801019381dea3..907b9efd39a87 100644
+--- a/arch/riscv/include/asm/tlbflush.h
++++ b/arch/riscv/include/asm/tlbflush.h
+@@ -22,6 +22,24 @@ static inline void local_flush_tlb_page(unsigned long addr)
+ {
+ ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ }
++
++static inline void local_flush_tlb_all_asid(unsigned long asid)
++{
++ __asm__ __volatile__ ("sfence.vma x0, %0"
++ :
++ : "r" (asid)
++ : "memory");
++}
++
++static inline void local_flush_tlb_page_asid(unsigned long addr,
++ unsigned long asid)
++{
++ __asm__ __volatile__ ("sfence.vma %0, %1"
++ :
++ : "r" (addr), "r" (asid)
++ : "memory");
++}
++
+ #else /* CONFIG_MMU */
+ #define local_flush_tlb_all() do { } while (0)
+ #define local_flush_tlb_page(addr) do { } while (0)
+diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
+index 0cb94992c15b3..5372b708fae21 100644
+--- a/arch/riscv/kernel/elf_kexec.c
++++ b/arch/riscv/kernel/elf_kexec.c
+@@ -21,6 +21,18 @@
+ #include <linux/memblock.h>
+ #include <asm/setup.h>
+
++int arch_kimage_file_post_load_cleanup(struct kimage *image)
++{
++ kvfree(image->arch.fdt);
++ image->arch.fdt = NULL;
++
++ vfree(image->elf_headers);
++ image->elf_headers = NULL;
++ image->elf_headers_sz = 0;
++
++ return kexec_image_post_load_cleanup_default(image);
++}
++
+ static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
+ struct kexec_elf_info *elf_info, unsigned long old_pbase,
+ unsigned long new_pbase)
+@@ -298,6 +310,8 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
+ pr_err("Error add DTB kbuf ret=%d\n", ret);
+ goto out_free_fdt;
+ }
++ /* Cache the fdt buffer address for memory cleanup */
++ image->arch.fdt = fdt;
+ pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem);
+ goto out;
+
+diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
+index 08d11a53f39e7..bcfe9eb55f80f 100644
+--- a/arch/riscv/kernel/stacktrace.c
++++ b/arch/riscv/kernel/stacktrace.c
+@@ -58,7 +58,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
+ } else {
+ fp = frame->fp;
+ pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+- (unsigned long *)(fp - 8));
++ &frame->ra);
+ }
+
+ }
+diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
+index 7acbfbd14557e..80ce9caba8d22 100644
+--- a/arch/riscv/mm/context.c
++++ b/arch/riscv/mm/context.c
+@@ -196,6 +196,16 @@ switch_mm_fast:
+
+ if (need_flush_tlb)
+ local_flush_tlb_all();
++#ifdef CONFIG_SMP
++ else {
++ cpumask_t *mask = &mm->context.tlb_stale_mask;
++
++ if (cpumask_test_cpu(cpu, mask)) {
++ cpumask_clear_cpu(cpu, mask);
++ local_flush_tlb_all_asid(cntx & asid_mask);
++ }
++ }
++#endif
+ }
+
+ static void set_mm_noasid(struct mm_struct *mm)
+diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
+index 37ed760d007c3..ce7dfc81bb3fe 100644
+--- a/arch/riscv/mm/tlbflush.c
++++ b/arch/riscv/mm/tlbflush.c
+@@ -5,23 +5,7 @@
+ #include <linux/sched.h>
+ #include <asm/sbi.h>
+ #include <asm/mmu_context.h>
+-
+-static inline void local_flush_tlb_all_asid(unsigned long asid)
+-{
+- __asm__ __volatile__ ("sfence.vma x0, %0"
+- :
+- : "r" (asid)
+- : "memory");
+-}
+-
+-static inline void local_flush_tlb_page_asid(unsigned long addr,
+- unsigned long asid)
+-{
+- __asm__ __volatile__ ("sfence.vma %0, %1"
+- :
+- : "r" (addr), "r" (asid)
+- : "memory");
+-}
++#include <asm/tlbflush.h>
+
+ void flush_tlb_all(void)
+ {
+@@ -31,6 +15,7 @@ void flush_tlb_all(void)
+ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ unsigned long size, unsigned long stride)
+ {
++ struct cpumask *pmask = &mm->context.tlb_stale_mask;
+ struct cpumask *cmask = mm_cpumask(mm);
+ unsigned int cpuid;
+ bool broadcast;
+@@ -44,6 +29,15 @@ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ if (static_branch_unlikely(&use_asid_allocator)) {
+ unsigned long asid = atomic_long_read(&mm->context.id);
+
++ /*
++ * TLB will be immediately flushed on harts concurrently
++ * executing this MM context. TLB flush on other harts
++ * is deferred until this MM context migrates there.
++ */
++ cpumask_setall(pmask);
++ cpumask_clear_cpu(cpuid, pmask);
++ cpumask_andnot(pmask, pmask, cmask);
++
+ if (broadcast) {
+ sbi_remote_sfence_vma_asid(cmask, start, size, asid);
+ } else if (size <= stride) {
+diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
+index 2adeaf4de4df6..b363fddc2a89e 100644
+--- a/arch/x86/events/intel/uncore.h
++++ b/arch/x86/events/intel/uncore.h
+@@ -2,6 +2,7 @@
+ #include <linux/slab.h>
+ #include <linux/pci.h>
+ #include <asm/apicdef.h>
++#include <asm/intel-family.h>
+ #include <linux/io-64-nonatomic-lo-hi.h>
+
+ #include <linux/perf_event.h>
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index fcd95e93f479a..8f371f3cbbd24 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -3804,6 +3804,21 @@ static const struct attribute_group *skx_iio_attr_update[] = {
+ NULL,
+ };
+
++static void pmu_clear_mapping_attr(const struct attribute_group **groups,
++ struct attribute_group *ag)
++{
++ int i;
++
++ for (i = 0; groups[i]; i++) {
++ if (groups[i] == ag) {
++ for (i++; groups[i]; i++)
++ groups[i - 1] = groups[i];
++ groups[i - 1] = NULL;
++ break;
++ }
++ }
++}
++
+ static int
+ pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
+ {
+@@ -3852,7 +3867,7 @@ clear_attrs:
+ clear_topology:
+ kfree(type->topology);
+ clear_attr_update:
+- type->attr_update = NULL;
++ pmu_clear_mapping_attr(type->attr_update, ag);
+ return ret;
+ }
+
+@@ -5144,6 +5159,11 @@ static int icx_iio_get_topology(struct intel_uncore_type *type)
+
+ static int icx_iio_set_mapping(struct intel_uncore_type *type)
+ {
++ /* Detect ICX-D system. This case is not supported */
++ if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
++ pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
++ return -EPERM;
++ }
+ return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
+ }
+
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index 1c87501e0fa3d..10fb5b5c9efa4 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -788,6 +788,24 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ return status & MCI_STATUS_DEFERRED;
+ }
+
++static bool _log_error_deferred(unsigned int bank, u32 misc)
++{
++ if (!_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
++ mca_msr_reg(bank, MCA_ADDR), misc))
++ return false;
++
++ /*
++ * Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers.
++ * Return true here to avoid accessing these registers.
++ */
++ if (!mce_flags.smca)
++ return true;
++
++ /* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */
++ wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ return true;
++}
++
+ /*
+ * We have three scenarios for checking for Deferred errors:
+ *
+@@ -799,19 +817,8 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ */
+ static void log_error_deferred(unsigned int bank)
+ {
+- bool defrd;
+-
+- defrd = _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
+- mca_msr_reg(bank, MCA_ADDR), 0);
+-
+- if (!mce_flags.smca)
+- return;
+-
+- /* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */
+- if (defrd) {
+- wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ if (_log_error_deferred(bank, 0))
+ return;
+- }
+
+ /*
+ * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
+@@ -832,7 +839,7 @@ static void amd_deferred_error_interrupt(void)
+
+ static void log_error_thresholding(unsigned int bank, u64 misc)
+ {
+- _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS), mca_msr_reg(bank, MCA_ADDR), misc);
++ _log_error_deferred(bank, misc);
+ }
+
+ static void log_and_reset_block(struct threshold_block *block)
+diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
+index 025c8f0cd948c..40e74a9bef07a 100644
+--- a/arch/x86/kernel/cpu/microcode/intel.c
++++ b/arch/x86/kernel/cpu/microcode/intel.c
+@@ -621,7 +621,6 @@ void load_ucode_intel_ap(void)
+ else
+ iup = &intel_ucode_patch;
+
+-reget:
+ if (!*iup) {
+ patch = __load_ucode_intel(&uci);
+ if (!patch)
+@@ -632,12 +631,7 @@ reget:
+
+ uci.mc = *iup;
+
+- if (apply_microcode_early(&uci, true)) {
+- /* Mixed-silicon system? Try to refetch the proper patch: */
+- *iup = NULL;
+-
+- goto reget;
+- }
++ apply_microcode_early(&uci, true);
+ }
+
+ static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
+diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
+index 59e543b95a3c6..c2dde46a538e7 100644
+--- a/arch/x86/kernel/fpu/xstate.c
++++ b/arch/x86/kernel/fpu/xstate.c
+@@ -440,8 +440,8 @@ static void __init __xstate_dump_leaves(void)
+ }
+ }
+
+-#define XSTATE_WARN_ON(x) do { \
+- if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) { \
++#define XSTATE_WARN_ON(x, fmt, ...) do { \
++ if (WARN_ONCE(x, "XSAVE consistency problem: " fmt, ##__VA_ARGS__)) { \
+ __xstate_dump_leaves(); \
+ } \
+ } while (0)
+@@ -554,8 +554,7 @@ static bool __init check_xstate_against_struct(int nr)
+ (nr >= XFEATURE_MAX) ||
+ (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) ||
+ ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_RSRVD_COMP_16))) {
+- WARN_ONCE(1, "no structure for xstate: %d\n", nr);
+- XSTATE_WARN_ON(1);
++ XSTATE_WARN_ON(1, "No structure for xstate: %d\n", nr);
+ return false;
+ }
+ return true;
+@@ -598,12 +597,13 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
+ * XSAVES.
+ */
+ if (!xsaves && xfeature_is_supervisor(i)) {
+- XSTATE_WARN_ON(1);
++ XSTATE_WARN_ON(1, "Got supervisor feature %d, but XSAVES not advertised\n", i);
+ return false;
+ }
+ }
+ size = xstate_calculate_size(fpu_kernel_cfg.max_features, compacted);
+- XSTATE_WARN_ON(size != kernel_size);
++ XSTATE_WARN_ON(size != kernel_size,
++ "size %u != kernel_size %u\n", size, kernel_size);
+ return size == kernel_size;
+ }
+
+diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
+index bd165004776d9..e07234ec7e237 100644
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -217,7 +217,9 @@ void ftrace_replace_code(int enable)
+
+ ret = ftrace_verify_code(rec->ip, old);
+ if (ret) {
++ ftrace_expected = old;
+ ftrace_bug(ret, rec);
++ ftrace_expected = NULL;
+ return;
+ }
+ }
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 4c3c27b6aea3b..c6dd7ae68c8fb 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -37,6 +37,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/kasan.h>
+ #include <linux/moduleloader.h>
+@@ -283,12 +284,15 @@ static int can_probe(unsigned long paddr)
+ if (ret < 0)
+ return 0;
+
++#ifdef CONFIG_KGDB
+ /*
+- * Another debugging subsystem might insert this breakpoint.
+- * In that case, we can't recover it.
++ * If there is a dynamically installed kgdb sw breakpoint,
++ * this function should not be probed.
+ */
+- if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
++ if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++ kgdb_has_hit_break(addr))
+ return 0;
++#endif
+ addr += insn.length;
+ }
+
+diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
+index e6b8c5362b945..e57e07b0edb64 100644
+--- a/arch/x86/kernel/kprobes/opt.c
++++ b/arch/x86/kernel/kprobes/opt.c
+@@ -15,6 +15,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/objtool.h>
+ #include <linux/pgtable.h>
+@@ -279,19 +280,6 @@ static int insn_is_indirect_jump(struct insn *insn)
+ return ret;
+ }
+
+-static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
+-{
+- unsigned char ops;
+-
+- for (; addr < eaddr; addr++) {
+- if (get_kernel_nofault(ops, (void *)addr) < 0 ||
+- ops != INT3_INSN_OPCODE)
+- return false;
+- }
+-
+- return true;
+-}
+-
+ /* Decode whole function to ensure any instructions don't jump into target */
+ static int can_optimize(unsigned long paddr)
+ {
+@@ -334,15 +322,15 @@ static int can_optimize(unsigned long paddr)
+ ret = insn_decode_kernel(&insn, (void *)recovered_insn);
+ if (ret < 0)
+ return 0;
+-
++#ifdef CONFIG_KGDB
+ /*
+- * In the case of detecting unknown breakpoint, this could be
+- * a padding INT3 between functions. Let's check that all the
+- * rest of the bytes are also INT3.
++ * If there is a dynamically installed kgdb sw breakpoint,
++ * this function should not be probed.
+ */
+- if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
+- return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
+-
++ if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++ kgdb_has_hit_break(addr))
++ return 0;
++#endif
+ /* Recover address */
+ insn.kaddr = (void *)addr;
+ insn.next_byte = (void *)(addr + insn.length);
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index 9dda989a1cf01..4064ce1941ea7 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -2722,8 +2722,6 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
+ icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
+ __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
+ }
+- } else {
+- kvm_lapic_xapic_id_updated(vcpu->arch.apic);
+ }
+
+ return 0;
+@@ -2759,6 +2757,9 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
+ }
+ memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s));
+
++ if (!apic_x2apic_mode(apic))
++ kvm_lapic_xapic_id_updated(apic);
++
+ atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY);
+ kvm_recalculate_apic_map(vcpu->kvm);
+ kvm_apic_set_version(vcpu);
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index f56cc2382edf9..cf8fbbd74f9c3 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -4953,24 +4953,35 @@ static int handle_vmxon(struct kvm_vcpu *vcpu)
+ | FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
+
+ /*
+- * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
+- * that have higher priority than VM-Exit (see Intel SDM's pseudocode
+- * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
+- * running the guest, i.e. KVM needs to check the _guest_ values.
++ * Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter
++ * the guest and so cannot rely on hardware to perform the check,
++ * which has higher priority than VM-Exit (see Intel SDM's pseudocode
++ * for VMXON).
+ *
+- * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
+- * !COMPATIBILITY modes. KVM may run the guest in VM86 to emulate Real
+- * Mode, but KVM will never take the guest out of those modes.
++ * Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86
++ * and !COMPATIBILITY modes. For an unrestricted guest, KVM doesn't
++ * force any of the relevant guest state. For a restricted guest, KVM
++ * does force CR0.PE=1, but only to also force VM86 in order to emulate
++ * Real Mode, and so there's no need to check CR0.PE manually.
+ */
+- if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+- !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++ if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 1;
+ }
+
+ /*
+- * CPL=0 and all other checks that are lower priority than VM-Exit must
+- * be checked manually.
++ * The CPL is checked for "not in VMX operation" and for "in VMX root",
++ * and has higher priority than the VM-Fail due to being post-VMXON,
++ * i.e. VMXON #GPs outside of VMX non-root if CPL!=0. In VMX non-root,
++ * VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits
++ * from L2 to L1, i.e. there's no need to check for the vCPU being in
++ * VMX non-root.
++ *
++ * Forwarding the VM-Exit unconditionally, i.e. without performing the
++ * #UD checks (see above), is functionally ok because KVM doesn't allow
++ * L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's
++ * CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are
++ * missed by hardware due to shadowing CR0 and/or CR4.
+ */
+ if (vmx_get_cpl(vcpu)) {
+ kvm_inject_gp(vcpu, 0);
+@@ -4980,6 +4991,17 @@ static int handle_vmxon(struct kvm_vcpu *vcpu)
+ if (vmx->nested.vmxon)
+ return nested_vmx_fail(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
+
++ /*
++ * Invalid CR0/CR4 generates #GP. These checks are performed if and
++ * only if the vCPU isn't already in VMX operation, i.e. effectively
++ * have lower priority than the VM-Fail above.
++ */
++ if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
++ !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++ kvm_inject_gp(vcpu, 0);
++ return 1;
++ }
++
+ if ((vmx->msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
+ != VMXON_NEEDED_FEATURES) {
+ kvm_inject_gp(vcpu, 0);
+@@ -6663,7 +6685,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
+ SECONDARY_EXEC_ENABLE_INVPCID |
+ SECONDARY_EXEC_RDSEED_EXITING |
+ SECONDARY_EXEC_XSAVES |
+- SECONDARY_EXEC_TSC_SCALING;
++ SECONDARY_EXEC_TSC_SCALING |
++ SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
+
+ /*
+ * We can emulate "VMCS shadowing," even if the hardware
+diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c
+index aba8cebdc587f..3ed7d35fe9658 100644
+--- a/arch/x86/kvm/vmx/sgx.c
++++ b/arch/x86/kvm/vmx/sgx.c
+@@ -182,8 +182,10 @@ static int __handle_encls_ecreate(struct kvm_vcpu *vcpu,
+ /* Enforce CPUID restriction on max enclave size. */
+ max_size_log2 = (attributes & SGX_ATTR_MODE64BIT) ? sgx_12_0->edx >> 8 :
+ sgx_12_0->edx;
+- if (size >= BIT_ULL(max_size_log2))
++ if (size >= BIT_ULL(max_size_log2)) {
+ kvm_inject_gp(vcpu, 0);
++ return 1;
++ }
+
+ /*
+ * sgx_virt_ecreate() returns:
+diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
+index b0bc8897c924f..2a31b1ab0c9f2 100644
+--- a/arch/xtensa/kernel/xtensa_ksyms.c
++++ b/arch/xtensa/kernel/xtensa_ksyms.c
+@@ -62,6 +62,7 @@ extern int __modsi3(int, int);
+ extern int __mulsi3(int, int);
+ extern unsigned int __udivsi3(unsigned int, unsigned int);
+ extern unsigned int __umodsi3(unsigned int, unsigned int);
++extern unsigned long long __umulsidi3(unsigned int, unsigned int);
+
+ EXPORT_SYMBOL(__ashldi3);
+ EXPORT_SYMBOL(__ashrdi3);
+@@ -71,6 +72,7 @@ EXPORT_SYMBOL(__modsi3);
+ EXPORT_SYMBOL(__mulsi3);
+ EXPORT_SYMBOL(__udivsi3);
+ EXPORT_SYMBOL(__umodsi3);
++EXPORT_SYMBOL(__umulsidi3);
+
+ unsigned int __sync_fetch_and_and_4(volatile void *p, unsigned int v)
+ {
+diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
+index d4e9c397e3fde..7ecef0519a27c 100644
+--- a/arch/xtensa/lib/Makefile
++++ b/arch/xtensa/lib/Makefile
+@@ -5,7 +5,7 @@
+
+ lib-y += memcopy.o memset.o checksum.o \
+ ashldi3.o ashrdi3.o lshrdi3.o \
+- divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o \
++ divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o umulsidi3.o \
+ usercopy.o strncpy_user.o strnlen_user.o
+ lib-$(CONFIG_PCI) += pci-auto.o
+ lib-$(CONFIG_KCSAN) += kcsan-stubs.o
+diff --git a/arch/xtensa/lib/umulsidi3.S b/arch/xtensa/lib/umulsidi3.S
+new file mode 100644
+index 0000000000000..1360816479427
+--- /dev/null
++++ b/arch/xtensa/lib/umulsidi3.S
+@@ -0,0 +1,230 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */
++#include <linux/linkage.h>
++#include <asm/asmmacro.h>
++#include <asm/core.h>
++
++#if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
++#define XCHAL_NO_MUL 1
++#endif
++
++ENTRY(__umulsidi3)
++
++#ifdef __XTENSA_CALL0_ABI__
++ abi_entry(32)
++ s32i a12, sp, 16
++ s32i a13, sp, 20
++ s32i a14, sp, 24
++ s32i a15, sp, 28
++#elif XCHAL_NO_MUL
++ /* This is not really a leaf function; allocate enough stack space
++ to allow CALL12s to a helper function. */
++ abi_entry(32)
++#else
++ abi_entry_default
++#endif
++
++#ifdef __XTENSA_EB__
++#define wh a2
++#define wl a3
++#else
++#define wh a3
++#define wl a2
++#endif /* __XTENSA_EB__ */
++
++ /* This code is taken from the mulsf3 routine in ieee754-sf.S.
++ See more comments there. */
++
++#if XCHAL_HAVE_MUL32_HIGH
++ mull a6, a2, a3
++ muluh wh, a2, a3
++ mov wl, a6
++
++#else /* ! MUL32_HIGH */
++
++#if defined(__XTENSA_CALL0_ABI__) && XCHAL_NO_MUL
++ /* a0 and a8 will be clobbered by calling the multiply function
++ but a8 is not used here and need not be saved. */
++ s32i a0, sp, 0
++#endif
++
++#if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32
++
++#define a2h a4
++#define a3h a5
++
++ /* Get the high halves of the inputs into registers. */
++ srli a2h, a2, 16
++ srli a3h, a3, 16
++
++#define a2l a2
++#define a3l a3
++
++#if XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MUL16
++ /* Clear the high halves of the inputs. This does not matter
++ for MUL16 because the high bits are ignored. */
++ extui a2, a2, 0, 16
++ extui a3, a3, 0, 16
++#endif
++#endif /* MUL16 || MUL32 */
++
++
++#if XCHAL_HAVE_MUL16
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++ mul16u dst, xreg ## xhalf, yreg ## yhalf
++
++#elif XCHAL_HAVE_MUL32
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++ mull dst, xreg ## xhalf, yreg ## yhalf
++
++#elif XCHAL_HAVE_MAC16
++
++/* The preprocessor insists on inserting a space when concatenating after
++ a period in the definition of do_mul below. These macros are a workaround
++ using underscores instead of periods when doing the concatenation. */
++#define umul_aa_ll umul.aa.ll
++#define umul_aa_lh umul.aa.lh
++#define umul_aa_hl umul.aa.hl
++#define umul_aa_hh umul.aa.hh
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++ umul_aa_ ## xhalf ## yhalf xreg, yreg; \
++ rsr dst, ACCLO
++
++#else /* no multiply hardware */
++
++#define set_arg_l(dst, src) \
++ extui dst, src, 0, 16
++#define set_arg_h(dst, src) \
++ srli dst, src, 16
++
++#ifdef __XTENSA_CALL0_ABI__
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++ set_arg_ ## xhalf (a13, xreg); \
++ set_arg_ ## yhalf (a14, yreg); \
++ call0 .Lmul_mulsi3; \
++ mov dst, a12
++#else
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++ set_arg_ ## xhalf (a14, xreg); \
++ set_arg_ ## yhalf (a15, yreg); \
++ call12 .Lmul_mulsi3; \
++ mov dst, a14
++#endif /* __XTENSA_CALL0_ABI__ */
++
++#endif /* no multiply hardware */
++
++ /* Add pp1 and pp2 into a6 with carry-out in a9. */
++ do_mul(a6, a2, l, a3, h) /* pp 1 */
++ do_mul(a11, a2, h, a3, l) /* pp 2 */
++ movi a9, 0
++ add a6, a6, a11
++ bgeu a6, a11, 1f
++ addi a9, a9, 1
++1:
++ /* Shift the high half of a9/a6 into position in a9. Note that
++ this value can be safely incremented without any carry-outs. */
++ ssai 16
++ src a9, a9, a6
++
++ /* Compute the low word into a6. */
++ do_mul(a11, a2, l, a3, l) /* pp 0 */
++ sll a6, a6
++ add a6, a6, a11
++ bgeu a6, a11, 1f
++ addi a9, a9, 1
++1:
++ /* Compute the high word into wh. */
++ do_mul(wh, a2, h, a3, h) /* pp 3 */
++ add wh, wh, a9
++ mov wl, a6
++
++#endif /* !MUL32_HIGH */
++
++#if defined(__XTENSA_CALL0_ABI__) && XCHAL_NO_MUL
++ /* Restore the original return address. */
++ l32i a0, sp, 0
++#endif
++#ifdef __XTENSA_CALL0_ABI__
++ l32i a12, sp, 16
++ l32i a13, sp, 20
++ l32i a14, sp, 24
++ l32i a15, sp, 28
++ abi_ret(32)
++#else
++ abi_ret_default
++#endif
++
++#if XCHAL_NO_MUL
++
++ .macro do_addx2 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++ addx2 \dst, \as, \at
++#else
++ slli \tmp, \as, 1
++ add \dst, \tmp, \at
++#endif
++ .endm
++
++ .macro do_addx4 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++ addx4 \dst, \as, \at
++#else
++ slli \tmp, \as, 2
++ add \dst, \tmp, \at
++#endif
++ .endm
++
++ .macro do_addx8 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++ addx8 \dst, \as, \at
++#else
++ slli \tmp, \as, 3
++ add \dst, \tmp, \at
++#endif
++ .endm
++
++ /* For Xtensa processors with no multiply hardware, this simplified
++ version of _mulsi3 is used for multiplying 16-bit chunks of
++ the floating-point mantissas. When using CALL0, this function
++ uses a custom ABI: the inputs are passed in a13 and a14, the
++ result is returned in a12, and a8 and a15 are clobbered. */
++ .align 4
++.Lmul_mulsi3:
++ abi_entry_default
++
++ .macro mul_mulsi3_body dst, src1, src2, tmp1, tmp2
++ movi \dst, 0
++1: add \tmp1, \src2, \dst
++ extui \tmp2, \src1, 0, 1
++ movnez \dst, \tmp1, \tmp2
++
++ do_addx2 \tmp1, \src2, \dst, \tmp1
++ extui \tmp2, \src1, 1, 1
++ movnez \dst, \tmp1, \tmp2
++
++ do_addx4 \tmp1, \src2, \dst, \tmp1
++ extui \tmp2, \src1, 2, 1
++ movnez \dst, \tmp1, \tmp2
++
++ do_addx8 \tmp1, \src2, \dst, \tmp1
++ extui \tmp2, \src1, 3, 1
++ movnez \dst, \tmp1, \tmp2
++
++ srli \src1, \src1, 4
++ slli \src2, \src2, 4
++ bnez \src1, 1b
++ .endm
++
++#ifdef __XTENSA_CALL0_ABI__
++ mul_mulsi3_body a12, a13, a14, a15, a8
++#else
++ /* The result will be written into a2, so save that argument in a4. */
++ mov a4, a2
++ mul_mulsi3_body a2, a4, a3, a5, a6
++#endif
++ abi_ret_default
++#endif /* XCHAL_NO_MUL */
++
++ENDPROC(__umulsidi3)
+diff --git a/block/mq-deadline.c b/block/mq-deadline.c
+index 5639921dfa922..6672f1bce3795 100644
+--- a/block/mq-deadline.c
++++ b/block/mq-deadline.c
+@@ -130,6 +130,20 @@ static u8 dd_rq_ioclass(struct request *rq)
+ return IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
+ }
+
++/*
++ * get the request before `rq' in sector-sorted order
++ */
++static inline struct request *
++deadline_earlier_request(struct request *rq)
++{
++ struct rb_node *node = rb_prev(&rq->rb_node);
++
++ if (node)
++ return rb_entry_rq(node);
++
++ return NULL;
++}
++
+ /*
+ * get the request after `rq' in sector-sorted order
+ */
+@@ -277,6 +291,39 @@ static inline int deadline_check_fifo(struct dd_per_prio *per_prio,
+ return 0;
+ }
+
++/*
++ * Check if rq has a sequential request preceding it.
++ */
++static bool deadline_is_seq_writes(struct deadline_data *dd, struct request *rq)
++{
++ struct request *prev = deadline_earlier_request(rq);
++
++ if (!prev)
++ return false;
++
++ return blk_rq_pos(prev) + blk_rq_sectors(prev) == blk_rq_pos(rq);
++}
++
++/*
++ * Skip all write requests that are sequential from @rq, even if we cross
++ * a zone boundary.
++ */
++static struct request *deadline_skip_seq_writes(struct deadline_data *dd,
++ struct request *rq)
++{
++ sector_t pos = blk_rq_pos(rq);
++ sector_t skipped_sectors = 0;
++
++ while (rq) {
++ if (blk_rq_pos(rq) != pos + skipped_sectors)
++ break;
++ skipped_sectors += blk_rq_sectors(rq);
++ rq = deadline_latter_request(rq);
++ }
++
++ return rq;
++}
++
+ /*
+ * For the specified data direction, return the next request to
+ * dispatch using arrival ordered lists.
+@@ -297,11 +344,16 @@ deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+
+ /*
+ * Look for a write request that can be dispatched, that is one with
+- * an unlocked target zone.
++ * an unlocked target zone. For some HDDs, breaking a sequential
++ * write stream can lead to lower throughput, so make sure to preserve
++ * sequential write streams, even if that stream crosses into the next
++ * zones and these zones are unlocked.
+ */
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
+- if (blk_req_can_dispatch_to_zone(rq))
++ if (blk_req_can_dispatch_to_zone(rq) &&
++ (blk_queue_nonrot(rq->q) ||
++ !deadline_is_seq_writes(dd, rq)))
+ goto out;
+ }
+ rq = NULL;
+@@ -331,13 +383,19 @@ deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+
+ /*
+ * Look for a write request that can be dispatched, that is one with
+- * an unlocked target zone.
++ * an unlocked target zone. For some HDDs, breaking a sequential
++ * write stream can lead to lower throughput, so make sure to preserve
++ * sequential write streams, even if that stream crosses into the next
++ * zones and these zones are unlocked.
+ */
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ while (rq) {
+ if (blk_req_can_dispatch_to_zone(rq))
+ break;
+- rq = deadline_latter_request(rq);
++ if (blk_queue_nonrot(rq->q))
++ rq = deadline_latter_request(rq);
++ else
++ rq = deadline_skip_seq_writes(dd, rq);
+ }
+ spin_unlock_irqrestore(&dd->zone_lock, flags);
+
+@@ -789,6 +847,18 @@ static void dd_prepare_request(struct request *rq)
+ rq->elv.priv[0] = NULL;
+ }
+
++static bool dd_has_write_work(struct blk_mq_hw_ctx *hctx)
++{
++ struct deadline_data *dd = hctx->queue->elevator->elevator_data;
++ enum dd_prio p;
++
++ for (p = 0; p <= DD_PRIO_MAX; p++)
++ if (!list_empty_careful(&dd->per_prio[p].fifo_list[DD_WRITE]))
++ return true;
++
++ return false;
++}
++
+ /*
+ * Callback from inside blk_mq_free_request().
+ *
+@@ -828,9 +898,10 @@ static void dd_finish_request(struct request *rq)
+
+ spin_lock_irqsave(&dd->zone_lock, flags);
+ blk_req_zone_write_unlock(rq);
+- if (!list_empty(&per_prio->fifo_list[DD_WRITE]))
+- blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ spin_unlock_irqrestore(&dd->zone_lock, flags);
++
++ if (dd_has_write_work(rq->mq_hctx))
++ blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ }
+ }
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index ec69b43f926ae..6669daf1f31fe 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1162,7 +1162,11 @@ static int __driver_attach(struct device *dev, void *data)
+ return 0;
+ } else if (ret < 0) {
+ dev_dbg(dev, "Bus failed to match device: %d\n", ret);
+- return ret;
++ /*
++ * Driver could not match with device, but may match with
++ * another device on the bus.
++ */
++ return 0;
+ } /* ret > 0 means positive match */
+
+ if (driver_allows_async_probing(drv)) {
+diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c
+index 4a42186ff1112..083459028a4b8 100644
+--- a/drivers/bus/mhi/host/pm.c
++++ b/drivers/bus/mhi/host/pm.c
+@@ -301,7 +301,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl)
+ read_lock_irq(&mhi_chan->lock);
+
+ /* Only ring DB if ring is not empty */
+- if (tre_ring->base && tre_ring->wp != tre_ring->rp)
++ if (tre_ring->base && tre_ring->wp != tre_ring->rp &&
++ mhi_chan->ch_state == MHI_CH_STATE_ENABLED)
+ mhi_ring_chan_db(mhi_cntrl, mhi_chan);
+ read_unlock_irq(&mhi_chan->lock);
+ }
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index c9e32d100b7eb..b151cbfc3d9b9 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -1336,6 +1336,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ unsigned long flags;
+ struct cmd_rcvr *rcvr;
+ struct cmd_rcvr *rcvrs = NULL;
++ struct module *owner;
+
+ if (!acquire_ipmi_user(user, &i)) {
+ /*
+@@ -1398,8 +1399,9 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ kfree(rcvr);
+ }
+
++ owner = intf->owner;
+ kref_put(&intf->refcount, intf_free);
+- module_put(intf->owner);
++ module_put(owner);
+ }
+
+ int ipmi_destroy_user(struct ipmi_user *user)
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 6e357ad76f2eb..abddd7e43a9a6 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -2153,6 +2153,20 @@ skip_fallback_noirq:
+ }
+ module_init(init_ipmi_si);
+
++static void wait_msg_processed(struct smi_info *smi_info)
++{
++ unsigned long jiffies_now;
++ long time_diff;
++
++ while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
++ jiffies_now = jiffies;
++ time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
++ * SI_USEC_PER_JIFFY);
++ smi_event_handler(smi_info, time_diff);
++ schedule_timeout_uninterruptible(1);
++ }
++}
++
+ static void shutdown_smi(void *send_info)
+ {
+ struct smi_info *smi_info = send_info;
+@@ -2187,16 +2201,13 @@ static void shutdown_smi(void *send_info)
+ * in the BMC. Note that timers and CPU interrupts are off,
+ * so no need for locks.
+ */
+- while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+- poll(smi_info);
+- schedule_timeout_uninterruptible(1);
+- }
++ wait_msg_processed(smi_info);
++
+ if (smi_info->handlers)
+ disable_si_irq(smi_info);
+- while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+- poll(smi_info);
+- schedule_timeout_uninterruptible(1);
+- }
++
++ wait_msg_processed(smi_info);
++
+ if (smi_info->handlers)
+ smi_info->handlers->cleanup(smi_info->si_sm);
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 69b3d61852ac6..7e56a42750ea5 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1207,6 +1207,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
+ goto err_free_rcpumask;
+
++ init_completion(&policy->kobj_unregister);
+ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+ cpufreq_global_kobject, "policy%u", cpu);
+ if (ret) {
+@@ -1245,7 +1246,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ init_rwsem(&policy->rwsem);
+ spin_lock_init(&policy->transition_lock);
+ init_waitqueue_head(&policy->transition_wait);
+- init_completion(&policy->kobj_unregister);
+ INIT_WORK(&policy->update, handle_update);
+
+ policy->cpu = cpu;
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 79d9e14b70c87..0d0b96a7f4c07 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -790,8 +790,8 @@ config CRYPTO_DEV_CCREE
+ select CRYPTO_ECB
+ select CRYPTO_CTR
+ select CRYPTO_XTS
+- select CRYPTO_SM4
+- select CRYPTO_SM3
++ select CRYPTO_SM4_GENERIC
++ select CRYPTO_SM3_GENERIC
+ help
+ Say 'Y' to enable a driver for the REE interface of the Arm
+ TrustZone CryptoCell family of processors. Currently the
+diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
+index 792d6da7f0c07..084d052fddccb 100644
+--- a/drivers/crypto/ccp/sp-pci.c
++++ b/drivers/crypto/ccp/sp-pci.c
+@@ -381,6 +381,15 @@ static const struct psp_vdata pspv3 = {
+ .inten_reg = 0x10690,
+ .intsts_reg = 0x10694,
+ };
++
++static const struct psp_vdata pspv4 = {
++ .sev = &sevv2,
++ .tee = &teev1,
++ .feature_reg = 0x109fc,
++ .inten_reg = 0x10690,
++ .intsts_reg = 0x10694,
++};
++
+ #endif
+
+ static const struct sp_dev_vdata dev_vdata[] = {
+@@ -426,7 +435,7 @@ static const struct sp_dev_vdata dev_vdata[] = {
+ { /* 5 */
+ .bar = 2,
+ #ifdef CONFIG_CRYPTO_DEV_SP_PSP
+- .psp_vdata = &pspv2,
++ .psp_vdata = &pspv4,
+ #endif
+ },
+ { /* 6 */
+diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
+index 27e1fa9120639..743ce4fc3158c 100644
+--- a/drivers/crypto/hisilicon/Kconfig
++++ b/drivers/crypto/hisilicon/Kconfig
+@@ -26,7 +26,7 @@ config CRYPTO_DEV_HISI_SEC2
+ select CRYPTO_SHA1
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
+- select CRYPTO_SM4
++ select CRYPTO_SM4_GENERIC
+ depends on PCI && PCI_MSI
+ depends on UACCE || UACCE=n
+ depends on ARM64 || (COMPILE_TEST && 64BIT)
+diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c
+index 3b0bf6fea491a..b4db560105a9e 100644
+--- a/drivers/crypto/n2_core.c
++++ b/drivers/crypto/n2_core.c
+@@ -1229,6 +1229,7 @@ struct n2_hash_tmpl {
+ const u8 *hash_init;
+ u8 hw_op_hashsz;
+ u8 digest_size;
++ u8 statesize;
+ u8 block_size;
+ u8 auth_type;
+ u8 hmac_type;
+@@ -1260,6 +1261,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_MD5,
+ .hw_op_hashsz = MD5_DIGEST_SIZE,
+ .digest_size = MD5_DIGEST_SIZE,
++ .statesize = sizeof(struct md5_state),
+ .block_size = MD5_HMAC_BLOCK_SIZE },
+ { .name = "sha1",
+ .hash_zero = sha1_zero_message_hash,
+@@ -1268,6 +1270,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_SHA1,
+ .hw_op_hashsz = SHA1_DIGEST_SIZE,
+ .digest_size = SHA1_DIGEST_SIZE,
++ .statesize = sizeof(struct sha1_state),
+ .block_size = SHA1_BLOCK_SIZE },
+ { .name = "sha256",
+ .hash_zero = sha256_zero_message_hash,
+@@ -1276,6 +1279,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_HMAC_SHA256,
+ .hw_op_hashsz = SHA256_DIGEST_SIZE,
+ .digest_size = SHA256_DIGEST_SIZE,
++ .statesize = sizeof(struct sha256_state),
+ .block_size = SHA256_BLOCK_SIZE },
+ { .name = "sha224",
+ .hash_zero = sha224_zero_message_hash,
+@@ -1284,6 +1288,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ .hmac_type = AUTH_TYPE_RESERVED,
+ .hw_op_hashsz = SHA256_DIGEST_SIZE,
+ .digest_size = SHA224_DIGEST_SIZE,
++ .statesize = sizeof(struct sha256_state),
+ .block_size = SHA224_BLOCK_SIZE },
+ };
+ #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
+@@ -1424,6 +1429,7 @@ static int __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl)
+
+ halg = &ahash->halg;
+ halg->digestsize = tmpl->digest_size;
++ halg->statesize = tmpl->statesize;
+
+ base = &halg->base;
+ snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 78344e4d4215b..36ef236354557 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1225,7 +1225,7 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ struct cxl_endpoint_decoder *cxled_target;
+ struct cxl_memdev *cxlmd_target;
+
+- cxled_target = p->targets[pos];
++ cxled_target = p->targets[i];
+ if (!cxled_target)
+ continue;
+
+@@ -1922,6 +1922,9 @@ static int cxl_region_probe(struct device *dev)
+ */
+ up_read(&cxl_region_rwsem);
+
++ if (rc)
++ return rc;
++
+ switch (cxlr->mode) {
+ case CXL_DECODER_PMEM:
+ return devm_cxl_add_pmem_region(cxlr);
+diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
+index 63347a5ae5999..8c5f6f7fca112 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -776,8 +776,7 @@ static void remove_sysfs_files(struct devfreq *devfreq,
+ * @dev: the device to add devfreq feature.
+ * @profile: device-specific profile to run devfreq.
+ * @governor_name: name of the policy to choose frequency.
+- * @data: private data for the governor. The devfreq framework does not
+- * touch this value.
++ * @data: devfreq driver pass to governors, governor should not change it.
+ */
+ struct devfreq *devfreq_add_device(struct device *dev,
+ struct devfreq_dev_profile *profile,
+@@ -1011,8 +1010,7 @@ static void devm_devfreq_dev_release(struct device *dev, void *res)
+ * @dev: the device to add devfreq feature.
+ * @profile: device-specific profile to run devfreq.
+ * @governor_name: name of the policy to choose frequency.
+- * @data: private data for the governor. The devfreq framework does not
+- * touch this value.
++ * @data: devfreq driver pass to governors, governor should not change it.
+ *
+ * This function manages automatically the memory of devfreq device using device
+ * resource management and simplify the free operation for memory of devfreq
+diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
+index ab9db7adb3ade..d69672ccacc49 100644
+--- a/drivers/devfreq/governor_userspace.c
++++ b/drivers/devfreq/governor_userspace.c
+@@ -21,7 +21,7 @@ struct userspace_data {
+
+ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
+ {
+- struct userspace_data *data = df->data;
++ struct userspace_data *data = df->governor_data;
+
+ if (data->valid)
+ *freq = data->user_frequency;
+@@ -40,7 +40,7 @@ static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr,
+ int err = 0;
+
+ mutex_lock(&devfreq->lock);
+- data = devfreq->data;
++ data = devfreq->governor_data;
+
+ sscanf(buf, "%lu", &wanted);
+ data->user_frequency = wanted;
+@@ -60,7 +60,7 @@ static ssize_t set_freq_show(struct device *dev,
+ int err = 0;
+
+ mutex_lock(&devfreq->lock);
+- data = devfreq->data;
++ data = devfreq->governor_data;
+
+ if (data->valid)
+ err = sprintf(buf, "%lu\n", data->user_frequency);
+@@ -91,7 +91,7 @@ static int userspace_init(struct devfreq *devfreq)
+ goto out;
+ }
+ data->valid = false;
+- devfreq->data = data;
++ devfreq->governor_data = data;
+
+ err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
+ out:
+@@ -107,8 +107,8 @@ static void userspace_exit(struct devfreq *devfreq)
+ if (devfreq->dev.kobj.sd)
+ sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
+
+- kfree(devfreq->data);
+- devfreq->data = NULL;
++ kfree(devfreq->governor_data);
++ devfreq->governor_data = NULL;
+ }
+
+ static int devfreq_userspace_handler(struct devfreq *devfreq,
+diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
+index 0a638c97702a5..15f63452a9bec 100644
+--- a/drivers/edac/edac_mc_sysfs.c
++++ b/drivers/edac/edac_mc_sysfs.c
+@@ -298,6 +298,14 @@ DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
+ channel_dimm_label_show, channel_dimm_label_store, 6);
+ DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
+ channel_dimm_label_show, channel_dimm_label_store, 7);
++DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR,
++ channel_dimm_label_show, channel_dimm_label_store, 8);
++DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR,
++ channel_dimm_label_show, channel_dimm_label_store, 9);
++DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
++ channel_dimm_label_show, channel_dimm_label_store, 10);
++DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
++ channel_dimm_label_show, channel_dimm_label_store, 11);
+
+ /* Total possible dynamic DIMM Label attribute file table */
+ static struct attribute *dynamic_csrow_dimm_attr[] = {
+@@ -309,6 +317,10 @@ static struct attribute *dynamic_csrow_dimm_attr[] = {
+ &dev_attr_legacy_ch5_dimm_label.attr.attr,
+ &dev_attr_legacy_ch6_dimm_label.attr.attr,
+ &dev_attr_legacy_ch7_dimm_label.attr.attr,
++ &dev_attr_legacy_ch8_dimm_label.attr.attr,
++ &dev_attr_legacy_ch9_dimm_label.attr.attr,
++ &dev_attr_legacy_ch10_dimm_label.attr.attr,
++ &dev_attr_legacy_ch11_dimm_label.attr.attr,
+ NULL
+ };
+
+@@ -329,6 +341,14 @@ DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
+ channel_ce_count_show, NULL, 6);
+ DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
+ channel_ce_count_show, NULL, 7);
++DEVICE_CHANNEL(ch8_ce_count, S_IRUGO,
++ channel_ce_count_show, NULL, 8);
++DEVICE_CHANNEL(ch9_ce_count, S_IRUGO,
++ channel_ce_count_show, NULL, 9);
++DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
++ channel_ce_count_show, NULL, 10);
++DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
++ channel_ce_count_show, NULL, 11);
+
+ /* Total possible dynamic ce_count attribute file table */
+ static struct attribute *dynamic_csrow_ce_count_attr[] = {
+@@ -340,6 +360,10 @@ static struct attribute *dynamic_csrow_ce_count_attr[] = {
+ &dev_attr_legacy_ch5_ce_count.attr.attr,
+ &dev_attr_legacy_ch6_ce_count.attr.attr,
+ &dev_attr_legacy_ch7_ce_count.attr.attr,
++ &dev_attr_legacy_ch8_ce_count.attr.attr,
++ &dev_attr_legacy_ch9_ce_count.attr.attr,
++ &dev_attr_legacy_ch10_ce_count.attr.attr,
++ &dev_attr_legacy_ch11_ce_count.attr.attr,
+ NULL
+ };
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index f04e698e631c5..04c6c804ef65f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2998,14 +2998,15 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
+ continue;
+ }
+
+- /* skip suspend of gfx and psp for S0ix
++ /* skip suspend of gfx/mes and psp for S0ix
+ * gfx is in gfxoff state, so on resume it will exit gfxoff just
+ * like at runtime. PSP is also part of the always on hardware
+ * so no need to suspend it.
+ */
+ if (adev->in_s0ix &&
+ (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP ||
+- adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX))
++ adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
++ adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES))
+ continue;
+
+ /* XXX handle errors */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index de7144b06e933..379e65ea8afb1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2025,6 +2025,15 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+ "See modparam exp_hw_support\n");
+ return -ENODEV;
+ }
++ /* differentiate between P10 and P11 asics with the same DID */
++ if (pdev->device == 0x67FF &&
++ (pdev->revision == 0xE3 ||
++ pdev->revision == 0xE7 ||
++ pdev->revision == 0xF3 ||
++ pdev->revision == 0xF7)) {
++ flags &= ~AMD_ASIC_MASK;
++ flags |= CHIP_POLARIS10;
++ }
+
+ /* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU mapping,
+ * however, SME requires an indirect IOMMU mapping because the encryption
+@@ -2094,12 +2103,12 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+
+ pci_set_drvdata(pdev, ddev);
+
+- ret = amdgpu_driver_load_kms(adev, ent->driver_data);
++ ret = amdgpu_driver_load_kms(adev, flags);
+ if (ret)
+ goto err_pci;
+
+ retry_init:
+- ret = drm_dev_register(ddev, ent->driver_data);
++ ret = drm_dev_register(ddev, flags);
+ if (ret == -EAGAIN && ++retry <= 3) {
+ DRM_INFO("retry init %d\n", retry);
+ /* Don't request EX mode too frequently which is attacking */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index 4570ad4493905..bfe0fc258fc14 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1506,7 +1506,8 @@ u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)
+ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
+ uint32_t domain)
+ {
+- if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) {
++ if ((domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) &&
++ ((adev->asic_type == CHIP_CARRIZO) || (adev->asic_type == CHIP_STONEY))) {
+ domain = AMDGPU_GEM_DOMAIN_VRAM;
+ if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD)
+ domain = AMDGPU_GEM_DOMAIN_GTT;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+index 998b5d17b271b..0e664d0cc8d51 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+@@ -319,7 +319,7 @@ static void mmhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
+
+ tmp = mmMMVM_L2_CNTL5_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+- WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp);
++ WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL5, tmp);
+ }
+
+ static void mmhub_v2_0_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
+index 1b027d069ab40..4638ea7c2eec5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
+@@ -243,7 +243,7 @@ static void mmhub_v2_3_init_cache_regs(struct amdgpu_device *adev)
+
+ tmp = mmMMVM_L2_CNTL5_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+- WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp);
++ WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL5, tmp);
+ }
+
+ static void mmhub_v2_3_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+index a1d26c4d80b8c..16cc82215e2e1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+@@ -275,7 +275,7 @@ static void mmhub_v3_0_init_cache_regs(struct amdgpu_device *adev)
+
+ tmp = regMMVM_L2_CNTL5_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+- WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++ WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+
+ static void mmhub_v3_0_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
+index e8058edc1d108..6bdf2ef0298d6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
+@@ -269,7 +269,7 @@ static void mmhub_v3_0_1_init_cache_regs(struct amdgpu_device *adev)
+
+ tmp = regMMVM_L2_CNTL5_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+- WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++ WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+
+ static void mmhub_v3_0_1_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
+index 770be0a8f7ce7..45465acaa943a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
+@@ -268,7 +268,7 @@ static void mmhub_v3_0_2_init_cache_regs(struct amdgpu_device *adev)
+
+ tmp = regMMVM_L2_CNTL5_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+- WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++ WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+
+ static void mmhub_v3_0_2_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 4b16d9d1e058c..895bbd20dd07a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1511,6 +1511,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ case IP_VERSION(3, 0, 1):
+ case IP_VERSION(3, 1, 2):
+ case IP_VERSION(3, 1, 3):
++ case IP_VERSION(3, 1, 4):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
+ init_data.flags.gpu_vm_support = true;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+index b76f0f7e42998..d6b964cf73bd1 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+@@ -522,9 +522,9 @@ typedef enum {
+ TEMP_HOTSPOT_M,
+ TEMP_MEM,
+ TEMP_VR_GFX,
++ TEMP_VR_SOC,
+ TEMP_VR_MEM0,
+ TEMP_VR_MEM1,
+- TEMP_VR_SOC,
+ TEMP_VR_U,
+ TEMP_LIQUID0,
+ TEMP_LIQUID1,
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index 865d6358918d2..a9122b3b15322 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -28,6 +28,7 @@
+ #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
+ #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0 0x34
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 1983e0d29e9db..c01c6952f31b3 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -288,6 +288,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
+ break;
+ case IP_VERSION(13, 0, 0):
++ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0;
++ break;
+ case IP_VERSION(13, 0, 10):
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
+ break;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index f0121d1716301..b8430601304f0 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -187,6 +187,8 @@ static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] =
+ FEA_MAP(MEM_TEMP_READ),
+ FEA_MAP(ATHUB_MMHUB_PG),
+ FEA_MAP(SOC_PCC),
++ [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
++ [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
+@@ -517,6 +519,23 @@ static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu)
+ dpm_table);
+ if (ret)
+ return ret;
++
++ /*
++ * Update the reported maximum shader clock to the value
++ * which can be guarded to be achieved on all cards. This
++ * is aligned with Window setting. And considering that value
++ * might be not the peak frequency the card can achieve, it
++ * is normal some real-time clock frequency can overtake this
++ * labelled maximum clock frequency(for example in pp_dpm_sclk
++ * sysfs output).
++ */
++ if (skutable->DriverReportedClocks.GameClockAc &&
++ (dpm_table->dpm_levels[dpm_table->count - 1].value >
++ skutable->DriverReportedClocks.GameClockAc)) {
++ dpm_table->dpm_levels[dpm_table->count - 1].value =
++ skutable->DriverReportedClocks.GameClockAc;
++ dpm_table->max = skutable->DriverReportedClocks.GameClockAc;
++ }
+ } else {
+ dpm_table->count = 1;
+ dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
+@@ -779,6 +798,57 @@ static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu,
+ return ret;
+ }
+
++static int smu_v13_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
++ enum smu_clk_type clk_type,
++ uint32_t *min,
++ uint32_t *max)
++{
++ struct smu_13_0_dpm_context *dpm_context =
++ smu->smu_dpm.dpm_context;
++ struct smu_13_0_dpm_table *dpm_table;
++
++ switch (clk_type) {
++ case SMU_MCLK:
++ case SMU_UCLK:
++ /* uclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.uclk_table;
++ break;
++ case SMU_GFXCLK:
++ case SMU_SCLK:
++ /* gfxclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.gfx_table;
++ break;
++ case SMU_SOCCLK:
++ /* socclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.soc_table;
++ break;
++ case SMU_FCLK:
++ /* fclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.fclk_table;
++ break;
++ case SMU_VCLK:
++ case SMU_VCLK1:
++ /* vclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.vclk_table;
++ break;
++ case SMU_DCLK:
++ case SMU_DCLK1:
++ /* dclk dpm table */
++ dpm_table = &dpm_context->dpm_tables.dclk_table;
++ break;
++ default:
++ dev_err(smu->adev->dev, "Unsupported clock type!\n");
++ return -EINVAL;
++ }
++
++ if (min)
++ *min = dpm_table->min;
++ if (max)
++ *max = dpm_table->max;
++
++ return 0;
++}
++
+ static int smu_v13_0_0_read_sensor(struct smu_context *smu,
+ enum amd_pp_sensors sensor,
+ void *data,
+@@ -1281,9 +1351,17 @@ static int smu_v13_0_0_populate_umd_state_clk(struct smu_context *smu)
+ &dpm_context->dpm_tables.fclk_table;
+ struct smu_umd_pstate_table *pstate_table =
+ &smu->pstate_table;
++ struct smu_table_context *table_context = &smu->smu_table;
++ PPTable_t *pptable = table_context->driver_pptable;
++ DriverReportedClocks_t driver_clocks =
++ pptable->SkuTable.DriverReportedClocks;
+
+ pstate_table->gfxclk_pstate.min = gfx_table->min;
+- pstate_table->gfxclk_pstate.peak = gfx_table->max;
++ if (driver_clocks.GameClockAc &&
++ (driver_clocks.GameClockAc < gfx_table->max))
++ pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc;
++ else
++ pstate_table->gfxclk_pstate.peak = gfx_table->max;
+
+ pstate_table->uclk_pstate.min = mem_table->min;
+ pstate_table->uclk_pstate.peak = mem_table->max;
+@@ -1300,12 +1378,12 @@ static int smu_v13_0_0_populate_umd_state_clk(struct smu_context *smu)
+ pstate_table->fclk_pstate.min = fclk_table->min;
+ pstate_table->fclk_pstate.peak = fclk_table->max;
+
+- /*
+- * For now, just use the mininum clock frequency.
+- * TODO: update them when the real pstate settings available
+- */
+- pstate_table->gfxclk_pstate.standard = gfx_table->min;
+- pstate_table->uclk_pstate.standard = mem_table->min;
++ if (driver_clocks.BaseClockAc &&
++ driver_clocks.BaseClockAc < gfx_table->max)
++ pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc;
++ else
++ pstate_table->gfxclk_pstate.standard = gfx_table->max;
++ pstate_table->uclk_pstate.standard = mem_table->max;
+ pstate_table->socclk_pstate.standard = soc_table->min;
+ pstate_table->vclk_pstate.standard = vclk_table->min;
+ pstate_table->dclk_pstate.standard = dclk_table->min;
+@@ -1339,12 +1417,23 @@ out:
+ static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu,
+ uint32_t *speed)
+ {
++ int ret;
++
+ if (!speed)
+ return -EINVAL;
+
+- return smu_v13_0_0_get_smu_metrics_data(smu,
+- METRICS_CURR_FANPWM,
+- speed);
++ ret = smu_v13_0_0_get_smu_metrics_data(smu,
++ METRICS_CURR_FANPWM,
++ speed);
++ if (ret) {
++ dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
++ return ret;
++ }
++
++ /* Convert the PMFW output which is in percent to pwm(255) based */
++ *speed = MIN(*speed * 255 / 100, 255);
++
++ return 0;
+ }
+
+ static int smu_v13_0_0_get_fan_speed_rpm(struct smu_context *smu,
+@@ -1813,7 +1902,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ .get_enabled_mask = smu_cmn_get_enabled_mask,
+ .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable,
+ .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable,
+- .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq,
++ .get_dpm_ultimate_freq = smu_v13_0_0_get_dpm_ultimate_freq,
+ .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
+ .read_sensor = smu_v13_0_0_read_sensor,
+ .feature_is_enabled = smu_cmn_feature_is_enabled,
+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 39deb06a86ba3..222924363a681 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
+@@ -189,6 +189,8 @@ static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] =
+ FEA_MAP(MEM_TEMP_READ),
+ FEA_MAP(ATHUB_MMHUB_PG),
+ FEA_MAP(SOC_PCC),
++ [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
++ [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
+ };
+
+ static struct cmn2asic_mapping smu_v13_0_7_table_map[SMU_TABLE_COUNT] = {
+@@ -1359,12 +1361,23 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
+ static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu,
+ uint32_t *speed)
+ {
++ int ret;
++
+ if (!speed)
+ return -EINVAL;
+
+- return smu_v13_0_7_get_smu_metrics_data(smu,
+- METRICS_CURR_FANPWM,
+- speed);
++ ret = smu_v13_0_7_get_smu_metrics_data(smu,
++ METRICS_CURR_FANPWM,
++ speed);
++ if (ret) {
++ dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
++ return ret;
++ }
++
++ /* Convert the PMFW output which is in percent to pwm(255) based */
++ *speed = MIN(*speed * 255 / 100, 255);
++
++ return 0;
+ }
+
+ static int smu_v13_0_7_get_fan_speed_rpm(struct smu_context *smu,
+diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
+index 1ab083b35e3b9..17eada72bd925 100644
+--- a/drivers/gpu/drm/drm_connector.c
++++ b/drivers/gpu/drm/drm_connector.c
+@@ -505,6 +505,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
+ mutex_destroy(&connector->mutex);
+
+ memset(connector, 0, sizeof(*connector));
++
++ if (dev->registered)
++ drm_sysfs_hotplug_event(dev);
+ }
+ EXPORT_SYMBOL(drm_connector_cleanup);
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+index cc386f8a7116e..5cf13e52f7c94 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+@@ -258,7 +258,12 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
+ if (mapping->use == 0) {
+ mutex_lock(&mmu_context->lock);
+ if (mapping->context == mmu_context)
+- mapping->use += 1;
++ if (va && mapping->iova != va) {
++ etnaviv_iommu_reap_mapping(mapping);
++ mapping = NULL;
++ } else {
++ mapping->use += 1;
++ }
+ else
+ mapping = NULL;
+ mutex_unlock(&mmu_context->lock);
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+index dc1aa738c4f18..55479cb8b1ac3 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+@@ -135,6 +135,19 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,
+ drm_mm_remove_node(&mapping->vram_node);
+ }
+
++void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping)
++{
++ struct etnaviv_iommu_context *context = mapping->context;
++
++ lockdep_assert_held(&context->lock);
++ WARN_ON(mapping->use);
++
++ etnaviv_iommu_remove_mapping(context, mapping);
++ etnaviv_iommu_context_put(mapping->context);
++ mapping->context = NULL;
++ list_del_init(&mapping->mmu_node);
++}
++
+ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
+ struct drm_mm_node *node, size_t size)
+ {
+@@ -202,10 +215,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
+ * this mapping.
+ */
+ list_for_each_entry_safe(m, n, &list, scan_node) {
+- etnaviv_iommu_remove_mapping(context, m);
+- etnaviv_iommu_context_put(m->context);
+- m->context = NULL;
+- list_del_init(&m->mmu_node);
++ etnaviv_iommu_reap_mapping(m);
+ list_del_init(&m->scan_node);
+ }
+
+@@ -257,10 +267,7 @@ static int etnaviv_iommu_insert_exact(struct etnaviv_iommu_context *context,
+ }
+
+ list_for_each_entry_safe(m, n, &scan_list, scan_node) {
+- etnaviv_iommu_remove_mapping(context, m);
+- etnaviv_iommu_context_put(m->context);
+- m->context = NULL;
+- list_del_init(&m->mmu_node);
++ etnaviv_iommu_reap_mapping(m);
+ list_del_init(&m->scan_node);
+ }
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+index e4a0b7d09c2ea..c01a147f0dfdd 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
++++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+@@ -91,6 +91,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context,
+ struct etnaviv_vram_mapping *mapping, u64 va);
+ void etnaviv_iommu_unmap_gem(struct etnaviv_iommu_context *context,
+ struct etnaviv_vram_mapping *mapping);
++void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping);
+
+ int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx,
+ struct etnaviv_vram_mapping *mapping,
+diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+index 75e8cc4337c93..fce69fa446d58 100644
+--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
++++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+@@ -137,9 +137,9 @@ static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi,
+ return ffs(intel_dsi->ports) - 1;
+
+ if (seq_port) {
+- if (intel_dsi->ports & PORT_B)
++ if (intel_dsi->ports & BIT(PORT_B))
+ return PORT_B;
+- else if (intel_dsi->ports & PORT_C)
++ else if (intel_dsi->ports & BIT(PORT_C))
+ return PORT_C;
+ }
+
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index cd75b0ca2555f..c607d1019e80b 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -729,32 +729,69 @@ static int eb_reserve(struct i915_execbuffer *eb)
+ bool unpinned;
+
+ /*
+- * Attempt to pin all of the buffers into the GTT.
+- * This is done in 2 phases:
++ * We have one more buffers that we couldn't bind, which could be due to
++ * various reasons. To resolve this we have 4 passes, with every next
++ * level turning the screws tighter:
+ *
+- * 1. Unbind all objects that do not match the GTT constraints for
+- * the execbuffer (fenceable, mappable, alignment etc).
+- * 2. Bind new objects.
++ * 0. Unbind all objects that do not match the GTT constraints for the
++ * execbuffer (fenceable, mappable, alignment etc). Bind all new
++ * objects. This avoids unnecessary unbinding of later objects in order
++ * to make room for the earlier objects *unless* we need to defragment.
+ *
+- * This avoid unnecessary unbinding of later objects in order to make
+- * room for the earlier objects *unless* we need to defragment.
++ * 1. Reorder the buffers, where objects with the most restrictive
++ * placement requirements go first (ignoring fixed location buffers for
++ * now). For example, objects needing the mappable aperture (the first
++ * 256M of GTT), should go first vs objects that can be placed just
++ * about anywhere. Repeat the previous pass.
+ *
+- * Defragmenting is skipped if all objects are pinned at a fixed location.
++ * 2. Consider buffers that are pinned at a fixed location. Also try to
++ * evict the entire VM this time, leaving only objects that we were
++ * unable to lock. Try again to bind the buffers. (still using the new
++ * buffer order).
++ *
++ * 3. We likely have object lock contention for one or more stubborn
++ * objects in the VM, for which we need to evict to make forward
++ * progress (perhaps we are fighting the shrinker?). When evicting the
++ * VM this time around, anything that we can't lock we now track using
++ * the busy_bo, using the full lock (after dropping the vm->mutex to
++ * prevent deadlocks), instead of trylock. We then continue to evict the
++ * VM, this time with the stubborn object locked, which we can now
++ * hopefully unbind (if still bound in the VM). Repeat until the VM is
++ * evicted. Finally we should be able bind everything.
+ */
+- for (pass = 0; pass <= 2; pass++) {
++ for (pass = 0; pass <= 3; pass++) {
+ int pin_flags = PIN_USER | PIN_VALIDATE;
+
+ if (pass == 0)
+ pin_flags |= PIN_NONBLOCK;
+
+ if (pass >= 1)
+- unpinned = eb_unbind(eb, pass == 2);
++ unpinned = eb_unbind(eb, pass >= 2);
+
+ if (pass == 2) {
+ err = mutex_lock_interruptible(&eb->context->vm->mutex);
+ if (!err) {
+- err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
++ err = i915_gem_evict_vm(eb->context->vm, &eb->ww, NULL);
++ mutex_unlock(&eb->context->vm->mutex);
++ }
++ if (err)
++ return err;
++ }
++
++ if (pass == 3) {
++retry:
++ err = mutex_lock_interruptible(&eb->context->vm->mutex);
++ if (!err) {
++ struct drm_i915_gem_object *busy_bo = NULL;
++
++ err = i915_gem_evict_vm(eb->context->vm, &eb->ww, &busy_bo);
+ mutex_unlock(&eb->context->vm->mutex);
++ if (err && busy_bo) {
++ err = i915_gem_object_lock(busy_bo, &eb->ww);
++ i915_gem_object_put(busy_bo);
++ if (!err)
++ goto retry;
++ }
+ }
+ if (err)
+ return err;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+index 0c5c43852e24d..6f579cb8f2ff6 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+@@ -369,7 +369,7 @@ retry:
+ if (vma == ERR_PTR(-ENOSPC)) {
+ ret = mutex_lock_interruptible(&ggtt->vm.mutex);
+ if (!ret) {
+- ret = i915_gem_evict_vm(&ggtt->vm, &ww);
++ ret = i915_gem_evict_vm(&ggtt->vm, &ww, NULL);
+ mutex_unlock(&ggtt->vm.mutex);
+ }
+ if (ret)
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
+index 85482a04d1584..c3d1726d16b61 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
+@@ -726,6 +726,9 @@ bool i915_gem_object_needs_ccs_pages(struct drm_i915_gem_object *obj)
+ if (!HAS_FLAT_CCS(to_i915(obj->base.dev)))
+ return false;
+
++ if (obj->flags & I915_BO_ALLOC_CCS_AUX)
++ return true;
++
+ for (i = 0; i < obj->mm.n_placements; i++) {
+ /* Compression is not allowed for the objects with smem placement */
+ if (obj->mm.placements[i]->type == INTEL_MEMORY_SYSTEM)
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+index 9f6b14ec189a2..1c3d074b44c34 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
++++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+@@ -325,16 +325,18 @@ struct drm_i915_gem_object {
+ * dealing with userspace objects the CPU fault handler is free to ignore this.
+ */
+ #define I915_BO_ALLOC_GPU_ONLY BIT(6)
++#define I915_BO_ALLOC_CCS_AUX BIT(7)
+ #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
+ I915_BO_ALLOC_VOLATILE | \
+ I915_BO_ALLOC_CPU_CLEAR | \
+ I915_BO_ALLOC_USER | \
+ I915_BO_ALLOC_PM_VOLATILE | \
+ I915_BO_ALLOC_PM_EARLY | \
+- I915_BO_ALLOC_GPU_ONLY)
+-#define I915_BO_READONLY BIT(7)
+-#define I915_TILING_QUIRK_BIT 8 /* unknown swizzling; do not release! */
+-#define I915_BO_PROTECTED BIT(9)
++ I915_BO_ALLOC_GPU_ONLY | \
++ I915_BO_ALLOC_CCS_AUX)
++#define I915_BO_READONLY BIT(8)
++#define I915_TILING_QUIRK_BIT 9 /* unknown swizzling; do not release! */
++#define I915_BO_PROTECTED BIT(10)
+ /**
+ * @mem_flags - Mutable placement-related flags
+ *
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+index 9aad84059d568..aa0ef0c45554b 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+@@ -50,6 +50,7 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
+ container_of(bo->bdev, typeof(*i915), bdev);
+ struct drm_i915_gem_object *backup;
+ struct ttm_operation_ctx ctx = {};
++ unsigned int flags;
+ int err = 0;
+
+ if (bo->resource->mem_type == I915_PL_SYSTEM || obj->ttm.backup)
+@@ -65,7 +66,22 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
+ if (obj->flags & I915_BO_ALLOC_PM_VOLATILE)
+ return 0;
+
+- backup = i915_gem_object_create_shmem(i915, obj->base.size);
++ /*
++ * It seems that we might have some framebuffers still pinned at this
++ * stage, but for such objects we might also need to deal with the CCS
++ * aux state. Make sure we force the save/restore of the CCS state,
++ * otherwise we might observe display corruption, when returning from
++ * suspend.
++ */
++ flags = 0;
++ if (i915_gem_object_needs_ccs_pages(obj)) {
++ WARN_ON_ONCE(!i915_gem_object_is_framebuffer(obj));
++ WARN_ON_ONCE(!pm_apply->allow_gpu);
++
++ flags = I915_BO_ALLOC_CCS_AUX;
++ }
++ backup = i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
++ obj->base.size, 0, flags);
+ if (IS_ERR(backup))
+ return PTR_ERR(backup);
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c
+index 933648cc90ff9..50b6533a35b23 100644
+--- a/drivers/gpu/drm/i915/gt/intel_migrate.c
++++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
+@@ -341,6 +341,16 @@ static int emit_no_arbitration(struct i915_request *rq)
+ return 0;
+ }
+
++static int max_pte_pkt_size(struct i915_request *rq, int pkt)
++{
++ struct intel_ring *ring = rq->ring;
++
++ pkt = min_t(int, pkt, (ring->space - rq->reserved_space) / sizeof(u32) + 5);
++ pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++
++ return pkt;
++}
++
+ static int emit_pte(struct i915_request *rq,
+ struct sgt_dma *it,
+ enum i915_cache_level cache_level,
+@@ -387,8 +397,7 @@ static int emit_pte(struct i915_request *rq,
+ return PTR_ERR(cs);
+
+ /* Pack as many PTE updates as possible into a single MI command */
+- pkt = min_t(int, dword_length, ring->space / sizeof(u32) + 5);
+- pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++ pkt = max_pte_pkt_size(rq, dword_length);
+
+ hdr = cs;
+ *cs++ = MI_STORE_DATA_IMM | REG_BIT(21); /* as qword elements */
+@@ -421,8 +430,7 @@ static int emit_pte(struct i915_request *rq,
+ }
+ }
+
+- pkt = min_t(int, dword_rem, ring->space / sizeof(u32) + 5);
+- pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++ pkt = max_pte_pkt_size(rq, dword_rem);
+
+ hdr = cs;
+ *cs++ = MI_STORE_DATA_IMM | REG_BIT(21);
+diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
+index f025ee4fa5261..a4b4d9b7d26c7 100644
+--- a/drivers/gpu/drm/i915/i915_gem_evict.c
++++ b/drivers/gpu/drm/i915/i915_gem_evict.c
+@@ -416,6 +416,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
+ * @vm: Address space to cleanse
+ * @ww: An optional struct i915_gem_ww_ctx. If not NULL, i915_gem_evict_vm
+ * will be able to evict vma's locked by the ww as well.
++ * @busy_bo: Optional pointer to struct drm_i915_gem_object. If not NULL, then
++ * in the event i915_gem_evict_vm() is unable to trylock an object for eviction,
++ * then @busy_bo will point to it. -EBUSY is also returned. The caller must drop
++ * the vm->mutex, before trying again to acquire the contended lock. The caller
++ * also owns a reference to the object.
+ *
+ * This function evicts all vmas from a vm.
+ *
+@@ -425,7 +430,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
+ * To clarify: This is for freeing up virtual address space, not for freeing
+ * memory in e.g. the shrinker.
+ */
+-int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
++int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww,
++ struct drm_i915_gem_object **busy_bo)
+ {
+ int ret = 0;
+
+@@ -457,15 +463,22 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
+ * the resv is shared among multiple objects, we still
+ * need the object ref.
+ */
+- if (dying_vma(vma) ||
++ if (!i915_gem_object_get_rcu(vma->obj) ||
+ (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx))) {
+ __i915_vma_pin(vma);
+ list_add(&vma->evict_link, &locked_eviction_list);
+ continue;
+ }
+
+- if (!i915_gem_object_trylock(vma->obj, ww))
++ if (!i915_gem_object_trylock(vma->obj, ww)) {
++ if (busy_bo) {
++ *busy_bo = vma->obj; /* holds ref */
++ ret = -EBUSY;
++ break;
++ }
++ i915_gem_object_put(vma->obj);
+ continue;
++ }
+
+ __i915_vma_pin(vma);
+ list_add(&vma->evict_link, &eviction_list);
+@@ -473,25 +486,29 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
+ if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
+ break;
+
+- ret = 0;
+ /* Unbind locked objects first, before unlocking the eviction_list */
+ list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
+ __i915_vma_unpin(vma);
+
+- if (ret == 0)
++ if (ret == 0) {
+ ret = __i915_vma_unbind(vma);
+- if (ret != -EINTR) /* "Get me out of here!" */
+- ret = 0;
++ if (ret != -EINTR) /* "Get me out of here!" */
++ ret = 0;
++ }
++ if (!dying_vma(vma))
++ i915_gem_object_put(vma->obj);
+ }
+
+ list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
+ __i915_vma_unpin(vma);
+- if (ret == 0)
++ if (ret == 0) {
+ ret = __i915_vma_unbind(vma);
+- if (ret != -EINTR) /* "Get me out of here!" */
+- ret = 0;
++ if (ret != -EINTR) /* "Get me out of here!" */
++ ret = 0;
++ }
+
+ i915_gem_object_unlock(vma->obj);
++ i915_gem_object_put(vma->obj);
+ }
+ } while (ret == 0);
+
+diff --git a/drivers/gpu/drm/i915/i915_gem_evict.h b/drivers/gpu/drm/i915/i915_gem_evict.h
+index e593c530f9bd7..bf0ee0e4fe608 100644
+--- a/drivers/gpu/drm/i915/i915_gem_evict.h
++++ b/drivers/gpu/drm/i915/i915_gem_evict.h
+@@ -11,6 +11,7 @@
+ struct drm_mm_node;
+ struct i915_address_space;
+ struct i915_gem_ww_ctx;
++struct drm_i915_gem_object;
+
+ int __must_check i915_gem_evict_something(struct i915_address_space *vm,
+ struct i915_gem_ww_ctx *ww,
+@@ -23,6 +24,7 @@ int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
+ struct drm_mm_node *node,
+ unsigned int flags);
+ int i915_gem_evict_vm(struct i915_address_space *vm,
+- struct i915_gem_ww_ctx *ww);
++ struct i915_gem_ww_ctx *ww,
++ struct drm_i915_gem_object **busy_bo);
+
+ #endif /* __I915_GEM_EVICT_H__ */
+diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
+index 373582cfd8f31..240b7b8ed281d 100644
+--- a/drivers/gpu/drm/i915/i915_vma.c
++++ b/drivers/gpu/drm/i915/i915_vma.c
+@@ -1569,7 +1569,7 @@ static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+ * locked objects when called from execbuf when pinning
+ * is removed. This would probably regress badly.
+ */
+- i915_gem_evict_vm(vm, NULL);
++ i915_gem_evict_vm(vm, NULL, NULL);
+ mutex_unlock(&vm->mutex);
+ }
+ } while (1);
+diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+index 8c6517d29b8e0..37068542aafe7 100644
+--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
++++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+@@ -344,7 +344,7 @@ static int igt_evict_vm(void *arg)
+
+ /* Everything is pinned, nothing should happen */
+ mutex_lock(&ggtt->vm.mutex);
+- err = i915_gem_evict_vm(&ggtt->vm, NULL);
++ err = i915_gem_evict_vm(&ggtt->vm, NULL, NULL);
+ mutex_unlock(&ggtt->vm.mutex);
+ if (err) {
+ pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
+@@ -356,7 +356,7 @@ static int igt_evict_vm(void *arg)
+
+ for_i915_gem_ww(&ww, err, false) {
+ mutex_lock(&ggtt->vm.mutex);
+- err = i915_gem_evict_vm(&ggtt->vm, &ww);
++ err = i915_gem_evict_vm(&ggtt->vm, &ww, NULL);
+ mutex_unlock(&ggtt->vm.mutex);
+ }
+
+diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+index eb8208bfe5ab3..98370b25a4b61 100644
+--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
++++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+@@ -1601,7 +1601,11 @@ static int ingenic_drm_init(void)
+ return err;
+ }
+
+- return platform_driver_register(&ingenic_drm_driver);
++ err = platform_driver_register(&ingenic_drm_driver);
++ if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && err)
++ platform_driver_unregister(ingenic_ipu_driver_ptr);
++
++ return err;
+ }
+ module_init(ingenic_drm_init);
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index ff2f735bbe7a0..5c7dc411b1804 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -309,7 +309,8 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
+ if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
+ box->x != 0 || box->y != 0 || box->z != 0 ||
+ box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
+- box->d != 1 || box_count != 1) {
++ box->d != 1 || box_count != 1 ||
++ box->w > 64 || box->h > 64) {
+ /* TODO handle none page aligned offsets */
+ /* TODO handle more dst & src != 0 */
+ /* TODO handle more then one copy */
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index fdc642362c140..6601b677c2502 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -3385,18 +3385,24 @@ static int __init parse_amd_iommu_options(char *str)
+ static int __init parse_ivrs_ioapic(char *str)
+ {
+ u32 seg = 0, bus, dev, fn;
+- int ret, id, i;
++ int id, i;
+ u32 devid;
+
+- ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+- if (ret != 4) {
+- ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+- if (ret != 5) {
+- pr_err("Invalid command line: ivrs_ioapic%s\n", str);
+- return 1;
+- }
++ if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++ sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++ goto found;
++
++ if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++ sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++ pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
++ str, id, seg, bus, dev, fn);
++ goto found;
+ }
+
++ pr_err("Invalid command line: ivrs_ioapic%s\n", str);
++ return 1;
++
++found:
+ if (early_ioapic_map_size == EARLY_MAP_SIZE) {
+ pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
+ str);
+@@ -3417,18 +3423,24 @@ static int __init parse_ivrs_ioapic(char *str)
+ static int __init parse_ivrs_hpet(char *str)
+ {
+ u32 seg = 0, bus, dev, fn;
+- int ret, id, i;
++ int id, i;
+ u32 devid;
+
+- ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+- if (ret != 4) {
+- ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+- if (ret != 5) {
+- pr_err("Invalid command line: ivrs_hpet%s\n", str);
+- return 1;
+- }
++ if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++ sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++ goto found;
++
++ if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++ sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++ pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
++ str, id, seg, bus, dev, fn);
++ goto found;
+ }
+
++ pr_err("Invalid command line: ivrs_hpet%s\n", str);
++ return 1;
++
++found:
+ if (early_hpet_map_size == EARLY_MAP_SIZE) {
+ pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
+ str);
+@@ -3449,19 +3461,36 @@ static int __init parse_ivrs_hpet(char *str)
+ static int __init parse_ivrs_acpihid(char *str)
+ {
+ u32 seg = 0, bus, dev, fn;
+- char *hid, *uid, *p;
++ char *hid, *uid, *p, *addr;
+ char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
+- int ret, i;
+-
+- ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+- if (ret != 4) {
+- ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
+- if (ret != 5) {
+- pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
+- return 1;
++ int i;
++
++ addr = strchr(str, '@');
++ if (!addr) {
++ if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
++ sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
++ pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
++ str, acpiid, seg, bus, dev, fn);
++ goto found;
+ }
++ goto not_found;
+ }
+
++ /* We have the '@', make it the terminator to get just the acpiid */
++ *addr++ = 0;
++
++ if (sscanf(str, "=%s", acpiid) != 1)
++ goto not_found;
++
++ if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
++ sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
++ goto found;
++
++not_found:
++ pr_err("Invalid command line: ivrs_acpihid%s\n", str);
++ return 1;
++
++found:
+ p = acpiid;
+ hid = strsep(&p, ":");
+ uid = p;
+@@ -3471,6 +3500,13 @@ static int __init parse_ivrs_acpihid(char *str)
+ return 1;
+ }
+
++ /*
++ * Ignore leading zeroes after ':', so e.g., AMDI0095:00
++ * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
++ */
++ while (*uid == '0' && *(uid + 1))
++ uid++;
++
+ i = early_acpihid_map_size++;
+ memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+ memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
+index ab13b73802650..83a5975bcc729 100644
+--- a/drivers/md/dm-cache-metadata.c
++++ b/drivers/md/dm-cache-metadata.c
+@@ -551,11 +551,13 @@ static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
+ return r;
+ }
+
+-static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
++static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
++ bool destroy_bm)
+ {
+ dm_sm_destroy(cmd->metadata_sm);
+ dm_tm_destroy(cmd->tm);
+- dm_block_manager_destroy(cmd->bm);
++ if (destroy_bm)
++ dm_block_manager_destroy(cmd->bm);
+ }
+
+ typedef unsigned long (*flags_mutator)(unsigned long);
+@@ -826,7 +828,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
+ cmd2 = lookup(bdev);
+ if (cmd2) {
+ mutex_unlock(&table_lock);
+- __destroy_persistent_data_objects(cmd);
++ __destroy_persistent_data_objects(cmd, true);
+ kfree(cmd);
+ return cmd2;
+ }
+@@ -874,7 +876,7 @@ void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
+ mutex_unlock(&table_lock);
+
+ if (!cmd->fail_io)
+- __destroy_persistent_data_objects(cmd);
++ __destroy_persistent_data_objects(cmd, true);
+ kfree(cmd);
+ }
+ }
+@@ -1807,14 +1809,52 @@ int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
+
+ int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
+ {
+- int r;
++ int r = -EINVAL;
++ struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++ /* fail_io is double-checked with cmd->root_lock held below */
++ if (unlikely(cmd->fail_io))
++ return r;
++
++ /*
++ * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++ * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++ * shrinker associated with the block manager's bufio client vs cmd root_lock).
++ * - must take shrinker_rwsem without holding cmd->root_lock
++ */
++ new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++ CACHE_MAX_CONCURRENT_LOCKS);
+
+ WRITE_LOCK(cmd);
+- __destroy_persistent_data_objects(cmd);
+- r = __create_persistent_data_objects(cmd, false);
++ if (cmd->fail_io) {
++ WRITE_UNLOCK(cmd);
++ goto out;
++ }
++
++ __destroy_persistent_data_objects(cmd, false);
++ old_bm = cmd->bm;
++ if (IS_ERR(new_bm)) {
++ DMERR("could not create block manager during abort");
++ cmd->bm = NULL;
++ r = PTR_ERR(new_bm);
++ goto out_unlock;
++ }
++
++ cmd->bm = new_bm;
++ r = __open_or_format_metadata(cmd, false);
++ if (r) {
++ cmd->bm = NULL;
++ goto out_unlock;
++ }
++ new_bm = NULL;
++out_unlock:
+ if (r)
+ cmd->fail_io = true;
+ WRITE_UNLOCK(cmd);
++ dm_block_manager_destroy(old_bm);
++out:
++ if (new_bm && !IS_ERR(new_bm))
++ dm_block_manager_destroy(new_bm);
+
+ return r;
+ }
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index 54a8d5c9a44ea..5e92fac90b675 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -907,16 +907,16 @@ static void abort_transaction(struct cache *cache)
+ if (get_cache_mode(cache) >= CM_READ_ONLY)
+ return;
+
+- if (dm_cache_metadata_set_needs_check(cache->cmd)) {
+- DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
+- set_cache_mode(cache, CM_FAIL);
+- }
+-
+ DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
+ if (dm_cache_metadata_abort(cache->cmd)) {
+ DMERR("%s: failed to abort metadata transaction", dev_name);
+ set_cache_mode(cache, CM_FAIL);
+ }
++
++ if (dm_cache_metadata_set_needs_check(cache->cmd)) {
++ DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
++ set_cache_mode(cache, CM_FAIL);
++ }
+ }
+
+ static void metadata_operation_failed(struct cache *cache, const char *op, int r)
+@@ -1887,6 +1887,7 @@ static void destroy(struct cache *cache)
+ if (cache->prison)
+ dm_bio_prison_destroy_v2(cache->prison);
+
++ cancel_delayed_work_sync(&cache->waker);
+ if (cache->wq)
+ destroy_workqueue(cache->wq);
+
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index 2f1cc66d26412..29e0b85eeaf09 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -1958,6 +1958,7 @@ static void clone_dtr(struct dm_target *ti)
+
+ mempool_exit(&clone->hydration_pool);
+ dm_kcopyd_client_destroy(clone->kcopyd_client);
++ cancel_delayed_work_sync(&clone->waker);
+ destroy_workqueue(clone->wq);
+ hash_table_exit(clone);
+ dm_clone_metadata_close(clone->cmd);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index e97e9f97456d4..1388ee35571e0 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4558,6 +4558,8 @@ static void dm_integrity_dtr(struct dm_target *ti)
+ BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
+ BUG_ON(!list_empty(&ic->wait_list));
+
++ if (ic->mode == 'B')
++ cancel_delayed_work_sync(&ic->bitmap_flush_work);
+ if (ic->metadata_wq)
+ destroy_workqueue(ic->metadata_wq);
+ if (ic->wait_wq)
+diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
+index a27395c8621ff..6bcc4c4786d89 100644
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -724,6 +724,15 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
+ goto bad_cleanup_data_sm;
+ }
+
++ /*
++ * For pool metadata opening process, root setting is redundant
++ * because it will be set again in __begin_transaction(). But dm
++ * pool aborting process really needs to get last transaction's
++ * root to avoid accessing broken btree.
++ */
++ pmd->root = le64_to_cpu(disk_super->data_mapping_root);
++ pmd->details_root = le64_to_cpu(disk_super->device_details_root);
++
+ __setup_btree_details(pmd);
+ dm_bm_unlock(sblock);
+
+@@ -776,13 +785,15 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f
+ return r;
+ }
+
+-static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd)
++static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
++ bool destroy_bm)
+ {
+ dm_sm_destroy(pmd->data_sm);
+ dm_sm_destroy(pmd->metadata_sm);
+ dm_tm_destroy(pmd->nb_tm);
+ dm_tm_destroy(pmd->tm);
+- dm_block_manager_destroy(pmd->bm);
++ if (destroy_bm)
++ dm_block_manager_destroy(pmd->bm);
+ }
+
+ static int __begin_transaction(struct dm_pool_metadata *pmd)
+@@ -989,7 +1000,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
+ }
+ pmd_write_unlock(pmd);
+ if (!pmd->fail_io)
+- __destroy_persistent_data_objects(pmd);
++ __destroy_persistent_data_objects(pmd, true);
+
+ kfree(pmd);
+ return 0;
+@@ -1860,19 +1871,52 @@ static void __set_abort_with_changes_flags(struct dm_pool_metadata *pmd)
+ int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
+ {
+ int r = -EINVAL;
++ struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++ /* fail_io is double-checked with pmd->root_lock held below */
++ if (unlikely(pmd->fail_io))
++ return r;
++
++ /*
++ * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++ * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++ * shrinker associated with the block manager's bufio client vs pmd root_lock).
++ * - must take shrinker_rwsem without holding pmd->root_lock
++ */
++ new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++ THIN_MAX_CONCURRENT_LOCKS);
+
+ pmd_write_lock(pmd);
+- if (pmd->fail_io)
++ if (pmd->fail_io) {
++ pmd_write_unlock(pmd);
+ goto out;
++ }
+
+ __set_abort_with_changes_flags(pmd);
+- __destroy_persistent_data_objects(pmd);
+- r = __create_persistent_data_objects(pmd, false);
++ __destroy_persistent_data_objects(pmd, false);
++ old_bm = pmd->bm;
++ if (IS_ERR(new_bm)) {
++ DMERR("could not create block manager during abort");
++ pmd->bm = NULL;
++ r = PTR_ERR(new_bm);
++ goto out_unlock;
++ }
++
++ pmd->bm = new_bm;
++ r = __open_or_format_metadata(pmd, false);
++ if (r) {
++ pmd->bm = NULL;
++ goto out_unlock;
++ }
++ new_bm = NULL;
++out_unlock:
+ if (r)
+ pmd->fail_io = true;
+-
+-out:
+ pmd_write_unlock(pmd);
++ dm_block_manager_destroy(old_bm);
++out:
++ if (new_bm && !IS_ERR(new_bm))
++ dm_block_manager_destroy(new_bm);
+
+ return r;
+ }
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index e76c96c760a9b..196f82559ad6b 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2889,6 +2889,8 @@ static void __pool_destroy(struct pool *pool)
+ dm_bio_prison_destroy(pool->prison);
+ dm_kcopyd_client_destroy(pool->copier);
+
++ cancel_delayed_work_sync(&pool->waker);
++ cancel_delayed_work_sync(&pool->no_space_timeout);
+ if (pool->wq)
+ destroy_workqueue(pool->wq);
+
+@@ -3540,20 +3542,28 @@ static int pool_preresume(struct dm_target *ti)
+ */
+ r = bind_control_target(pool, ti);
+ if (r)
+- return r;
++ goto out;
+
+ r = maybe_resize_data_dev(ti, &need_commit1);
+ if (r)
+- return r;
++ goto out;
+
+ r = maybe_resize_metadata_dev(ti, &need_commit2);
+ if (r)
+- return r;
++ goto out;
+
+ if (need_commit1 || need_commit2)
+ (void) commit(pool);
++out:
++ /*
++ * When a thin-pool is PM_FAIL, it cannot be rebuilt if
++ * bio is in deferred list. Therefore need to return 0
++ * to allow pool_resume() to flush IO.
++ */
++ if (r && get_pool_mode(pool) == PM_FAIL)
++ r = 0;
+
+- return 0;
++ return r;
+ }
+
+ static void pool_suspend_active_thins(struct pool *pool)
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 63ece30114e53..e7cc6ba1b657f 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -486,7 +486,7 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ sb = kmap_atomic(bitmap->storage.sb_page);
+ pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
+ pr_debug(" magic: %08x\n", le32_to_cpu(sb->magic));
+- pr_debug(" version: %d\n", le32_to_cpu(sb->version));
++ pr_debug(" version: %u\n", le32_to_cpu(sb->version));
+ pr_debug(" uuid: %08x.%08x.%08x.%08x\n",
+ le32_to_cpu(*(__le32 *)(sb->uuid+0)),
+ le32_to_cpu(*(__le32 *)(sb->uuid+4)),
+@@ -497,11 +497,11 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ pr_debug("events cleared: %llu\n",
+ (unsigned long long) le64_to_cpu(sb->events_cleared));
+ pr_debug(" state: %08x\n", le32_to_cpu(sb->state));
+- pr_debug(" chunksize: %d B\n", le32_to_cpu(sb->chunksize));
+- pr_debug(" daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
++ pr_debug(" chunksize: %u B\n", le32_to_cpu(sb->chunksize));
++ pr_debug(" daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep));
+ pr_debug(" sync size: %llu KB\n",
+ (unsigned long long)le64_to_cpu(sb->sync_size)/2);
+- pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
++ pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
+ kunmap_atomic(sb);
+ }
+
+@@ -2105,7 +2105,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bytes = DIV_ROUND_UP(chunks, 8);
+ if (!bitmap->mddev->bitmap_info.external)
+ bytes += sizeof(bitmap_super_t);
+- } while (bytes > (space << 9));
++ } while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) <
++ (BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1));
+ } else
+ chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
+
+@@ -2150,7 +2151,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bitmap->counts.missing_pages = pages;
+ bitmap->counts.chunkshift = chunkshift;
+ bitmap->counts.chunks = chunks;
+- bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
++ bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift +
+ BITMAP_BLOCK_SHIFT);
+
+ blocks = min(old_counts.chunks << old_counts.chunkshift,
+@@ -2176,8 +2177,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ bitmap->counts.missing_pages = old_counts.pages;
+ bitmap->counts.chunkshift = old_counts.chunkshift;
+ bitmap->counts.chunks = old_counts.chunks;
+- bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
+- BITMAP_BLOCK_SHIFT);
++ bitmap->mddev->bitmap_info.chunksize =
++ 1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT);
+ blocks = old_counts.chunks << old_counts.chunkshift;
+ pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n");
+ break;
+@@ -2537,6 +2538,9 @@ chunksize_store(struct mddev *mddev, const char *buf, size_t len)
+ if (csize < 512 ||
+ !is_power_of_2(csize))
+ return -EINVAL;
++ if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE *
++ sizeof(((bitmap_super_t *)0)->chunksize))))
++ return -EOVERFLOW;
+ mddev->bitmap_info.chunksize = csize;
+ return len;
+ }
+diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
+index f6ee678107d37..9ce5f010de3f8 100644
+--- a/drivers/media/dvb-core/dmxdev.c
++++ b/drivers/media/dvb-core/dmxdev.c
+@@ -790,6 +790,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
+ if (mutex_lock_interruptible(&dmxdev->mutex))
+ return -ERESTARTSYS;
+
++ if (dmxdev->exit) {
++ mutex_unlock(&dmxdev->mutex);
++ return -ENODEV;
++ }
++
+ for (i = 0; i < dmxdev->filternum; i++)
+ if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
+ break;
+@@ -1448,7 +1453,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
+
+ void dvb_dmxdev_release(struct dmxdev *dmxdev)
+ {
++ mutex_lock(&dmxdev->mutex);
+ dmxdev->exit = 1;
++ mutex_unlock(&dmxdev->mutex);
++
+ if (dmxdev->dvbdev->users > 1) {
+ wait_event(dmxdev->dvbdev->wait_queue,
+ dmxdev->dvbdev->users == 1);
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 9934728734af9..a31d52cb6d62c 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -335,6 +335,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
+ GFP_KERNEL);
+ if (!dvbdev->pads) {
+ kfree(dvbdev->entity);
++ dvbdev->entity = NULL;
+ return -ENOMEM;
+ }
+ }
+diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
+index 3d54a0ec86afd..3ae1f3a2f1420 100644
+--- a/drivers/media/dvb-frontends/stv0288.c
++++ b/drivers/media/dvb-frontends/stv0288.c
+@@ -440,9 +440,8 @@ static int stv0288_set_frontend(struct dvb_frontend *fe)
+ struct stv0288_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+- char tm;
+- unsigned char tda[3];
+- u8 reg, time_out = 0;
++ u8 tda[3], reg, time_out = 0;
++ s8 tm;
+
+ dprintk("%s : FE_SET_FRONTEND\n", __func__);
+
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+index 72d70984e99a6..6d3c92045c05f 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+@@ -468,8 +468,10 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+ /* Wait until instance is returned or timeout occurred */
+ if (s5p_mfc_wait_for_done_ctx(ctx,
+- S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
++ S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){
++ clear_work_bit_irqsave(ctx);
+ mfc_err("Err returning instance\n");
++ }
+
+ /* Free resources */
+ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+index b65e506665af7..f62703cebb77c 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+@@ -1218,6 +1218,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ unsigned long mb_y_addr, mb_c_addr;
+ int slice_type;
+ unsigned int strm_size;
++ bool src_ready;
+
+ slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
+ strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
+@@ -1257,7 +1258,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ }
+ }
+ }
+- if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
++ if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||
++ ctx->state == MFCINST_FINISHING)) {
+ mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
+ list);
+ if (mb_entry->flags & MFC_BUF_FLAG_USED) {
+@@ -1288,7 +1290,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
+ vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+- if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
++
++ src_ready = true;
++ if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)
++ src_ready = false;
++ if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)
++ src_ready = false;
++ if (!src_ready || ctx->dst_queue_cnt == 0)
+ clear_work_bit(ctx);
+
+ return 0;
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+index 8227004f67469..c0df5ac9fcff2 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+@@ -1060,7 +1060,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* aspect ratio VUI */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 5);
+ reg |= ((p_h264->vui_sar & 0x1) << 5);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1083,7 +1083,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+
+ /* intra picture period for H.264 open GOP */
+ /* control */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 4);
+ reg |= ((p_h264->open_gop & 0x1) << 4);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1097,23 +1097,23 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* 'WEIGHTED_BI_PREDICTION' for B is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x3 << 9);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 14);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* ASO */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 6);
+ reg |= ((p_h264->aso & 0x1) << 6);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* hier qp enable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 8);
+ reg |= ((p_h264->open_gop & 0x1) << 8);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1134,7 +1134,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ writel(reg, mfc_regs->e_h264_num_t_layer);
+
+ /* frame packing SEI generation */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 25);
+ reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
+ writel(reg, mfc_regs->e_h264_options);
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 51cb8cfce3236..d83800803cf1e 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -228,13 +228,15 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
+ div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
+ sdhci_enable_clk(host, div);
+
+- /* enable auto gate sdhc_enable_auto_gate */
+- val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
+- mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
+- SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
+- if (mask != (val & mask)) {
+- val |= mask;
+- sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++ /* Enable CLK_AUTO when the clock is greater than 400K. */
++ if (clk > 400000) {
++ val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
++ mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
++ SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
++ if (mask != (val & mask)) {
++ val |= mask;
++ sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++ }
+ }
+ }
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 0cf1a1797ea32..2e0655c0b606f 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1184,6 +1184,8 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
+ continue;
+
+ erase = &map->erase_type[i];
++ if (!erase->size)
++ continue;
+
+ /* Alignment is not mandatory for overlaid regions */
+ if (region->offset & SNOR_OVERLAID_REGION &&
+diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
+index 119b38e6fc2a3..d57ddaf1525b3 100644
+--- a/drivers/mtd/spi-nor/gigadevice.c
++++ b/drivers/mtd/spi-nor/gigadevice.c
+@@ -8,19 +8,29 @@
+
+ #include "core.h"
+
+-static void gd25q256_default_init(struct spi_nor *nor)
++static int
++gd25q256_post_bfpt(struct spi_nor *nor,
++ const struct sfdp_parameter_header *bfpt_header,
++ const struct sfdp_bfpt *bfpt)
+ {
+ /*
+- * Some manufacturer like GigaDevice may use different
+- * bit to set QE on different memories, so the MFR can't
+- * indicate the quad_enable method for this case, we need
+- * to set it in the default_init fixup hook.
++ * GD25Q256C supports the first version of JESD216 which does not define
++ * the Quad Enable methods. Overwrite the default Quad Enable method.
++ *
++ * GD25Q256 GENERATION | SFDP MAJOR VERSION | SFDP MINOR VERSION
++ * GD25Q256C | SFDP_JESD216_MAJOR | SFDP_JESD216_MINOR
++ * GD25Q256D | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR
++ * GD25Q256E | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR
+ */
+- nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
++ if (bfpt_header->major == SFDP_JESD216_MAJOR &&
++ bfpt_header->minor == SFDP_JESD216_MINOR)
++ nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
++
++ return 0;
+ }
+
+ static const struct spi_nor_fixups gd25q256_fixups = {
+- .default_init = gd25q256_default_init,
++ .post_bfpt = gd25q256_post_bfpt,
+ };
+
+ static const struct flash_info gigadevice_nor_parts[] = {
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 77d4f3eab9715..d52e598fd652b 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -2896,12 +2896,12 @@ static int ravb_remove(struct platform_device *pdev)
+ priv->desc_bat_dma);
+ /* Set reset mode */
+ ravb_write(ndev, CCC_OPC_RESET, CCC);
+- pm_runtime_put_sync(&pdev->dev);
+ unregister_netdev(ndev);
+ if (info->nc_queues)
+ netif_napi_del(&priv->napi[RAVB_NC]);
+ netif_napi_del(&priv->napi[RAVB_BE]);
+ ravb_mdio_release(priv);
++ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ reset_control_assert(priv->rstc);
+ free_netdev(ndev);
+diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
+index 7390f94cd4ca2..a05bda7b9a3ba 100644
+--- a/drivers/net/wireless/microchip/wilc1000/sdio.c
++++ b/drivers/net/wireless/microchip/wilc1000/sdio.c
+@@ -20,6 +20,7 @@ static const struct sdio_device_id wilc_sdio_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
+ { },
+ };
++MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
+
+ #define WILC_SDIO_BLOCK_SIZE 512
+
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index e6c01db393f95..f26d2ba8a3715 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -281,7 +281,7 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ const char *cmdline, size_t extra_fdt_size)
+ {
+ void *fdt;
+- int ret, chosen_node;
++ int ret, chosen_node, len;
+ const void *prop;
+ size_t fdt_size;
+
+@@ -324,19 +324,19 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ goto out;
+
+ /* Did we boot using an initrd? */
+- prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
++ prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", &len);
+ if (prop) {
+ u64 tmp_start, tmp_end, tmp_size;
+
+- tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
++ tmp_start = of_read_number(prop, len / 4);
+
+- prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
++ prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", &len);
+ if (!prop) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+- tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
++ tmp_end = of_read_number(prop, len / 4);
+
+ /*
+ * kexec reserves exact initrd size, while firmware may
+diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
+index d4be9d2ee74d9..8bdc5e043831c 100644
+--- a/drivers/parisc/led.c
++++ b/drivers/parisc/led.c
+@@ -137,6 +137,9 @@ static int start_task(void)
+
+ /* Create the work queue and queue the LED task */
+ led_wq = create_singlethread_workqueue("led_wq");
++ if (!led_wq)
++ return -ENOMEM;
++
+ queue_delayed_work(led_wq, &led_task, 0);
+
+ return 0;
+diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c
+index e402f05068a53..66d9ab2886468 100644
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -29,6 +29,9 @@
+ #define PCI_DOE_FLAG_CANCEL 0
+ #define PCI_DOE_FLAG_DEAD 1
+
++/* Max data object length is 2^18 dwords */
++#define PCI_DOE_MAX_LENGTH (1 << 18)
++
+ /**
+ * struct pci_doe_mb - State for a single DOE mailbox
+ *
+@@ -107,6 +110,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
+ {
+ struct pci_dev *pdev = doe_mb->pdev;
+ int offset = doe_mb->cap_offset;
++ size_t length;
+ u32 val;
+ int i;
+
+@@ -123,15 +127,20 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
+ if (FIELD_GET(PCI_DOE_STATUS_ERROR, val))
+ return -EIO;
+
++ /* Length is 2 DW of header + length of payload in DW */
++ length = 2 + task->request_pl_sz / sizeof(u32);
++ if (length > PCI_DOE_MAX_LENGTH)
++ return -EIO;
++ if (length == PCI_DOE_MAX_LENGTH)
++ length = 0;
++
+ /* Write DOE Header */
+ val = FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_VID, task->prot.vid) |
+ FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_TYPE, task->prot.type);
+ pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, val);
+- /* Length is 2 DW of header + length of payload in DW */
+ pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+ FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH,
+- 2 + task->request_pl_sz /
+- sizeof(u32)));
++ length));
+ for (i = 0; i < task->request_pl_sz / sizeof(u32); i++)
+ pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+ task->request_pl[i]);
+@@ -178,7 +187,10 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
+ pci_write_config_dword(pdev, offset + PCI_DOE_READ, 0);
+
+ length = FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, val);
+- if (length > SZ_1M || length < 2)
++ /* A value of 0x0 indicates max data object length */
++ if (!length)
++ length = PCI_DOE_MAX_LENGTH;
++ if (length < 2)
+ return -EIO;
+
+ /* First 2 dwords have already been read */
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+index fc804e08e3cb5..6dd4050c9f2ed 100644
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -1174,11 +1174,9 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+
+ sysfs_bin_attr_init(res_attr);
+ if (write_combine) {
+- pdev->res_attr_wc[num] = res_attr;
+ sprintf(res_attr_name, "resource%d_wc", num);
+ res_attr->mmap = pci_mmap_resource_wc;
+ } else {
+- pdev->res_attr[num] = res_attr;
+ sprintf(res_attr_name, "resource%d", num);
+ if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+ res_attr->read = pci_read_resource_io;
+@@ -1196,10 +1194,17 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+ res_attr->size = pci_resource_len(pdev, num);
+ res_attr->private = (void *)(unsigned long)num;
+ retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+- if (retval)
++ if (retval) {
+ kfree(res_attr);
++ return retval;
++ }
++
++ if (write_combine)
++ pdev->res_attr_wc[num] = res_attr;
++ else
++ pdev->res_attr[num] = res_attr;
+
+- return retval;
++ return 0;
+ }
+
+ /**
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 95bc329e74c0e..a484da1a9c66d 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6462,6 +6462,8 @@ bool pci_device_is_present(struct pci_dev *pdev)
+ {
+ u32 v;
+
++ /* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
++ pdev = pci_physfn(pdev);
+ if (pci_dev_is_disconnected(pdev))
+ return false;
+ return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 3e730c05ac3fb..0feda8eb93b52 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -959,8 +959,8 @@ static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
+
+ .clk_list = qmp_v3_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
+- .reset_list = sc7180_usb3phy_reset_l,
+- .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l),
++ .reset_list = msm8996_usb3phy_reset_l,
++ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v3_usb3phy_regs_layout,
+@@ -1032,8 +1032,8 @@ static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
+ .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+
+- .clk_list = qmp_v4_phy_clk_l,
+- .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
++ .clk_list = qmp_v4_sm8250_usbphy_clk_l,
++ .num_clks = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
+index ca0817f8e41e9..24ce0c0ee8463 100644
+--- a/drivers/remoteproc/imx_dsp_rproc.c
++++ b/drivers/remoteproc/imx_dsp_rproc.c
+@@ -347,9 +347,6 @@ static int imx_dsp_rproc_stop(struct rproc *rproc)
+ struct device *dev = rproc->dev.parent;
+ int ret = 0;
+
+- /* Make sure work is finished */
+- flush_work(&priv->rproc_work);
+-
+ if (rproc->state == RPROC_CRASHED) {
+ priv->flags &= ~REMOTE_IS_READY;
+ return 0;
+@@ -432,9 +429,18 @@ static void imx_dsp_rproc_vq_work(struct work_struct *work)
+ {
+ struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
+ rproc_work);
++ struct rproc *rproc = priv->rproc;
++
++ mutex_lock(&rproc->lock);
++
++ if (rproc->state != RPROC_RUNNING)
++ goto unlock_mutex;
+
+ rproc_vq_interrupt(priv->rproc, 0);
+ rproc_vq_interrupt(priv->rproc, 1);
++
++unlock_mutex:
++ mutex_unlock(&rproc->lock);
+ }
+
+ /**
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index 38383e7de3c1e..80592ccd10199 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -113,8 +113,8 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
+ { 0x80000000, 0x80000000, 0x10000000, 0 },
+ { 0x90000000, 0x80000000, 0x10000000, 0 },
+
+- { 0xC0000000, 0xa0000000, 0x10000000, 0 },
+- { 0xD0000000, 0xa0000000, 0x10000000, 0 },
++ { 0xC0000000, 0xC0000000, 0x10000000, 0 },
++ { 0xD0000000, 0xC0000000, 0x10000000, 0 },
+ };
+
+ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 4fc5ce2187ac8..3f5458372b783 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -1954,12 +1954,18 @@ static void rproc_crash_handler_work(struct work_struct *work)
+
+ mutex_lock(&rproc->lock);
+
+- if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
++ if (rproc->state == RPROC_CRASHED) {
+ /* handle only the first crash detected */
+ mutex_unlock(&rproc->lock);
+ return;
+ }
+
++ if (rproc->state == RPROC_OFFLINE) {
++ /* Don't recover if the remote processor was stopped */
++ mutex_unlock(&rproc->lock);
++ goto out;
++ }
++
+ rproc->state = RPROC_CRASHED;
+ dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
+ rproc->name);
+@@ -1969,6 +1975,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
+ if (!rproc->recovery_disabled)
+ rproc_trigger_recovery(rproc);
+
++out:
+ pm_relax(rproc->dev.parent);
+ }
+
+diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
+index 157bf5209ac40..a40c1a52df659 100644
+--- a/drivers/rtc/rtc-ds1347.c
++++ b/drivers/rtc/rtc-ds1347.c
+@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
+ return err;
+
+ century = (dt->tm_year / 100) + 19;
+- err = regmap_write(map, DS1347_CENTURY_REG, century);
++ err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
+ if (err)
+ return err;
+
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index e0d7a54595627..795a80a4faa8c 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -63,6 +63,7 @@ config QCOM_GSBI
+ config QCOM_LLCC
+ tristate "Qualcomm Technologies, Inc. LLCC driver"
+ depends on ARCH_QCOM || COMPILE_TEST
++ select REGMAP_MMIO
+ help
+ Qualcomm Technologies, Inc. platform specific
+ Last Level Cache Controller(LLCC) driver for platforms such as,
+@@ -236,6 +237,7 @@ config QCOM_ICC_BWMON
+ tristate "QCOM Interconnect Bandwidth Monitor driver"
+ depends on ARCH_QCOM || COMPILE_TEST
+ select PM_OPP
++ select REGMAP_MMIO
+ help
+ Sets up driver monitoring bandwidth on various interconnects and
+ based on that voting for interconnect bandwidth, adjusting their
+diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c
+index a9472e0e5d61c..27d6e25a01153 100644
+--- a/drivers/soc/ux500/ux500-soc-id.c
++++ b/drivers/soc/ux500/ux500-soc-id.c
+@@ -167,20 +167,18 @@ ATTRIBUTE_GROUPS(ux500_soc);
+ static const char *db8500_read_soc_id(struct device_node *backupram)
+ {
+ void __iomem *base;
+- void __iomem *uid;
+ const char *retstr;
++ u32 uid[5];
+
+ base = of_iomap(backupram, 0);
+ if (!base)
+ return NULL;
+- uid = base + 0x1fc0;
++ memcpy_fromio(uid, base + 0x1fc0, sizeof(uid));
+
+ /* Throw these device-specific numbers into the entropy pool */
+- add_device_randomness(uid, 0x14);
++ add_device_randomness(uid, sizeof(uid));
+ retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+- readl((u32 *)uid+0),
+- readl((u32 *)uid+1), readl((u32 *)uid+2),
+- readl((u32 *)uid+3), readl((u32 *)uid+4));
++ uid[0], uid[1], uid[2], uid[3], uid[4]);
+ iounmap(base);
+ return retstr;
+ }
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index 2234bb8d48b34..490ba0eb249b3 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
+ return 0;
+ }
+
++static struct v4l2_rect *
++imgu_subdev_get_crop(struct imgu_v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state, unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&sd->subdev, sd_state, pad);
++ else
++ return &sd->rect.eff;
++}
++
++static struct v4l2_rect *
++imgu_subdev_get_compose(struct imgu_v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state, unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&sd->subdev, sd_state, pad);
++ else
++ return &sd->rect.bds;
++}
++
+ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
+- sel->pad);
+- else
+- sel->r = imgu_sd->rect.eff;
++ sel->r = *imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ return 0;
+ case V4L2_SEL_TGT_COMPOSE:
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
+- sel->pad);
+- else
+- sel->r = imgu_sd->rect.bds;
++ sel->r = *imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ return 0;
+ default:
+ return -EINVAL;
+@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_selection *sel)
+ {
+ struct imgu_device *imgu = v4l2_get_subdevdata(sd);
+- struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
+- struct imgu_v4l2_subdev,
+- subdev);
+- struct v4l2_rect *rect, *try_sel;
++ struct imgu_v4l2_subdev *imgu_sd =
++ container_of(sd, struct imgu_v4l2_subdev, subdev);
++ struct v4l2_rect *rect;
+
+ dev_dbg(&imgu->pci_dev->dev,
+ "set subdev %u sel which %u target 0x%4x rect [%ux%u]",
+@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
+- rect = &imgu_sd->rect.eff;
++ rect = imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ break;
+ case V4L2_SEL_TGT_COMPOSE:
+- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
+- rect = &imgu_sd->rect.bds;
++ rect = imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++ sel->which);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+- if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+- *try_sel = sel->r;
+- else
+- *rect = sel->r;
+-
++ *rect = sel->r;
+ return 0;
+ }
+
+diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c
+index b26e44adb2be7..426e653bd55d5 100644
+--- a/drivers/staging/media/tegra-video/csi.c
++++ b/drivers/staging/media/tegra-video/csi.c
+@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ for (i = 0; i < chan->numgangports; i++)
+ chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
+
+- chan->of_node = node;
++ chan->of_node = of_node_get(node);
+ chan->numpads = num_pads;
+ if (num_pads & 0x2) {
+ chan->pads[0].flags = MEDIA_PAD_FL_SINK;
+@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ chan->mipi = tegra_mipi_request(csi->dev, node);
+ if (IS_ERR(chan->mipi)) {
+ ret = PTR_ERR(chan->mipi);
++ chan->mipi = NULL;
+ dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
+ }
+
+@@ -640,6 +641,7 @@ static void tegra_csi_channels_cleanup(struct tegra_csi *csi)
+ media_entity_cleanup(&subdev->entity);
+ }
+
++ of_node_put(chan->of_node);
+ list_del(&chan->list);
+ kfree(chan);
+ }
+diff --git a/drivers/staging/media/tegra-video/csi.h b/drivers/staging/media/tegra-video/csi.h
+index 4ee05a1785cfa..6960ea2e3d360 100644
+--- a/drivers/staging/media/tegra-video/csi.h
++++ b/drivers/staging/media/tegra-video/csi.h
+@@ -56,7 +56,7 @@ struct tegra_csi;
+ * @framerate: active framerate for TPG
+ * @h_blank: horizontal blanking for TPG active format
+ * @v_blank: vertical blanking for TPG active format
+- * @mipi: mipi device for corresponding csi channel pads
++ * @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
+ * @pixel_rate: active pixel rate from the sensor on this channel
+ */
+ struct tegra_csi_channel {
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index 21c478df6aef4..ed53c0208f407 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -433,6 +433,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ u64 wanted_disk_byte = ref->wanted_disk_byte;
+ u64 count = 0;
+ u64 data_offset;
++ u8 type;
+
+ if (level != 0) {
+ eb = path->nodes[level];
+@@ -487,6 +488,9 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ continue;
+ }
+ fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
++ type = btrfs_file_extent_type(eb, fi);
++ if (type == BTRFS_FILE_EXTENT_INLINE)
++ goto next;
+ disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+ data_offset = btrfs_file_extent_offset(eb, fi);
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 7aa220742c61d..6f006430115a3 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7128,8 +7128,9 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ map->stripes[i].dev = handle_missing_device(fs_info,
+ devid, uuid);
+ if (IS_ERR(map->stripes[i].dev)) {
++ ret = PTR_ERR(map->stripes[i].dev);
+ free_extent_map(em);
+- return PTR_ERR(map->stripes[i].dev);
++ return ret;
+ }
+ }
+
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 712a431614480..6094cb2ff099b 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -678,9 +678,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
+ seq_printf(s, ",echo_interval=%lu",
+ tcon->ses->server->echo_interval / HZ);
+
+- /* Only display max_credits if it was overridden on mount */
++ /* Only display the following if overridden on mount */
+ if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
+ seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
++ if (tcon->ses->server->tcp_nodelay)
++ seq_puts(s, ",tcpnodelay");
++ if (tcon->ses->server->noautotune)
++ seq_puts(s, ",noautotune");
++ if (tcon->ses->server->noblocksnd)
++ seq_puts(s, ",noblocksend");
+
+ if (tcon->snapshot_time)
+ seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 816161f51b29d..4e4810339d763 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -279,8 +279,10 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
+ tcon->need_reconnect = true;
+ tcon->status = TID_NEED_RECON;
+ }
+- if (ses->tcon_ipc)
++ if (ses->tcon_ipc) {
+ ses->tcon_ipc->need_reconnect = true;
++ ses->tcon_ipc->status = TID_NEED_RECON;
++ }
+
+ next_session:
+ spin_unlock(&ses->chan_lock);
+@@ -1870,6 +1872,9 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+
+ cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n", rc, tcon->tid);
+
++ spin_lock(&tcon->tc_lock);
++ tcon->status = TID_GOOD;
++ spin_unlock(&tcon->tc_lock);
+ ses->tcon_ipc = tcon;
+ out:
+ return rc;
+@@ -2155,7 +2160,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)),
+ struct cifs_ses *
+ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+- int rc = -ENOMEM;
++ int rc = 0;
+ unsigned int xid;
+ struct cifs_ses *ses;
+ struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
+@@ -2204,6 +2209,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ return ses;
+ }
+
++ rc = -ENOMEM;
++
+ cifs_dbg(FYI, "Existing smb sess not found\n");
+ ses = sesInfoAlloc();
+ if (ses == NULL)
+@@ -2276,10 +2283,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ list_add(&ses->smb_ses_list, &server->smb_ses_list);
+ spin_unlock(&cifs_tcp_ses_lock);
+
+- free_xid(xid);
+-
+ cifs_setup_ipc(ses, ctx);
+
++ free_xid(xid);
++
+ return ses;
+
+ get_ses_fail:
+@@ -2598,6 +2605,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ tcon->nodelete = ctx->nodelete;
+ tcon->local_lease = ctx->local_lease;
+ INIT_LIST_HEAD(&tcon->pending_opens);
++ tcon->status = TID_GOOD;
+
+ /* schedule query interfaces poll */
+ INIT_DELAYED_WORK(&tcon->query_interfaces,
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index aa0245268d40e..6a12279671978 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -3481,7 +3481,7 @@ smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
+ if (rc)
+ return rc;
+
+- memcpy(data, begin_of_buf, buffer_length);
++ memcpy(data, begin_of_buf, minbufsize);
+
+ return 0;
+ }
+@@ -3605,7 +3605,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
+
+ rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
+ le32_to_cpu(rsp->OutputBufferLength),
+- &rsp_iov, min_len, *data);
++ &rsp_iov, dlen ? *dlen : min_len, *data);
+ if (rc && allocated) {
+ kfree(*data);
+ *data = NULL;
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 59f64c596233b..871d4e9f49fb6 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1543,7 +1543,11 @@ static void process_recv_sockets(struct work_struct *work)
+
+ static void process_listen_recv_socket(struct work_struct *work)
+ {
+- accept_from_sock(&listen_con);
++ int ret;
++
++ do {
++ ret = accept_from_sock(&listen_con);
++ } while (!ret);
+ }
+
+ static void dlm_connect(struct connection *con)
+@@ -1820,7 +1824,7 @@ static int dlm_listen_for_all(void)
+ result = sock->ops->listen(sock, 5);
+ if (result < 0) {
+ dlm_close_sock(&listen_con.sock);
+- goto out;
++ return result;
+ }
+
+ return 0;
+@@ -2023,7 +2027,6 @@ fail_listen:
+ dlm_proto_ops = NULL;
+ fail_proto_ops:
+ dlm_allow_conn = 0;
+- dlm_close_sock(&listen_con.sock);
+ work_stop();
+ fail_local:
+ deinit_local();
+diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
+index 8f597753ac129..5202eddfc3c0a 100644
+--- a/fs/ext2/dir.c
++++ b/fs/ext2/dir.c
+@@ -679,7 +679,7 @@ int ext2_empty_dir (struct inode * inode)
+ page = ext2_get_page(inode, i, 0, &page_addr);
+
+ if (IS_ERR(page))
+- goto not_empty;
++ return 0;
+
+ kaddr = page_addr;
+ de = (ext2_dirent *)kaddr;
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 3bf9a6926798f..c3c52826212e7 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -558,7 +558,7 @@ enum {
+ *
+ * It's not paranoia if the Murphy's Law really *is* out to get you. :-)
+ */
+-#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG))
++#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1U << EXT4_INODE_##FLAG))
+ #define CHECK_FLAG_VALUE(FLAG) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))
+
+ static inline void ext4_check_flag_values(void)
+@@ -2964,7 +2964,8 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
+ typedef enum {
+ EXT4_IGET_NORMAL = 0,
+ EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */
+- EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */
++ EXT4_IGET_HANDLE = 0x0002, /* Inode # is from a handle */
++ EXT4_IGET_BAD = 0x0004 /* Allow to iget a bad inode */
+ } ext4_iget_flags;
+
+ extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+@@ -3621,8 +3622,8 @@ extern void ext4_initialize_dirent_tail(struct buffer_head *bh,
+ unsigned int blocksize);
+ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh);
+-extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+- struct inode *inode);
++extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++ struct inode *inode, struct dentry *dentry);
+ extern int __ext4_link(struct inode *dir, struct inode *inode,
+ struct dentry *dentry);
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 8378b86c1b496..eee73abc21f65 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5803,6 +5803,14 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
+ struct ext4_extent *extent;
+ ext4_lblk_t first_lblk, first_lclu, last_lclu;
+
++ /*
++ * if data can be stored inline, the logical cluster isn't
++ * mapped - no physical clusters have been allocated, and the
++ * file has no extents
++ */
++ if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++ return 0;
++
+ /* search for the extent closest to the first block in the cluster */
+ path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
+ if (IS_ERR(path)) {
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index 23167efda95ee..9c2459ddedb45 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -1372,7 +1372,7 @@ retry:
+ if (count_reserved)
+ count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
+ &orig_es, &rc);
+- goto out;
++ goto out_get_reserved;
+ }
+
+ if (len1 > 0) {
+@@ -1414,6 +1414,7 @@ retry:
+ }
+ }
+
++out_get_reserved:
+ if (count_reserved)
+ *reserved = get_rsvd(inode, end, es, &rc);
+ out:
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index e5d20da585287..8ceedc14928af 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -418,25 +418,34 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
+ struct __track_dentry_update_args *dentry_update =
+ (struct __track_dentry_update_args *)arg;
+ struct dentry *dentry = dentry_update->dentry;
+- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++ struct inode *dir = dentry->d_parent->d_inode;
++ struct super_block *sb = inode->i_sb;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ mutex_unlock(&ei->i_fc_lock);
++
++ if (IS_ENCRYPTED(dir)) {
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME,
++ NULL);
++ mutex_lock(&ei->i_fc_lock);
++ return -EOPNOTSUPP;
++ }
++
+ node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
+ if (!node) {
+- ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ mutex_lock(&ei->i_fc_lock);
+ return -ENOMEM;
+ }
+
+ node->fcd_op = dentry_update->op;
+- node->fcd_parent = dentry->d_parent->d_inode->i_ino;
++ node->fcd_parent = dir->i_ino;
+ node->fcd_ino = inode->i_ino;
+ if (dentry->d_name.len > DNAME_INLINE_LEN) {
+ node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
+ if (!node->fcd_name.name) {
+ kmem_cache_free(ext4_fc_dentry_cachep, node);
+- ext4_fc_mark_ineligible(inode->i_sb,
+- EXT4_FC_REASON_NOMEM, NULL);
++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ mutex_lock(&ei->i_fc_lock);
+ return -ENOMEM;
+ }
+@@ -674,6 +683,15 @@ static void ext4_fc_submit_bh(struct super_block *sb, bool is_tail)
+
+ /* Ext4 commit path routines */
+
++/* memcpy to fc reserved space and update CRC */
++static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
++ int len, u32 *crc)
++{
++ if (crc)
++ *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
++ return memcpy(dst, src, len);
++}
++
+ /* memzero and update CRC */
+ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+ u32 *crc)
+@@ -699,62 +717,59 @@ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+ */
+ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ {
+- struct ext4_fc_tl *tl;
++ struct ext4_fc_tl tl;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct buffer_head *bh;
+ int bsize = sbi->s_journal->j_blocksize;
+ int ret, off = sbi->s_fc_bytes % bsize;
+- int pad_len;
++ int remaining;
++ u8 *dst;
+
+ /*
+- * After allocating len, we should have space at least for a 0 byte
+- * padding.
++ * If 'len' is too long to fit in any block alongside a PAD tlv, then we
++ * cannot fulfill the request.
+ */
+- if (len + EXT4_FC_TAG_BASE_LEN > bsize)
++ if (len > bsize - EXT4_FC_TAG_BASE_LEN)
+ return NULL;
+
+- if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) {
+- /*
+- * Only allocate from current buffer if we have enough space for
+- * this request AND we have space to add a zero byte padding.
+- */
+- if (!sbi->s_fc_bh) {
+- ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+- if (ret)
+- return NULL;
+- sbi->s_fc_bh = bh;
+- }
++ if (!sbi->s_fc_bh) {
++ ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
++ if (ret)
++ return NULL;
++ sbi->s_fc_bh = bh;
++ }
++ dst = sbi->s_fc_bh->b_data + off;
++
++ /*
++ * Allocate the bytes in the current block if we can do so while still
++ * leaving enough space for a PAD tlv.
++ */
++ remaining = bsize - EXT4_FC_TAG_BASE_LEN - off;
++ if (len <= remaining) {
+ sbi->s_fc_bytes += len;
+- return sbi->s_fc_bh->b_data + off;
++ return dst;
+ }
+- /* Need to add PAD tag */
+- tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off);
+- tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
+- pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN;
+- tl->fc_len = cpu_to_le16(pad_len);
+- if (crc)
+- *crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN);
+- if (pad_len > 0)
+- ext4_fc_memzero(sb, tl + 1, pad_len, crc);
++
++ /*
++ * Else, terminate the current block with a PAD tlv, then allocate a new
++ * block and allocate the bytes at the start of that new block.
++ */
++
++ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
++ tl.fc_len = cpu_to_le16(remaining);
++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++ ext4_fc_memzero(sb, dst + EXT4_FC_TAG_BASE_LEN, remaining, crc);
++
+ ext4_fc_submit_bh(sb, false);
+
+ ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+ if (ret)
+ return NULL;
+ sbi->s_fc_bh = bh;
+- sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize + 1) * bsize + len;
++ sbi->s_fc_bytes += bsize - off + len;
+ return sbi->s_fc_bh->b_data;
+ }
+
+-/* memcpy to fc reserved space and update CRC */
+-static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
+- int len, u32 *crc)
+-{
+- if (crc)
+- *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
+- return memcpy(dst, src, len);
+-}
+-
+ /*
+ * Complete a fast commit by writing tail tag.
+ *
+@@ -782,7 +797,7 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ off = sbi->s_fc_bytes % bsize;
+
+ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_TAIL);
+- tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail));
++ tl.fc_len = cpu_to_le16(bsize - off + sizeof(struct ext4_fc_tail));
+ sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize);
+
+ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc);
+@@ -792,6 +807,8 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ dst += sizeof(tail.fc_tid);
+ tail.fc_crc = cpu_to_le32(crc);
+ ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL);
++ dst += sizeof(tail.fc_crc);
++ memset(dst, 0, bsize - off); /* Don't leak uninitialized memory. */
+
+ ext4_fc_submit_bh(sb, true);
+
+@@ -1396,7 +1413,7 @@ static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
+ return 0;
+ }
+
+- ret = __ext4_unlink(NULL, old_parent, &entry, inode);
++ ret = __ext4_unlink(old_parent, &entry, inode, NULL);
+ /* -ENOENT ok coz it might not exist anymore. */
+ if (ret == -ENOENT)
+ ret = 0;
+@@ -1986,32 +2003,31 @@ void ext4_fc_replay_cleanup(struct super_block *sb)
+ kfree(sbi->s_fc_replay_state.fc_modified_inodes);
+ }
+
+-static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl,
+- u8 *val, u8 *end)
++static bool ext4_fc_value_len_isvalid(struct ext4_sb_info *sbi,
++ int tag, int len)
+ {
+- if (val + tl->fc_len > end)
+- return false;
+-
+- /* Here only check ADD_RANGE/TAIL/HEAD which will read data when do
+- * journal rescan before do CRC check. Other tags length check will
+- * rely on CRC check.
+- */
+- switch (tl->fc_tag) {
++ switch (tag) {
+ case EXT4_FC_TAG_ADD_RANGE:
+- return (sizeof(struct ext4_fc_add_range) == tl->fc_len);
+- case EXT4_FC_TAG_TAIL:
+- return (sizeof(struct ext4_fc_tail) <= tl->fc_len);
+- case EXT4_FC_TAG_HEAD:
+- return (sizeof(struct ext4_fc_head) == tl->fc_len);
++ return len == sizeof(struct ext4_fc_add_range);
+ case EXT4_FC_TAG_DEL_RANGE:
++ return len == sizeof(struct ext4_fc_del_range);
++ case EXT4_FC_TAG_CREAT:
+ case EXT4_FC_TAG_LINK:
+ case EXT4_FC_TAG_UNLINK:
+- case EXT4_FC_TAG_CREAT:
++ len -= sizeof(struct ext4_fc_dentry_info);
++ return len >= 1 && len <= EXT4_NAME_LEN;
+ case EXT4_FC_TAG_INODE:
++ len -= sizeof(struct ext4_fc_inode);
++ return len >= EXT4_GOOD_OLD_INODE_SIZE &&
++ len <= sbi->s_inode_size;
+ case EXT4_FC_TAG_PAD:
+- default:
+- return true;
++ return true; /* padding can have any length */
++ case EXT4_FC_TAG_TAIL:
++ return len >= sizeof(struct ext4_fc_tail);
++ case EXT4_FC_TAG_HEAD:
++ return len == sizeof(struct ext4_fc_head);
+ }
++ return false;
+ }
+
+ /*
+@@ -2049,7 +2065,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ state = &sbi->s_fc_replay_state;
+
+ start = (u8 *)bh->b_data;
+- end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++ end = start + journal->j_blocksize;
+
+ if (state->fc_replay_expected_off == 0) {
+ state->fc_cur_tag = 0;
+@@ -2070,11 +2086,12 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ }
+
+ state->fc_replay_expected_off++;
+- for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
+ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
+ ext4_fc_get_tl(&tl, cur);
+ val = cur + EXT4_FC_TAG_BASE_LEN;
+- if (!ext4_fc_tag_len_isvalid(&tl, val, end)) {
++ if (tl.fc_len > end - val ||
++ !ext4_fc_value_len_isvalid(sbi, tl.fc_tag, tl.fc_len)) {
+ ret = state->fc_replay_num_tags ?
+ JBD2_FC_REPLAY_STOP : -ECANCELED;
+ goto out_err;
+@@ -2187,9 +2204,9 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ #endif
+
+ start = (u8 *)bh->b_data;
+- end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++ end = start + journal->j_blocksize;
+
+- for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
+ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
+ ext4_fc_get_tl(&tl, cur);
+ val = cur + EXT4_FC_TAG_BASE_LEN;
+@@ -2258,17 +2275,17 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal)
+ journal->j_fc_cleanup_callback = ext4_fc_cleanup;
+ }
+
+-static const char *fc_ineligible_reasons[] = {
+- "Extended attributes changed",
+- "Cross rename",
+- "Journal flag changed",
+- "Insufficient memory",
+- "Swap boot",
+- "Resize",
+- "Dir renamed",
+- "Falloc range op",
+- "Data journalling",
+- "FC Commit Failed"
++static const char * const fc_ineligible_reasons[] = {
++ [EXT4_FC_REASON_XATTR] = "Extended attributes changed",
++ [EXT4_FC_REASON_CROSS_RENAME] = "Cross rename",
++ [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed",
++ [EXT4_FC_REASON_NOMEM] = "Insufficient memory",
++ [EXT4_FC_REASON_SWAP_BOOT] = "Swap boot",
++ [EXT4_FC_REASON_RESIZE] = "Resize",
++ [EXT4_FC_REASON_RENAME_DIR] = "Dir renamed",
++ [EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
++ [EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
++ [EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
+ };
+
+ int ext4_fc_info_show(struct seq_file *seq, void *v)
+diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
+index a6154c3ed1357..2fadb2c4780c8 100644
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -58,7 +58,7 @@ struct ext4_fc_dentry_info {
+ __u8 fc_dname[];
+ };
+
+-/* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */
++/* Value structure for EXT4_FC_TAG_INODE. */
+ struct ext4_fc_inode {
+ __le32 fc_ino;
+ __u8 fc_raw_inode[];
+@@ -96,6 +96,7 @@ enum {
+ EXT4_FC_REASON_RENAME_DIR,
+ EXT4_FC_REASON_FALLOC_RANGE,
+ EXT4_FC_REASON_INODE_JOURNAL_DATA,
++ EXT4_FC_REASON_ENCRYPTED_FILENAME,
+ EXT4_FC_REASON_MAX
+ };
+
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index 860fc51190098..c68bebe7ff4b6 100644
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -148,6 +148,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ struct super_block *sb = inode->i_sb;
+ Indirect *p = chain;
+ struct buffer_head *bh;
++ unsigned int key;
+ int ret = -EIO;
+
+ *err = 0;
+@@ -156,7 +157,13 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ if (!p->key)
+ goto no_block;
+ while (--depth) {
+- bh = sb_getblk(sb, le32_to_cpu(p->key));
++ key = le32_to_cpu(p->key);
++ if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) {
++ /* the block was out of range */
++ ret = -EFSCORRUPTED;
++ goto failure;
++ }
++ bh = sb_getblk(sb, key);
+ if (unlikely(!bh)) {
+ ret = -ENOMEM;
+ goto failure;
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 6da73be32bff3..8cfbcfcb67b9a 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -222,13 +222,13 @@ void ext4_evict_inode(struct inode *inode)
+
+ /*
+ * For inodes with journalled data, transaction commit could have
+- * dirtied the inode. Flush worker is ignoring it because of I_FREEING
+- * flag but we still need to remove the inode from the writeback lists.
++ * dirtied the inode. And for inodes with dioread_nolock, unwritten
++ * extents converting worker could merge extents and also have dirtied
++ * the inode. Flush worker is ignoring it because of I_FREEING flag but
++ * we still need to remove the inode from the writeback lists.
+ */
+- if (!list_empty_careful(&inode->i_io_list)) {
+- WARN_ON_ONCE(!ext4_should_journal_data(inode));
++ if (!list_empty_careful(&inode->i_io_list))
+ inode_io_list_del(inode);
+- }
+
+ /*
+ * Protect us against freezing - iput() caller didn't have to have any
+@@ -335,6 +335,12 @@ stop_handle:
+ ext4_xattr_inode_array_free(ea_inode_array);
+ return;
+ no_delete:
++ /*
++ * Check out some where else accidentally dirty the evicting inode,
++ * which may probably cause inode use-after-free issues later.
++ */
++ WARN_ON_ONCE(!list_empty_careful(&inode->i_io_list));
++
+ if (!list_empty(&EXT4_I(inode)->i_fc_list))
+ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
+ ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
+@@ -1309,7 +1315,8 @@ static int ext4_write_end(struct file *file,
+
+ trace_ext4_write_end(inode, pos, len, copied);
+
+- if (ext4_has_inline_data(inode))
++ if (ext4_has_inline_data(inode) &&
++ ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+ return ext4_write_inline_data_end(inode, pos, len, copied, page);
+
+ copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+@@ -4225,7 +4232,8 @@ int ext4_truncate(struct inode *inode)
+
+ /* If we zero-out tail of the page, we have to create jinode for jbd2 */
+ if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
+- if (ext4_inode_attach_jinode(inode) < 0)
++ err = ext4_inode_attach_jinode(inode);
++ if (err)
+ goto out_trace;
+ }
+
+@@ -4473,9 +4481,17 @@ static int __ext4_get_inode_loc(struct super_block *sb, unsigned long ino,
+ inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
+ inode_offset = ((ino - 1) %
+ EXT4_INODES_PER_GROUP(sb));
+- block = ext4_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
+ iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
+
++ block = ext4_inode_table(sb, gdp);
++ if ((block <= le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) ||
++ (block >= ext4_blocks_count(EXT4_SB(sb)->s_es))) {
++ ext4_error(sb, "Invalid inode table block %llu in "
++ "block_group %u", block, iloc->block_group);
++ return -EFSCORRUPTED;
++ }
++ block += (inode_offset / inodes_per_block);
++
+ bh = sb_getblk(sb, block);
+ if (unlikely(!bh))
+ return -ENOMEM;
+@@ -5044,8 +5060,14 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+ if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb))
+ ext4_error_inode(inode, function, line, 0,
+ "casefold flag without casefold feature");
+- brelse(iloc.bh);
++ if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) {
++ ext4_error_inode(inode, function, line, 0,
++ "bad inode without EXT4_IGET_BAD flag");
++ ret = -EUCLEAN;
++ goto bad_inode;
++ }
+
++ brelse(iloc.bh);
+ unlock_new_inode(inode);
+ return inode;
+
+@@ -5816,6 +5838,14 @@ static int __ext4_expand_extra_isize(struct inode *inode,
+ return 0;
+ }
+
++ /*
++ * We may need to allocate external xattr block so we need quotas
++ * initialized. Here we can be called with various locks held so we
++ * cannot affort to initialize quotas ourselves. So just bail.
++ */
++ if (dquot_initialize_needed(inode))
++ return -EAGAIN;
++
+ /* try to expand with EAs present */
+ error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+ raw_inode, handle);
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index eed8bd7812d58..62a68d9cee1cb 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -374,7 +374,8 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ blkcnt_t blocks;
+ unsigned short bytes;
+
+- inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
++ inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO,
++ EXT4_IGET_SPECIAL | EXT4_IGET_BAD);
+ if (IS_ERR(inode_bl))
+ return PTR_ERR(inode_bl);
+ ei_bl = EXT4_I(inode_bl);
+@@ -424,7 +425,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ /* Protect extent tree against block allocations via delalloc */
+ ext4_double_down_write_data_sem(inode, inode_bl);
+
+- if (inode_bl->i_nlink == 0) {
++ if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) {
+ /* this inode has never been used as a BOOT_LOADER */
+ set_nlink(inode_bl, 1);
+ i_uid_write(inode_bl, 0);
+@@ -731,6 +732,10 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ if (ext4_is_quota_file(inode))
+ return err;
+
++ err = dquot_initialize(inode);
++ if (err)
++ return err;
++
+ err = ext4_get_inode_loc(inode, &iloc);
+ if (err)
+ return err;
+@@ -746,10 +751,6 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ brelse(iloc.bh);
+ }
+
+- err = dquot_initialize(inode);
+- if (err)
+- return err;
+-
+ handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+ EXT4_QUOTA_INIT_BLOCKS(sb) +
+ EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+@@ -1156,19 +1157,22 @@ static int ext4_ioctl_getuuid(struct ext4_sb_info *sbi,
+
+ if (fsuuid.fsu_len == 0) {
+ fsuuid.fsu_len = UUID_SIZE;
+- if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid.fsu_len)))
++ if (copy_to_user(&ufsuuid->fsu_len, &fsuuid.fsu_len,
++ sizeof(fsuuid.fsu_len)))
+ return -EFAULT;
+- return -EINVAL;
++ return 0;
+ }
+
+- if (fsuuid.fsu_len != UUID_SIZE || fsuuid.fsu_flags != 0)
++ if (fsuuid.fsu_len < UUID_SIZE || fsuuid.fsu_flags != 0)
+ return -EINVAL;
+
+ lock_buffer(sbi->s_sbh);
+ memcpy(uuid, sbi->s_es->s_uuid, UUID_SIZE);
+ unlock_buffer(sbi->s_sbh);
+
+- if (copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
++ fsuuid.fsu_len = UUID_SIZE;
++ if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid)) ||
++ copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
+ return -EFAULT;
+ return 0;
+ }
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index be8136aafa22c..1e1a421333e8d 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -3204,14 +3204,20 @@ end_rmdir:
+ return retval;
+ }
+
+-int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+- struct inode *inode)
++int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++ struct inode *inode,
++ struct dentry *dentry /* NULL during fast_commit recovery */)
+ {
+ int retval = -ENOENT;
+ struct buffer_head *bh;
+ struct ext4_dir_entry_2 *de;
++ handle_t *handle;
+ int skip_remove_dentry = 0;
+
++ /*
++ * Keep this outside the transaction; it may have to set up the
++ * directory's encryption key, which isn't GFP_NOFS-safe.
++ */
+ bh = ext4_find_entry(dir, d_name, &de, NULL);
+ if (IS_ERR(bh))
+ return PTR_ERR(bh);
+@@ -3228,7 +3234,14 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
+ skip_remove_dentry = 1;
+ else
+- goto out;
++ goto out_bh;
++ }
++
++ handle = ext4_journal_start(dir, EXT4_HT_DIR,
++ EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
++ if (IS_ERR(handle)) {
++ retval = PTR_ERR(handle);
++ goto out_bh;
+ }
+
+ if (IS_DIRSYNC(dir))
+@@ -3237,12 +3250,12 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ if (!skip_remove_dentry) {
+ retval = ext4_delete_entry(handle, dir, de, bh);
+ if (retval)
+- goto out;
++ goto out_handle;
+ dir->i_ctime = dir->i_mtime = current_time(dir);
+ ext4_update_dx_flag(dir);
+ retval = ext4_mark_inode_dirty(handle, dir);
+ if (retval)
+- goto out;
++ goto out_handle;
+ } else {
+ retval = 0;
+ }
+@@ -3255,15 +3268,17 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ ext4_orphan_add(handle, inode);
+ inode->i_ctime = current_time(inode);
+ retval = ext4_mark_inode_dirty(handle, inode);
+-
+-out:
++ if (dentry && !retval)
++ ext4_fc_track_unlink(handle, dentry);
++out_handle:
++ ext4_journal_stop(handle);
++out_bh:
+ brelse(bh);
+ return retval;
+ }
+
+ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ {
+- handle_t *handle;
+ int retval;
+
+ if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
+@@ -3281,16 +3296,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ if (retval)
+ goto out_trace;
+
+- handle = ext4_journal_start(dir, EXT4_HT_DIR,
+- EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
+- if (IS_ERR(handle)) {
+- retval = PTR_ERR(handle);
+- goto out_trace;
+- }
+-
+- retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry));
+- if (!retval)
+- ext4_fc_track_unlink(handle, dentry);
++ retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry);
+ #if IS_ENABLED(CONFIG_UNICODE)
+ /* VFS negative dentries are incompatible with Encoding and
+ * Case-insensitiveness. Eventually we'll want avoid
+@@ -3301,8 +3307,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ if (IS_CASEFOLDED(dir))
+ d_invalidate(dentry);
+ #endif
+- if (handle)
+- ext4_journal_stop(handle);
+
+ out_trace:
+ trace_ext4_unlink_exit(dentry, retval);
+@@ -3792,6 +3796,9 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ return -EXDEV;
+
+ retval = dquot_initialize(old.dir);
++ if (retval)
++ return retval;
++ retval = dquot_initialize(old.inode);
+ if (retval)
+ return retval;
+ retval = dquot_initialize(new.dir);
+diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
+index 69a9cf9137a61..e5b47dda33175 100644
+--- a/fs/ext4/orphan.c
++++ b/fs/ext4/orphan.c
+@@ -412,7 +412,7 @@ void ext4_orphan_cleanup(struct super_block *sb, struct ext4_super_block *es)
+ /* don't clear list on RO mount w/ errors */
+ if (es->s_last_orphan && !(s_flags & SB_RDONLY)) {
+ ext4_msg(sb, KERN_INFO, "Errors on filesystem, "
+- "clearing orphan list.\n");
++ "clearing orphan list.");
+ es->s_last_orphan = 0;
+ }
+ ext4_debug("Skipping orphan recovery on fs with errors.\n");
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 46b87ffeb3045..b493233750ab2 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1110,6 +1110,16 @@ exit_free:
+ return err;
+ }
+
++static inline void ext4_set_block_group_nr(struct super_block *sb, char *data,
++ ext4_group_t group)
++{
++ struct ext4_super_block *es = (struct ext4_super_block *) data;
++
++ es->s_block_group_nr = cpu_to_le16(group);
++ if (ext4_has_metadata_csum(sb))
++ es->s_checksum = ext4_superblock_csum(sb, es);
++}
++
+ /*
+ * Update the backup copies of the ext4 metadata. These don't need to be part
+ * of the main resize transaction, because e2fsck will re-write them if there
+@@ -1158,7 +1168,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ while (group < sbi->s_groups_count) {
+ struct buffer_head *bh;
+ ext4_fsblk_t backup_block;
+- struct ext4_super_block *es;
++ int has_super = ext4_bg_has_super(sb, group);
++ ext4_fsblk_t first_block = ext4_group_first_block_no(sb, group);
+
+ /* Out of journal space, and can't get more - abort - so sad */
+ err = ext4_resize_ensure_credits_batch(handle, 1);
+@@ -1168,8 +1179,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ if (meta_bg == 0)
+ backup_block = ((ext4_fsblk_t)group) * bpg + blk_off;
+ else
+- backup_block = (ext4_group_first_block_no(sb, group) +
+- ext4_bg_has_super(sb, group));
++ backup_block = first_block + has_super;
+
+ bh = sb_getblk(sb, backup_block);
+ if (unlikely(!bh)) {
+@@ -1187,10 +1197,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ memcpy(bh->b_data, data, size);
+ if (rest)
+ memset(bh->b_data + size, 0, rest);
+- es = (struct ext4_super_block *) bh->b_data;
+- es->s_block_group_nr = cpu_to_le16(group);
+- if (ext4_has_metadata_csum(sb))
+- es->s_checksum = ext4_superblock_csum(sb, es);
++ if (has_super && (backup_block == first_block))
++ ext4_set_block_group_nr(sb, bh->b_data, group);
+ set_buffer_uptodate(bh);
+ unlock_buffer(bh);
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
+@@ -1476,8 +1484,6 @@ static void ext4_update_super(struct super_block *sb,
+ * active. */
+ ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
+ reserved_blocks);
+- ext4_superblock_csum_set(sb);
+- unlock_buffer(sbi->s_sbh);
+
+ /* Update the free space counts */
+ percpu_counter_add(&sbi->s_freeclusters_counter,
+@@ -1513,6 +1519,8 @@ static void ext4_update_super(struct super_block *sb,
+ ext4_calculate_overhead(sb);
+ es->s_overhead_clusters = cpu_to_le32(sbi->s_overhead);
+
++ ext4_superblock_csum_set(sb);
++ unlock_buffer(sbi->s_sbh);
+ if (test_opt(sb, DEBUG))
+ printk(KERN_DEBUG "EXT4-fs: added group %u:"
+ "%llu blocks(%llu free %llu reserved)\n", flex_gd->count,
+@@ -1596,8 +1604,8 @@ exit_journal:
+ int meta_bg = ext4_has_feature_meta_bg(sb);
+ sector_t old_gdb = 0;
+
+- update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+- sizeof(struct ext4_super_block), 0);
++ update_backups(sb, ext4_group_first_block_no(sb, 0),
++ (char *)es, sizeof(struct ext4_super_block), 0);
+ for (; gdb_num <= gdb_num_end; gdb_num++) {
+ struct buffer_head *gdb_bh;
+
+@@ -1808,7 +1816,7 @@ errout:
+ if (test_opt(sb, DEBUG))
+ printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
+ "blocks\n", ext4_blocks_count(es));
+- update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr,
++ update_backups(sb, ext4_group_first_block_no(sb, 0),
+ (char *)es, sizeof(struct ext4_super_block), 0);
+ }
+ return err;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 091db733834ee..2eae6e038f38a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1323,6 +1323,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ return NULL;
+
+ inode_set_iversion(&ei->vfs_inode, 1);
++ ei->i_flags = 0;
+ spin_lock_init(&ei->i_raw_lock);
+ INIT_LIST_HEAD(&ei->i_prealloc_list);
+ atomic_set(&ei->i_prealloc_active, 0);
+@@ -2260,7 +2261,7 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ return -EINVAL;
+ }
+
+- error = fs_lookup_param(fc, param, 1, &path);
++ error = fs_lookup_param(fc, param, 1, LOOKUP_FOLLOW, &path);
+ if (error) {
+ ext4_msg(NULL, KERN_ERR, "error: could not find "
+ "journal device path");
+@@ -5580,7 +5581,7 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
+
+ ext4_debug("Journal inode found at %p: %lld bytes\n",
+ journal_inode, journal_inode->i_size);
+- if (!S_ISREG(journal_inode->i_mode)) {
++ if (!S_ISREG(journal_inode->i_mode) || IS_ENCRYPTED(journal_inode)) {
+ ext4_msg(sb, KERN_ERR, "invalid journal inode");
+ iput(journal_inode);
+ return NULL;
+@@ -6743,6 +6744,20 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
+ return err;
+ }
+
++static inline bool ext4_check_quota_inum(int type, unsigned long qf_inum)
++{
++ switch (type) {
++ case USRQUOTA:
++ return qf_inum == EXT4_USR_QUOTA_INO;
++ case GRPQUOTA:
++ return qf_inum == EXT4_GRP_QUOTA_INO;
++ case PRJQUOTA:
++ return qf_inum >= EXT4_GOOD_OLD_FIRST_INO;
++ default:
++ BUG();
++ }
++}
++
+ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ unsigned int flags)
+ {
+@@ -6759,9 +6774,16 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ if (!qf_inums[type])
+ return -EPERM;
+
++ if (!ext4_check_quota_inum(type, qf_inums[type])) {
++ ext4_error(sb, "Bad quota inum: %lu, type: %d",
++ qf_inums[type], type);
++ return -EUCLEAN;
++ }
++
+ qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
+ if (IS_ERR(qf_inode)) {
+- ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
++ ext4_error(sb, "Bad quota inode: %lu, type: %d",
++ qf_inums[type], type);
+ return PTR_ERR(qf_inode);
+ }
+
+@@ -6800,8 +6822,9 @@ int ext4_enable_quotas(struct super_block *sb)
+ if (err) {
+ ext4_warning(sb,
+ "Failed to enable quota tracking "
+- "(type=%d, err=%d). Please run "
+- "e2fsck to fix.", type, err);
++ "(type=%d, err=%d, ino=%lu). "
++ "Please run e2fsck to fix.", type,
++ err, qf_inums[type]);
+ for (type--; type >= 0; type--) {
+ struct inode *inode;
+
+diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
+index 94442c690ca7d..47a132170f306 100644
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -79,7 +79,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count,
+ size_t n = min_t(size_t, count,
+ PAGE_SIZE - offset_in_page(pos));
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ int res;
+
+ res = aops->write_begin(NULL, mapping, pos, n, &page, &fsdata);
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 36d6ba7190b6d..866772a2e068f 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1281,7 +1281,7 @@ retry_ref:
+ ce = mb_cache_entry_get(ea_block_cache, hash,
+ bh->b_blocknr);
+ if (ce) {
+- ce->e_reusable = 1;
++ set_bit(MBE_REUSABLE_B, &ce->e_flags);
+ mb_cache_entry_put(ea_block_cache, ce);
+ }
+ }
+@@ -1441,6 +1441,9 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle,
+ if (!err)
+ err = ext4_inode_attach_jinode(ea_inode);
+ if (err) {
++ if (ext4_xattr_inode_dec_ref(handle, ea_inode))
++ ext4_warning_inode(ea_inode,
++ "cleanup dec ref error %d", err);
+ iput(ea_inode);
+ return ERR_PTR(err);
+ }
+@@ -2042,7 +2045,7 @@ inserted:
+ }
+ BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
+ if (ref == EXT4_XATTR_REFCOUNT_MAX)
+- ce->e_reusable = 0;
++ clear_bit(MBE_REUSABLE_B, &ce->e_flags);
+ ea_bdebug(new_bh, "reusing; refcount now=%d",
+ ref);
+ ext4_xattr_block_csum_set(inode, new_bh);
+@@ -2070,19 +2073,11 @@ inserted:
+
+ goal = ext4_group_first_block_no(sb,
+ EXT4_I(inode)->i_block_group);
+-
+- /* non-extent files can't have physical blocks past 2^32 */
+- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+- goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+-
+ block = ext4_new_meta_blocks(handle, inode, goal, 0,
+ NULL, &error);
+ if (error)
+ goto cleanup;
+
+- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+- BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
+-
+ ea_idebug(inode, "creating block %llu",
+ (unsigned long long)block);
+
+@@ -2555,7 +2550,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+
+ is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
+ bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
+- buffer = kmalloc(value_size, GFP_NOFS);
++ buffer = kvmalloc(value_size, GFP_NOFS);
+ b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
+ if (!is || !bs || !buffer || !b_entry_name) {
+ error = -ENOMEM;
+@@ -2607,7 +2602,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+ error = 0;
+ out:
+ kfree(b_entry_name);
+- kfree(buffer);
++ kvfree(buffer);
+ if (is)
+ brelse(is->iloc.bh);
+ if (bs)
+diff --git a/fs/fs_parser.c b/fs/fs_parser.c
+index ed40ce5742fda..edb3712dcfa58 100644
+--- a/fs/fs_parser.c
++++ b/fs/fs_parser.c
+@@ -138,15 +138,16 @@ EXPORT_SYMBOL(__fs_parse);
+ * @fc: The filesystem context to log errors through.
+ * @param: The parameter.
+ * @want_bdev: T if want a blockdev
++ * @flags: Pathwalk flags passed to filename_lookup()
+ * @_path: The result of the lookup
+ */
+ int fs_lookup_param(struct fs_context *fc,
+ struct fs_parameter *param,
+ bool want_bdev,
++ unsigned int flags,
+ struct path *_path)
+ {
+ struct filename *f;
+- unsigned int flags = 0;
+ bool put_f;
+ int ret;
+
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+index e272ad738faff..2a4b8b549e934 100644
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -100,8 +100,9 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ atomic_set(&entry->e_refcnt, 2);
+ entry->e_key = key;
+ entry->e_value = value;
+- entry->e_reusable = reusable;
+- entry->e_referenced = 0;
++ entry->e_flags = 0;
++ if (reusable)
++ set_bit(MBE_REUSABLE_B, &entry->e_flags);
+ head = mb_cache_entry_head(cache, key);
+ hlist_bl_lock(head);
+ hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
+@@ -165,7 +166,8 @@ static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
+ while (node) {
+ entry = hlist_bl_entry(node, struct mb_cache_entry,
+ e_hash_list);
+- if (entry->e_key == key && entry->e_reusable &&
++ if (entry->e_key == key &&
++ test_bit(MBE_REUSABLE_B, &entry->e_flags) &&
+ atomic_inc_not_zero(&entry->e_refcnt))
+ goto out;
+ node = node->next;
+@@ -284,7 +286,7 @@ EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
+ void mb_cache_entry_touch(struct mb_cache *cache,
+ struct mb_cache_entry *entry)
+ {
+- entry->e_referenced = 1;
++ set_bit(MBE_REFERENCED_B, &entry->e_flags);
+ }
+ EXPORT_SYMBOL(mb_cache_entry_touch);
+
+@@ -309,9 +311,9 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache,
+ entry = list_first_entry(&cache->c_list,
+ struct mb_cache_entry, e_list);
+ /* Drop initial hash reference if there is no user */
+- if (entry->e_referenced ||
++ if (test_bit(MBE_REFERENCED_B, &entry->e_flags) ||
+ atomic_cmpxchg(&entry->e_refcnt, 1, 0) != 1) {
+- entry->e_referenced = 0;
++ clear_bit(MBE_REFERENCED_B, &entry->e_flags);
+ list_move_tail(&entry->e_list, &cache->c_list);
+ continue;
+ }
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 0427b44bfee54..f27faf5db5544 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2324,6 +2324,8 @@ static int vfs_setup_quota_inode(struct inode *inode, int type)
+ struct super_block *sb = inode->i_sb;
+ struct quota_info *dqopt = sb_dqopt(sb);
+
++ if (is_bad_inode(inode))
++ return -EUCLEAN;
+ if (!S_ISREG(inode->i_mode))
+ return -EACCES;
+ if (IS_RDONLY(inode))
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 184b957e28ada..1eac74cacc963 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -634,7 +634,7 @@ static inline u32 type_flag(u32 type)
+ }
+
+ /* only use after check_attach_btf_id() */
+-static inline enum bpf_prog_type resolve_prog_type(struct bpf_prog *prog)
++static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog)
+ {
+ return prog->type == BPF_PROG_TYPE_EXT ?
+ prog->aux->dst_prog->type : prog->type;
+diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
+index 34aab4dd336c8..4dc7cda4fd469 100644
+--- a/include/linux/devfreq.h
++++ b/include/linux/devfreq.h
+@@ -152,8 +152,8 @@ struct devfreq_stats {
+ * @max_state: count of entry present in the frequency table.
+ * @previous_freq: previously configured frequency value.
+ * @last_status: devfreq user device info, performance statistics
+- * @data: Private data of the governor. The devfreq framework does not
+- * touch this.
++ * @data: devfreq driver pass to governors, governor should not change it.
++ * @governor_data: private data for governors, devfreq core doesn't touch it.
+ * @user_min_freq_req: PM QoS minimum frequency request from user (via sysfs)
+ * @user_max_freq_req: PM QoS maximum frequency request from user (via sysfs)
+ * @scaling_min_freq: Limit minimum frequency requested by OPP interface
+@@ -193,7 +193,8 @@ struct devfreq {
+ unsigned long previous_freq;
+ struct devfreq_dev_status last_status;
+
+- void *data; /* private data for governors */
++ void *data;
++ void *governor_data;
+
+ struct dev_pm_qos_request user_min_freq_req;
+ struct dev_pm_qos_request user_max_freq_req;
+diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h
+index f103c91139d4a..01542c4b87a2b 100644
+--- a/include/linux/fs_parser.h
++++ b/include/linux/fs_parser.h
+@@ -76,6 +76,7 @@ static inline int fs_parse(struct fs_context *fc,
+ extern int fs_lookup_param(struct fs_context *fc,
+ struct fs_parameter *param,
+ bool want_bdev,
++ unsigned int flags,
+ struct path *_path);
+
+ extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
+diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
+index 2da63fd7b98f4..97e64184767de 100644
+--- a/include/linux/mbcache.h
++++ b/include/linux/mbcache.h
+@@ -10,6 +10,12 @@
+
+ struct mb_cache;
+
++/* Cache entry flags */
++enum {
++ MBE_REFERENCED_B = 0,
++ MBE_REUSABLE_B
++};
++
+ struct mb_cache_entry {
+ /* List of entries in cache - protected by cache->c_list_lock */
+ struct list_head e_list;
+@@ -26,8 +32,7 @@ struct mb_cache_entry {
+ atomic_t e_refcnt;
+ /* Key in hash - stable during lifetime of the entry */
+ u32 e_key;
+- u32 e_referenced:1;
+- u32 e_reusable:1;
++ unsigned long e_flags;
+ /* User provided value - stable during lifetime of the entry */
+ u64 e_value;
+ };
+diff --git a/include/net/mptcp.h b/include/net/mptcp.h
+index 412479ebf5ad3..3c5c68618fcc5 100644
+--- a/include/net/mptcp.h
++++ b/include/net/mptcp.h
+@@ -97,8 +97,6 @@ struct mptcp_out_options {
+ };
+
+ #ifdef CONFIG_MPTCP
+-extern struct request_sock_ops mptcp_subflow_request_sock_ops;
+-
+ void mptcp_init(void);
+
+ static inline bool sk_is_mptcp(const struct sock *sk)
+@@ -188,6 +186,9 @@ void mptcp_seq_show(struct seq_file *seq);
+ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ const struct sock *sk_listener,
+ struct sk_buff *skb);
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener);
+
+ __be32 mptcp_get_reset_option(const struct sk_buff *skb);
+
+@@ -274,6 +275,13 @@ static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ return 0; /* TCP fallback */
+ }
+
++static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener)
++{
++ return NULL;
++}
++
+ static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
+ #endif /* CONFIG_MPTCP */
+
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index 229e8fae66a34..ced95fec3367d 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RESIZE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RENAME_DIR);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
++TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+
+ #define show_fc_reason(reason) \
+@@ -116,7 +117,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+ { EXT4_FC_REASON_RESIZE, "RESIZE"}, \
+ { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, \
+ { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, \
+- { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"})
++ { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}, \
++ { EXT4_FC_REASON_ENCRYPTED_FILENAME, "ENCRYPTED_FILENAME"})
+
+ TRACE_EVENT(ext4_other_inode_update_time,
+ TP_PROTO(struct inode *inode, ino_t orig_ino),
+@@ -2764,7 +2766,7 @@ TRACE_EVENT(ext4_fc_stats,
+ ),
+
+ TP_printk("dev %d,%d fc ineligible reasons:\n"
+- "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u "
++ "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u"
+ "num_commits:%lu, ineligible: %lu, numblks: %lu",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
+@@ -2776,6 +2778,7 @@ TRACE_EVENT(ext4_fc_stats,
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE),
+ FC_REASON_NAME_STAT(EXT4_FC_REASON_INODE_JOURNAL_DATA),
++ FC_REASON_NAME_STAT(EXT4_FC_REASON_ENCRYPTED_FILENAME),
+ __entry->fc_commits, __entry->fc_ineligible_commits,
+ __entry->fc_numblks)
+ );
+diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
+index 99f783c384bb4..8f5ee380d3093 100644
+--- a/include/trace/events/jbd2.h
++++ b/include/trace/events/jbd2.h
+@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( char, sync_commit )
+- __field( int, transaction )
++ __field( tid_t, transaction )
+ ),
+
+ TP_fast_assign(
+@@ -49,7 +49,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ __entry->transaction = commit_transaction->t_tid;
+ ),
+
+- TP_printk("dev %d,%d transaction %d sync %d",
++ TP_printk("dev %d,%d transaction %u sync %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->transaction, __entry->sync_commit)
+ );
+@@ -97,8 +97,8 @@ TRACE_EVENT(jbd2_end_commit,
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( char, sync_commit )
+- __field( int, transaction )
+- __field( int, head )
++ __field( tid_t, transaction )
++ __field( tid_t, head )
+ ),
+
+ TP_fast_assign(
+@@ -108,7 +108,7 @@ TRACE_EVENT(jbd2_end_commit,
+ __entry->head = journal->j_tail_sequence;
+ ),
+
+- TP_printk("dev %d,%d transaction %d sync %d head %d",
++ TP_printk("dev %d,%d transaction %u sync %d head %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->transaction, __entry->sync_commit, __entry->head)
+ );
+@@ -134,14 +134,14 @@ TRACE_EVENT(jbd2_submit_inode_data,
+ );
+
+ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, requested_blocks)
+@@ -155,28 +155,28 @@ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+ __entry->requested_blocks = requested_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u "
++ TP_printk("dev %d,%d tid %u type %u line_no %u "
+ "requested_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->requested_blocks)
+ );
+
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_start,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_restart,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int requested_blocks),
+
+ TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+
+ TRACE_EVENT(jbd2_handle_extend,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int buffer_credits,
+ int requested_blocks),
+
+@@ -184,7 +184,7 @@ TRACE_EVENT(jbd2_handle_extend,
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, buffer_credits )
+@@ -200,7 +200,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ __entry->requested_blocks = requested_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u "
++ TP_printk("dev %d,%d tid %u type %u line_no %u "
+ "buffer_credits %d requested_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->buffer_credits,
+@@ -208,7 +208,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ );
+
+ TRACE_EVENT(jbd2_handle_stats,
+- TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++ TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ unsigned int line_no, int interval, int sync,
+ int requested_blocks, int dirtied_blocks),
+
+@@ -217,7 +217,7 @@ TRACE_EVENT(jbd2_handle_stats,
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned int, type )
+ __field( unsigned int, line_no )
+ __field( int, interval )
+@@ -237,7 +237,7 @@ TRACE_EVENT(jbd2_handle_stats,
+ __entry->dirtied_blocks = dirtied_blocks;
+ ),
+
+- TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d "
++ TP_printk("dev %d,%d tid %u type %u line_no %u interval %d "
+ "sync %d requested_blocks %d dirtied_blocks %d",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ __entry->type, __entry->line_no, __entry->interval,
+@@ -246,14 +246,14 @@ TRACE_EVENT(jbd2_handle_stats,
+ );
+
+ TRACE_EVENT(jbd2_run_stats,
+- TP_PROTO(dev_t dev, unsigned long tid,
++ TP_PROTO(dev_t dev, tid_t tid,
+ struct transaction_run_stats_s *stats),
+
+ TP_ARGS(dev, tid, stats),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned long, wait )
+ __field( unsigned long, request_delay )
+ __field( unsigned long, running )
+@@ -279,7 +279,7 @@ TRACE_EVENT(jbd2_run_stats,
+ __entry->blocks_logged = stats->rs_blocks_logged;
+ ),
+
+- TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u "
++ TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u "
+ "locked %u flushing %u logging %u handle_count %u "
+ "blocks %u blocks_logged %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+@@ -294,14 +294,14 @@ TRACE_EVENT(jbd2_run_stats,
+ );
+
+ TRACE_EVENT(jbd2_checkpoint_stats,
+- TP_PROTO(dev_t dev, unsigned long tid,
++ TP_PROTO(dev_t dev, tid_t tid,
+ struct transaction_chp_stats_s *stats),
+
+ TP_ARGS(dev, tid, stats),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+- __field( unsigned long, tid )
++ __field( tid_t, tid )
+ __field( unsigned long, chp_time )
+ __field( __u32, forced_to_close )
+ __field( __u32, written )
+@@ -317,7 +317,7 @@ TRACE_EVENT(jbd2_checkpoint_stats,
+ __entry->dropped = stats->cs_dropped;
+ ),
+
+- TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u "
++ TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u "
+ "written %u dropped %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ jiffies_to_msecs(__entry->chp_time),
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index c4600a5781de1..7d315c94b80af 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2088,6 +2088,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
+ bool bpf_prog_map_compatible(struct bpf_map *map,
+ const struct bpf_prog *fp)
+ {
++ enum bpf_prog_type prog_type = resolve_prog_type(fp);
+ bool ret;
+
+ if (fp->kprobe_override)
+@@ -2098,12 +2099,12 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
+ /* There's no owner yet where we could check for
+ * compatibility.
+ */
+- map->owner.type = fp->type;
++ map->owner.type = prog_type;
+ map->owner.jited = fp->jited;
+ map->owner.xdp_has_frags = fp->aux->xdp_has_frags;
+ ret = true;
+ } else {
+- ret = map->owner.type == fp->type &&
++ ret = map->owner.type == prog_type &&
+ map->owner.jited == fp->jited &&
+ map->owner.xdp_has_frags == fp->aux->xdp_has_frags;
+ }
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index a636fab5e381a..6914f328f7d7d 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -12176,12 +12176,12 @@ SYSCALL_DEFINE5(perf_event_open,
+ if (flags & ~PERF_FLAG_ALL)
+ return -EINVAL;
+
+- /* Do we allow access to perf_event_open(2) ? */
+- err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
++ err = perf_copy_attr(attr_uptr, &attr);
+ if (err)
+ return err;
+
+- err = perf_copy_attr(attr_uptr, &attr);
++ /* Do we allow access to perf_event_open(2) ? */
++ err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
+ if (err)
+ return err;
+
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 1052126bdca22..0977defe98205 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -369,6 +369,7 @@ config SCHED_TRACER
+ config HWLAT_TRACER
+ bool "Tracer to detect hardware latencies (like SMIs)"
+ select GENERIC_TRACER
++ select TRACER_MAX_TRACE
+ help
+ This tracer, when enabled will create one or more kernel threads,
+ depending on what the cpumask file is set to, which each thread
+@@ -404,6 +405,7 @@ config HWLAT_TRACER
+ config OSNOISE_TRACER
+ bool "OS Noise tracer"
+ select GENERIC_TRACER
++ select TRACER_MAX_TRACE
+ help
+ In the context of high-performance computing (HPC), the Operating
+ System Noise (osnoise) refers to the interference experienced by an
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 7132e21e90d6d..0bfd805ec63fa 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1421,6 +1421,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ return false;
+ }
+ EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
++#define free_snapshot(tr) do { } while (0)
+ #endif /* CONFIG_TRACER_SNAPSHOT */
+
+ void tracer_tracing_off(struct trace_array *tr)
+@@ -1692,6 +1693,8 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
+ }
+
+ unsigned long __read_mostly tracing_thresh;
++
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops;
+
+ #ifdef LATENCY_FS_NOTIFY
+@@ -1748,18 +1751,14 @@ void latency_fsnotify(struct trace_array *tr)
+ irq_work_queue(&tr->fsnotify_irqwork);
+ }
+
+-#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)
++#else /* !LATENCY_FS_NOTIFY */
+
+ #define trace_create_maxlat_file(tr, d_tracer) \
+ trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \
+ d_tracer, &tr->max_latency, &tracing_max_lat_fops)
+
+-#else
+-#define trace_create_maxlat_file(tr, d_tracer) do { } while (0)
+ #endif
+
+-#ifdef CONFIG_TRACER_MAX_TRACE
+ /*
+ * Copy the new maximum trace into the separate maximum-trace
+ * structure. (this way the maximum trace is permanently saved,
+@@ -1834,14 +1833,15 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ ring_buffer_record_off(tr->max_buffer.buffer);
+
+ #ifdef CONFIG_TRACER_SNAPSHOT
+- if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
+- goto out_unlock;
++ if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) {
++ arch_spin_unlock(&tr->max_lock);
++ return;
++ }
+ #endif
+ swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
+
+ __update_max_tr(tr, tsk, cpu);
+
+- out_unlock:
+ arch_spin_unlock(&tr->max_lock);
+ }
+
+@@ -1888,6 +1888,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
+ __update_max_tr(tr, tsk, cpu);
+ arch_spin_unlock(&tr->max_lock);
+ }
++
+ #endif /* CONFIG_TRACER_MAX_TRACE */
+
+ static int wait_on_pipe(struct trace_iterator *iter, int full)
+@@ -6563,7 +6564,7 @@ out:
+ return ret;
+ }
+
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+
+ static ssize_t
+ tracing_max_lat_read(struct file *filp, char __user *ubuf,
+@@ -6787,7 +6788,20 @@ waitagain:
+
+ ret = print_trace_line(iter);
+ if (ret == TRACE_TYPE_PARTIAL_LINE) {
+- /* don't print partial lines */
++ /*
++ * If one print_trace_line() fills entire trace_seq in one shot,
++ * trace_seq_to_user() will returns -EBUSY because save_len == 0,
++ * In this case, we need to consume it, otherwise, loop will peek
++ * this event next time, resulting in an infinite loop.
++ */
++ if (save_len == 0) {
++ iter->seq.full = 0;
++ trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
++ trace_consume(iter);
++ break;
++ }
++
++ /* In other cases, don't print partial lines */
+ iter->seq.seq.len = save_len;
+ break;
+ }
+@@ -7578,7 +7592,7 @@ static const struct file_operations tracing_thresh_fops = {
+ .llseek = generic_file_llseek,
+ };
+
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops = {
+ .open = tracing_open_generic,
+ .read = tracing_max_lat_read,
+@@ -9592,7 +9606,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
+
+ create_trace_options_dir(tr);
+
++#ifdef CONFIG_TRACER_MAX_TRACE
+ trace_create_maxlat_file(tr, d_tracer);
++#endif
+
+ if (ftrace_create_function_files(tr, d_tracer))
+ MEM_FAIL(1, "Could not allocate function filter files");
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 900e75d96c846..e5558d41d36ca 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -308,8 +308,7 @@ struct trace_array {
+ struct array_buffer max_buffer;
+ bool allocated_snapshot;
+ #endif
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ unsigned long max_latency;
+ #ifdef CONFIG_FSNOTIFY
+ struct dentry *d_max_latency;
+@@ -687,12 +686,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ void *cond_data);
+ void update_max_tr_single(struct trace_array *tr,
+ struct task_struct *tsk, int cpu);
+-#endif /* CONFIG_TRACER_MAX_TRACE */
+
+-#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+- || defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY)
++#ifdef CONFIG_FSNOTIFY
+ #define LATENCY_FS_NOTIFY
+ #endif
++#endif /* CONFIG_TRACER_MAX_TRACE */
+
+ #ifdef LATENCY_FS_NOTIFY
+ void latency_fsnotify(struct trace_array *tr);
+@@ -1968,17 +1966,30 @@ static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
+ }
+
+ /* Check the name is good for event/group/fields */
+-static inline bool is_good_name(const char *name)
++static inline bool __is_good_name(const char *name, bool hash_ok)
+ {
+- if (!isalpha(*name) && *name != '_')
++ if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-'))
+ return false;
+ while (*++name != '\0') {
+- if (!isalpha(*name) && !isdigit(*name) && *name != '_')
++ if (!isalpha(*name) && !isdigit(*name) && *name != '_' &&
++ (!hash_ok || *name != '-'))
+ return false;
+ }
+ return true;
+ }
+
++/* Check the name is good for event/group/fields */
++static inline bool is_good_name(const char *name)
++{
++ return __is_good_name(name, false);
++}
++
++/* Check the name is good for system */
++static inline bool is_good_system_name(const char *name)
++{
++ return __is_good_name(name, true);
++}
++
+ /* Convert certain expected symbols into '_' when generating event names */
+ static inline void sanitize_event_name(char *name)
+ {
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 3b055aaee89a9..cae987f5a6524 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -560,6 +560,9 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
+ {
+ struct eprobe_data *edata = data->private_data;
+
++ if (unlikely(!rec))
++ return;
++
+ if (unlikely(!rec))
+ return;
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index d8406f6f5d399..3fb4da6ee8ef0 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -588,7 +588,7 @@ struct action_data {
+ * event param, and is passed to the synthetic event
+ * invocation.
+ */
+- unsigned int var_ref_idx[TRACING_MAP_VARS_MAX];
++ unsigned int var_ref_idx[SYNTH_FIELDS_MAX];
+ struct synth_event *synth_event;
+ bool use_trace_keyword;
+ char *synth_event_name;
+@@ -2150,7 +2150,9 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
+ return ref_field;
+ }
+ }
+-
++ /* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
++ if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
++ return NULL;
+ ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
+ if (ref_field) {
+ if (init_var_ref(ref_field, var_field, system, event_name)) {
+@@ -3562,6 +3564,7 @@ static int parse_action_params(struct trace_array *tr, char *params,
+ while (params) {
+ if (data->n_params >= SYNTH_FIELDS_MAX) {
+ hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
++ ret = -EINVAL;
+ goto out;
+ }
+
+@@ -3898,6 +3901,10 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
+
+ lockdep_assert_held(&event_mutex);
+
++ /* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
++ if (data->n_params > SYNTH_FIELDS_MAX)
++ return -EINVAL;
++
+ if (data->use_trace_keyword)
+ synth_event_name = data->synth_event_name;
+ else
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 29fbfb27c2b2c..b16673926a415 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -1282,12 +1282,12 @@ static int __create_synth_event(const char *name, const char *raw_fields)
+ goto err_free_arg;
+ }
+
+- fields[n_fields++] = field;
+ if (n_fields == SYNTH_FIELDS_MAX) {
+ synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
+ ret = -EINVAL;
+ goto err_free_arg;
+ }
++ fields[n_fields++] = field;
+
+ n_fields_this_loop++;
+ }
+diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
+index 36dff277de464..bb2f95d7175c2 100644
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
+ return -EINVAL;
+ }
+ strlcpy(buf, event, slash - event + 1);
+- if (!is_good_name(buf)) {
++ if (!is_good_system_name(buf)) {
+ trace_probe_log_err(offset, BAD_GROUP_NAME);
+ return -EINVAL;
+ }
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 88f34cdeef023..dd1d02c9e0d08 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -2080,6 +2080,7 @@ config TEST_MIN_HEAP
+ config TEST_SORT
+ tristate "Array-based sort test" if !KUNIT_ALL_TESTS
+ depends on KUNIT
++ select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+ default KUNIT_ALL_TESTS
+ help
+ This option enables the self-test function of 'sort()' at boot,
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 942d2dfa11151..26fb97d1d4d9a 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -288,12 +288,11 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+ struct tcp_request_sock *treq;
+ struct request_sock *req;
+
+-#ifdef CONFIG_MPTCP
+ if (sk_is_mptcp(sk))
+- ops = &mptcp_subflow_request_sock_ops;
+-#endif
++ req = mptcp_subflow_reqsk_alloc(ops, sk, false);
++ else
++ req = inet_reqsk_alloc(ops, sk, false);
+
+- req = inet_reqsk_alloc(ops, sk, false);
+ if (!req)
+ return NULL;
+
+diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
+index 9e82250cbb703..0430415357ba3 100644
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -156,6 +156,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
+
+ if (addr_val.addr.id == 0 || !(addr_val.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
+ GENL_SET_ERR_MSG(info, "invalid addr id or flags");
++ err = -EINVAL;
+ goto announce_err;
+ }
+
+@@ -282,6 +283,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
+
+ if (addr_l.id == 0) {
+ NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id");
++ err = -EINVAL;
+ goto create_err;
+ }
+
+@@ -395,11 +397,13 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
+
+ if (addr_l.family != addr_r.family) {
+ GENL_SET_ERR_MSG(info, "address families do not match");
++ err = -EINVAL;
+ goto destroy_err;
+ }
+
+ if (!addr_l.port || !addr_r.port) {
+ GENL_SET_ERR_MSG(info, "missing local or remote port");
++ err = -EINVAL;
+ goto destroy_err;
+ }
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 2159b5f9988f8..613f515fedf0a 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -45,7 +45,6 @@ static void subflow_req_destructor(struct request_sock *req)
+ sock_put((struct sock *)subflow_req->msk);
+
+ mptcp_token_destroy_request(req);
+- tcp_request_sock_ops.destructor(req);
+ }
+
+ static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
+@@ -529,7 +528,7 @@ static int subflow_v6_rebuild_header(struct sock *sk)
+ }
+ #endif
+
+-struct request_sock_ops mptcp_subflow_request_sock_ops;
++static struct request_sock_ops mptcp_subflow_v4_request_sock_ops __ro_after_init;
+ static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
+
+ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+@@ -542,7 +541,7 @@ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+ goto drop;
+
+- return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++ return tcp_conn_request(&mptcp_subflow_v4_request_sock_ops,
+ &subflow_request_sock_ipv4_ops,
+ sk, skb);
+ drop:
+@@ -550,7 +549,14 @@ drop:
+ return 0;
+ }
+
++static void subflow_v4_req_destructor(struct request_sock *req)
++{
++ subflow_req_destructor(req);
++ tcp_request_sock_ops.destructor(req);
++}
++
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
++static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init;
+ static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
+ static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
+ static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
+@@ -573,15 +579,36 @@ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+ return 0;
+ }
+
+- return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++ return tcp_conn_request(&mptcp_subflow_v6_request_sock_ops,
+ &subflow_request_sock_ipv6_ops, sk, skb);
+
+ drop:
+ tcp_listendrop(sk);
+ return 0; /* don't send reset */
+ }
++
++static void subflow_v6_req_destructor(struct request_sock *req)
++{
++ subflow_req_destructor(req);
++ tcp6_request_sock_ops.destructor(req);
++}
++#endif
++
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++ struct sock *sk_listener,
++ bool attach_listener)
++{
++ if (ops->family == AF_INET)
++ ops = &mptcp_subflow_v4_request_sock_ops;
++#if IS_ENABLED(CONFIG_MPTCP_IPV6)
++ else if (ops->family == AF_INET6)
++ ops = &mptcp_subflow_v6_request_sock_ops;
+ #endif
+
++ return inet_reqsk_alloc(ops, sk_listener, attach_listener);
++}
++EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
++
+ /* validate hmac received in third ACK */
+ static bool subflow_hmac_valid(const struct request_sock *req,
+ const struct mptcp_options_received *mp_opt)
+@@ -1904,7 +1931,6 @@ static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
+ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ {
+ subflow_ops->obj_size = sizeof(struct mptcp_subflow_request_sock);
+- subflow_ops->slab_name = "request_sock_subflow";
+
+ subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name,
+ subflow_ops->obj_size, 0,
+@@ -1914,16 +1940,17 @@ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ if (!subflow_ops->slab)
+ return -ENOMEM;
+
+- subflow_ops->destructor = subflow_req_destructor;
+-
+ return 0;
+ }
+
+ void __init mptcp_subflow_init(void)
+ {
+- mptcp_subflow_request_sock_ops = tcp_request_sock_ops;
+- if (subflow_ops_init(&mptcp_subflow_request_sock_ops) != 0)
+- panic("MPTCP: failed to init subflow request sock ops\n");
++ mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops;
++ mptcp_subflow_v4_request_sock_ops.slab_name = "request_sock_subflow_v4";
++ mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor;
++
++ if (subflow_ops_init(&mptcp_subflow_v4_request_sock_ops) != 0)
++ panic("MPTCP: failed to init subflow v4 request sock ops\n");
+
+ subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
+ subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
+@@ -1938,6 +1965,20 @@ void __init mptcp_subflow_init(void)
+ tcp_prot_override.release_cb = tcp_release_cb_override;
+
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
++ /* In struct mptcp_subflow_request_sock, we assume the TCP request sock
++ * structures for v4 and v6 have the same size. It should not changed in
++ * the future but better to make sure to be warned if it is no longer
++ * the case.
++ */
++ BUILD_BUG_ON(sizeof(struct tcp_request_sock) != sizeof(struct tcp6_request_sock));
++
++ mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops;
++ mptcp_subflow_v6_request_sock_ops.slab_name = "request_sock_subflow_v6";
++ mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor;
++
++ if (subflow_ops_init(&mptcp_subflow_v6_request_sock_ops) != 0)
++ panic("MPTCP: failed to init subflow v6 request sock ops\n");
++
+ subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops;
+ subflow_request_sock_ipv6_ops.route_req = subflow_v6_route_req;
+
+diff --git a/security/device_cgroup.c b/security/device_cgroup.c
+index a9f8c63a96d1a..bef2b9285fb34 100644
+--- a/security/device_cgroup.c
++++ b/security/device_cgroup.c
+@@ -82,6 +82,17 @@ free_and_exit:
+ return -ENOMEM;
+ }
+
++static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
++{
++ struct dev_exception_item *ex, *tmp;
++
++ lockdep_assert_held(&devcgroup_mutex);
++
++ list_for_each_entry_safe(ex, tmp, orig, list) {
++ list_move_tail(&ex->list, dest);
++ }
++}
++
+ /*
+ * called under devcgroup_mutex
+ */
+@@ -604,11 +615,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+ int count, rc = 0;
+ struct dev_exception_item ex;
+ struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
++ struct dev_cgroup tmp_devcgrp;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ memset(&ex, 0, sizeof(ex));
++ memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
+ b = buffer;
+
+ switch (*b) {
+@@ -620,15 +633,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+
+ if (!may_allow_all(parent))
+ return -EPERM;
+- dev_exception_clean(devcgroup);
+- devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+- if (!parent)
++ if (!parent) {
++ devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++ dev_exception_clean(devcgroup);
+ break;
++ }
+
++ INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
++ rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
++ &devcgroup->exceptions);
++ if (rc)
++ return rc;
++ dev_exception_clean(devcgroup);
+ rc = dev_exceptions_copy(&devcgroup->exceptions,
+ &parent->exceptions);
+- if (rc)
++ if (rc) {
++ dev_exceptions_move(&devcgroup->exceptions,
++ &tmp_devcgrp.exceptions);
+ return rc;
++ }
++ devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++ dev_exception_clean(&tmp_devcgrp);
+ break;
+ case DEVCG_DENY:
+ if (css_has_online_children(&devcgroup->css))
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index 7249f16257c72..39caeca474449 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -112,7 +112,7 @@ choice
+
+ config IMA_DEFAULT_HASH_SM3
+ bool "SM3"
+- depends on CRYPTO_SM3=y
++ depends on CRYPTO_SM3_GENERIC=y
+ endchoice
+
+ config IMA_DEFAULT_HASH
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 040b03ddc1c77..4a207a3ef7ef3 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -542,8 +542,13 @@ static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,
+
+ rc = ima_collect_measurement(&tmp_iint, file, NULL, 0,
+ ima_hash_algo, NULL);
+- if (rc < 0)
++ if (rc < 0) {
++ /* ima_hash could be allocated in case of failure. */
++ if (rc != -ENOMEM)
++ kfree(tmp_iint.ima_hash);
++
+ return -EOPNOTSUPP;
++ }
+
+ iint = &tmp_iint;
+ mutex_lock(&iint->mutex);
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index 195ac18f09275..04c49f05cb74f 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -340,8 +340,11 @@ static struct ima_template_desc *restore_template_fmt(char *template_name)
+
+ template_desc->name = "";
+ template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
+- if (!template_desc->fmt)
++ if (!template_desc->fmt) {
++ kfree(template_desc);
++ template_desc = NULL;
+ goto out;
++ }
+
+ spin_lock(&template_list);
+ list_add_tail_rcu(&template_desc->list, &defined_templates);
+diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
+index b78753d27d8ea..d1fdd113450a6 100644
+--- a/security/integrity/platform_certs/load_uefi.c
++++ b/security/integrity/platform_certs/load_uefi.c
+@@ -35,6 +35,7 @@ static const struct dmi_system_id uefi_skip_cert[] = {
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
++ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
+ { }
+ };
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 94fe842178947..cca6e8fdec5ff 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6925,6 +6925,34 @@ static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec,
+ }
+ }
+
++static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ static const struct hda_pintbl pincfgs[] = {
++ { 0x14, 0x90170151 },
++ { 0x17, 0x90170150 },
++ { }
++ };
++ static const hda_nid_t conn[] = { 0x02, 0x03 };
++ static const hda_nid_t preferred_pairs[] = {
++ 0x14, 0x02,
++ 0x17, 0x03,
++ 0x21, 0x02,
++ 0
++ };
++ struct alc_spec *spec = codec->spec;
++
++ alc_fixup_no_shutup(codec, fix, action);
++
++ switch (action) {
++ case HDA_FIXUP_ACT_PRE_PROBE:
++ snd_hda_apply_pincfgs(codec, pincfgs);
++ snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
++ spec->gen.preferred_dacs = preferred_pairs;
++ break;
++ }
++}
++
+ enum {
+ ALC269_FIXUP_GPIO2,
+ ALC269_FIXUP_SONY_VAIO,
+@@ -7168,6 +7196,8 @@ enum {
+ ALC287_FIXUP_LEGION_16ITHG6,
+ ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+ ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN,
++ ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
++ ALC236_FIXUP_DELL_DUAL_CODECS,
+ };
+
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9117,6 +9147,18 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+ },
++ [ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc295_fixup_dell_inspiron_top_speakers,
++ .chained = true,
++ .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
++ },
++ [ALC236_FIXUP_DELL_DUAL_CODECS] = {
++ .type = HDA_FIXUP_PINS,
++ .v.func = alc1220_fixup_gb_dual_codecs,
++ .chained = true,
++ .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -9217,6 +9259,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
+ SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
++ SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++ SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++ SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++ SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
+ SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
+index c4c1e89b47c1b..83cb81999c6fc 100644
+--- a/sound/soc/jz4740/jz4740-i2s.c
++++ b/sound/soc/jz4740/jz4740-i2s.c
+@@ -55,7 +55,8 @@
+ #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
+ #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
+ #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
+-#define JZ_AIC_CTRL_FLUSH BIT(8)
++#define JZ_AIC_CTRL_TFLUSH BIT(8)
++#define JZ_AIC_CTRL_RFLUSH BIT(7)
+ #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
+ #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
+ #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
+@@ -90,6 +91,8 @@ enum jz47xx_i2s_version {
+ struct i2s_soc_info {
+ enum jz47xx_i2s_version version;
+ struct snd_soc_dai_driver *dai;
++
++ bool shared_fifo_flush;
+ };
+
+ struct jz4740_i2s {
+@@ -116,19 +119,44 @@ static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
+ writel(value, i2s->base + reg);
+ }
+
++static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
++ unsigned int reg, uint32_t bits)
++{
++ uint32_t value = jz4740_i2s_read(i2s, reg);
++ value |= bits;
++ jz4740_i2s_write(i2s, reg, value);
++}
++
+ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+- uint32_t conf, ctrl;
++ uint32_t conf;
+ int ret;
+
++ /*
++ * When we can flush FIFOs independently, only flush the FIFO
++ * that is starting up. We can do this when the DAI is active
++ * because it does not disturb other active substreams.
++ */
++ if (!i2s->soc_info->shared_fifo_flush) {
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
++ else
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
++ }
++
+ if (snd_soc_dai_active(dai))
+ return 0;
+
+- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
+- ctrl |= JZ_AIC_CTRL_FLUSH;
+- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
++ /*
++ * When there is a shared flush bit for both FIFOs, the TFLUSH
++ * bit flushes both FIFOs. Flushing while the DAI is active would
++ * cause FIFO underruns in other active substreams so we have to
++ * guard this behind the snd_soc_dai_active() check.
++ */
++ if (i2s->soc_info->shared_fifo_flush)
++ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
+
+ ret = clk_prepare_enable(i2s->clk_i2s);
+ if (ret)
+@@ -443,6 +471,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
+ static const struct i2s_soc_info jz4740_i2s_soc_info = {
+ .version = JZ_I2S_JZ4740,
+ .dai = &jz4740_i2s_dai,
++ .shared_fifo_flush = true,
+ };
+
+ static const struct i2s_soc_info jz4760_i2s_soc_info = {
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 09d1578f9d66f..1737c59e4ff67 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1963,7 +1963,7 @@ sub run_scp_mod {
+
+ sub _get_grub_index {
+
+- my ($command, $target, $skip) = @_;
++ my ($command, $target, $skip, $submenu) = @_;
+
+ return if (defined($grub_number) && defined($last_grub_menu) &&
+ $last_grub_menu eq $grub_menu && defined($last_machine) &&
+@@ -1980,11 +1980,16 @@ sub _get_grub_index {
+
+ my $found = 0;
+
++ my $submenu_number = 0;
++
+ while (<IN>) {
+ if (/$target/) {
+ $grub_number++;
+ $found = 1;
+ last;
++ } elsif (defined($submenu) && /$submenu/) {
++ $submenu_number++;
++ $grub_number = -1;
+ } elsif (/$skip/) {
+ $grub_number++;
+ }
+@@ -1993,6 +1998,9 @@ sub _get_grub_index {
+
+ dodie "Could not find '$grub_menu' through $command on $machine"
+ if (!$found);
++ if ($submenu_number > 0) {
++ $grub_number = "$submenu_number>$grub_number";
++ }
+ doprint "$grub_number\n";
+ $last_grub_menu = $grub_menu;
+ $last_machine = $machine;
+@@ -2003,6 +2011,7 @@ sub get_grub_index {
+ my $command;
+ my $target;
+ my $skip;
++ my $submenu;
+ my $grub_menu_qt;
+
+ if ($reboot_type !~ /^grub/) {
+@@ -2017,8 +2026,9 @@ sub get_grub_index {
+ $skip = '^\s*title\s';
+ } elsif ($reboot_type eq "grub2") {
+ $command = "cat $grub_file";
+- $target = '^menuentry.*' . $grub_menu_qt;
+- $skip = '^menuentry\s|^submenu\s';
++ $target = '^\s*menuentry.*' . $grub_menu_qt;
++ $skip = '^\s*menuentry';
++ $submenu = '^\s*submenu\s';
+ } elsif ($reboot_type eq "grub2bls") {
+ $command = $grub_bls_get;
+ $target = '^title=.*' . $grub_menu_qt;
+@@ -2027,7 +2037,7 @@ sub get_grub_index {
+ return;
+ }
+
+- _get_grub_index($command, $target, $skip);
++ _get_grub_index($command, $target, $skip, $submenu);
+ }
+
+ sub wait_for_input {
+@@ -2090,7 +2100,7 @@ sub reboot_to {
+ if ($reboot_type eq "grub") {
+ run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+ } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
+- run_ssh "$grub_reboot $grub_number";
++ run_ssh "$grub_reboot \"'$grub_number'\"";
+ } elsif ($reboot_type eq "syslinux") {
+ run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
+ } elsif (defined $reboot_script) {
+@@ -3768,9 +3778,10 @@ sub test_this_config {
+ # .config to make sure it is missing the config that
+ # we had before
+ my %configs = %min_configs;
+- delete $configs{$config};
++ $configs{$config} = "# $config is not set";
+ make_new_config ((values %configs), (values %keep_configs));
+ make_oldconfig;
++ delete $configs{$config};
+ undef %configs;
+ assign_configs \%configs, $output_config;
+
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index a3ea3d4a206d0..291144c284fbc 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -123,6 +123,11 @@ endef
+ clean:
+ $(CLEAN)
+
++# Enables to extend CFLAGS and LDFLAGS from command line, e.g.
++# make USERCFLAGS=-Werror USERLDFLAGS=-static
++CFLAGS += $(USERCFLAGS)
++LDFLAGS += $(USERLDFLAGS)
++
+ # When make O= with kselftest target from main level
+ # the following aren't defined.
+ #
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-12 12:17 Mike Pagano
0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-12 12:17 UTC (permalink / raw
To: gentoo-commits
commit: 319bd1afecafadce35585a733a6919e656db8780
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Jan 12 12:17:29 2023 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Jan 12 12:17:29 2023 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=319bd1af
Linux patch 6.0.19
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 6 +-
1018_linux-6.0.19.patch | 7559 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 7564 insertions(+), 1 deletion(-)
diff --git a/0000_README b/0000_README
index 569afe2e..ceb9effe 100644
--- a/0000_README
+++ b/0000_README
@@ -111,10 +111,14 @@ Patch: 1016_linux-6.0.17.patch
From: http://www.kernel.org
Desc: Linux 6.0.17
-Patch: 1017_linux-6.0.19.patch
+Patch: 1017_linux-6.0.18.patch
From: http://www.kernel.org
Desc: Linux 6.0.18
+Patch: 1018_linux-6.0.19.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.19
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1018_linux-6.0.19.patch b/1018_linux-6.0.19.patch
new file mode 100644
index 00000000..79b68f80
--- /dev/null
+++ b/1018_linux-6.0.19.patch
@@ -0,0 +1,7559 @@
+diff --git a/Makefile b/Makefile
+index 0104f69d30bbd..b978809a1c7cb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 18
++SUBLEVEL = 19
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index aecc403b28804..7f092cb55a417 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -128,15 +128,16 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
+ #define TIF_NEED_RESCHED 1 /* rescheduling necessary */
+ #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
+ #define TIF_UPROBE 3 /* breakpointed or singlestepping */
+-#define TIF_SYSCALL_TRACE 4 /* syscall trace active */
+-#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+-#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
+-#define TIF_SECCOMP 7 /* seccomp syscall filtering active */
+-#define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */
++#define TIF_NOTIFY_SIGNAL 4 /* signal notifications exist */
+
+ #define TIF_USING_IWMMXT 17
+ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+-#define TIF_RESTORE_SIGMASK 20
++#define TIF_RESTORE_SIGMASK 19
++#define TIF_SYSCALL_TRACE 20 /* syscall trace active */
++#define TIF_SYSCALL_AUDIT 21 /* syscall auditing active */
++#define TIF_SYSCALL_TRACEPOINT 22 /* syscall tracepoint instrumentation */
++#define TIF_SECCOMP 23 /* seccomp syscall filtering active */
++
+
+ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index 01c132bc33d54..4d06de77d92a6 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -64,7 +64,7 @@ void __init plat_mem_setup(void)
+ dtb = get_fdt();
+ __dt_setup_arch(dtb);
+
+- if (!early_init_dt_scan_memory())
++ if (early_init_dt_scan_memory())
+ return;
+
+ if (soc_info.mem_detect)
+diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
+index 855450bed9f52..ec0cab9fbddd0 100644
+--- a/arch/riscv/include/asm/uaccess.h
++++ b/arch/riscv/include/asm/uaccess.h
+@@ -165,7 +165,7 @@ do { \
+ might_fault(); \
+ access_ok(__p, sizeof(*__p)) ? \
+ __get_user((x), __p) : \
+- ((x) = 0, -EFAULT); \
++ ((x) = (__force __typeof__(x))0, -EFAULT); \
+ })
+
+ #define __put_user_asm(insn, x, ptr, err) \
+diff --git a/arch/riscv/kernel/probes/simulate-insn.h b/arch/riscv/kernel/probes/simulate-insn.h
+index cb6ff7dccb92e..de8474146a9b6 100644
+--- a/arch/riscv/kernel/probes/simulate-insn.h
++++ b/arch/riscv/kernel/probes/simulate-insn.h
+@@ -31,9 +31,9 @@ __RISCV_INSN_FUNCS(fence, 0x7f, 0x0f);
+ } while (0)
+
+ __RISCV_INSN_FUNCS(c_j, 0xe003, 0xa001);
+-__RISCV_INSN_FUNCS(c_jr, 0xf007, 0x8002);
++__RISCV_INSN_FUNCS(c_jr, 0xf07f, 0x8002);
+ __RISCV_INSN_FUNCS(c_jal, 0xe003, 0x2001);
+-__RISCV_INSN_FUNCS(c_jalr, 0xf007, 0x9002);
++__RISCV_INSN_FUNCS(c_jalr, 0xf07f, 0x9002);
+ __RISCV_INSN_FUNCS(c_beqz, 0xe003, 0xc001);
+ __RISCV_INSN_FUNCS(c_bnez, 0xe003, 0xe001);
+ __RISCV_INSN_FUNCS(c_ebreak, 0xffff, 0x9002);
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 06ad95ae78ceb..2d6915fe73856 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -1951,6 +1951,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
+ if (ctrl == PR_SPEC_FORCE_DISABLE)
+ task_set_spec_ib_force_disable(task);
+ task_update_spec_tif(task);
++ if (task == current)
++ indirect_branch_prediction_barrier();
+ break;
+ default:
+ return -ERANGE;
+diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
+index 9730c88530fc8..305514431f26e 100644
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
+ kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
+ kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+ ret = kexec_add_buffer(&kbuf);
+- if (ret) {
+- vfree((void *)image->elf_headers);
++ if (ret)
+ return ret;
+- }
+ image->elf_load_addr = kbuf.mem;
+ pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index ff04e9290715a..f46c87ef951df 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -300,6 +300,16 @@ static struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
+ *segs = nsegs;
+ return NULL;
+ split:
++ /*
++ * We can't sanely support splitting for a REQ_NOWAIT bio. End it
++ * with EAGAIN if splitting is required and return an error pointer.
++ */
++ if (bio->bi_opf & REQ_NOWAIT) {
++ bio->bi_status = BLK_STS_AGAIN;
++ bio_endio(bio);
++ return ERR_PTR(-EAGAIN);
++ }
++
+ *segs = nsegs;
+
+ /*
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index 31a8715d3a4d3..ebb5c846d8260 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1718,6 +1718,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
+ struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;
+ int ret = -EINVAL;
+
++ if (issue_flags & IO_URING_F_NONBLOCK)
++ return -EAGAIN;
++
+ ublk_ctrl_cmd_dump(cmd);
+
+ if (!(issue_flags & IO_URING_F_SQE128))
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index dd9a05174726b..53931fcef0d58 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -311,22 +311,35 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
+ virtqueue_notify(vq->vq);
+ }
+
++static blk_status_t virtblk_fail_to_queue(struct request *req, int rc)
++{
++ virtblk_cleanup_cmd(req);
++ switch (rc) {
++ case -ENOSPC:
++ return BLK_STS_DEV_RESOURCE;
++ case -ENOMEM:
++ return BLK_STS_RESOURCE;
++ default:
++ return BLK_STS_IOERR;
++ }
++}
++
+ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+ struct virtio_blk *vblk,
+ struct request *req,
+ struct virtblk_req *vbr)
+ {
+ blk_status_t status;
++ int num;
+
+ status = virtblk_setup_cmd(vblk->vdev, req, vbr);
+ if (unlikely(status))
+ return status;
+
+- vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+- if (unlikely(vbr->sg_table.nents < 0)) {
+- virtblk_cleanup_cmd(req);
+- return BLK_STS_RESOURCE;
+- }
++ num = virtblk_map_data(hctx, req, vbr);
++ if (unlikely(num < 0))
++ return virtblk_fail_to_queue(req, -ENOMEM);
++ vbr->sg_table.nents = num;
+
+ blk_mq_start_request(req);
+
+@@ -360,15 +373,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
+ blk_mq_stop_hw_queue(hctx);
+ spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
+ virtblk_unmap_data(req, vbr);
+- virtblk_cleanup_cmd(req);
+- switch (err) {
+- case -ENOSPC:
+- return BLK_STS_DEV_RESOURCE;
+- case -ENOMEM:
+- return BLK_STS_RESOURCE;
+- default:
+- return BLK_STS_IOERR;
+- }
++ return virtblk_fail_to_queue(req, err);
+ }
+
+ if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
+diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+index e553ccadbcbc8..e5876286828b8 100644
+--- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+@@ -239,7 +239,8 @@ static int virtio_crypto_alg_skcipher_close_session(
+ pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n",
+ ctrl_status->status, destroy_session->session_id);
+
+- return -EINVAL;
++ err = -EINVAL;
++ goto out;
+ }
+
+ err = 0;
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index a06decee51e06..a6e9968a2ddc0 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -608,7 +608,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+
+ seed = early_memremap(efi_rng_seed, sizeof(*seed));
+ if (seed != NULL) {
+- size = min(seed->size, EFI_RANDOM_SEED_SIZE);
++ size = min_t(u32, seed->size, SZ_1K); // sanity check
+ early_memunmap(seed, sizeof(*seed));
+ } else {
+ pr_err("Could not map UEFI random seed!\n");
+@@ -617,8 +617,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+ seed = early_memremap(efi_rng_seed,
+ sizeof(*seed) + size);
+ if (seed != NULL) {
+- pr_notice("seeding entropy pool\n");
+ add_bootloader_randomness(seed->bits, size);
++ memzero_explicit(seed->bits, size);
+ early_memunmap(seed, sizeof(*seed) + size);
+ } else {
+ pr_err("Could not map UEFI random seed!\n");
+diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
+index b0ae0a454404b..0ce2bf4b8b581 100644
+--- a/drivers/firmware/efi/libstub/efistub.h
++++ b/drivers/firmware/efi/libstub/efistub.h
+@@ -873,6 +873,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
+ efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
+ unsigned long *addr, unsigned long random_seed);
+
++efi_status_t efi_random_get_seed(void);
++
+ efi_status_t check_platform_features(void);
+
+ void *get_efi_config_table(efi_guid_t guid);
+diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
+index 33ab567695951..f85d2c0668777 100644
+--- a/drivers/firmware/efi/libstub/random.c
++++ b/drivers/firmware/efi/libstub/random.c
+@@ -67,27 +67,43 @@ efi_status_t efi_random_get_seed(void)
+ efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+ efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
+ efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
++ struct linux_efi_random_seed *prev_seed, *seed = NULL;
++ int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
+ efi_rng_protocol_t *rng = NULL;
+- struct linux_efi_random_seed *seed = NULL;
+ efi_status_t status;
+
+ status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
+ if (status != EFI_SUCCESS)
+ return status;
+
++ /*
++ * Check whether a seed was provided by a prior boot stage. In that
++ * case, instead of overwriting it, let's create a new buffer that can
++ * hold both, and concatenate the existing and the new seeds.
++ * Note that we should read the seed size with caution, in case the
++ * table got corrupted in memory somehow.
++ */
++ prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
++ if (prev_seed && prev_seed->size <= 512U) {
++ prev_seed_size = prev_seed->size;
++ seed_size += prev_seed_size;
++ }
++
+ /*
+ * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
+ * allocation will survive a kexec reboot (although we refresh the seed
+ * beforehand)
+ */
+ status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+- sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
++ struct_size(seed, bits, seed_size),
+ (void **)&seed);
+- if (status != EFI_SUCCESS)
+- return status;
++ if (status != EFI_SUCCESS) {
++ efi_warn("Failed to allocate memory for RNG seed.\n");
++ goto err_warn;
++ }
+
+ status = efi_call_proto(rng, get_rng, &rng_algo_raw,
+- EFI_RANDOM_SEED_SIZE, seed->bits);
++ EFI_RANDOM_SEED_SIZE, seed->bits);
+
+ if (status == EFI_UNSUPPORTED)
+ /*
+@@ -100,14 +116,28 @@ efi_status_t efi_random_get_seed(void)
+ if (status != EFI_SUCCESS)
+ goto err_freepool;
+
+- seed->size = EFI_RANDOM_SEED_SIZE;
++ seed->size = seed_size;
++ if (prev_seed_size)
++ memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits,
++ prev_seed_size);
++
+ status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
+ if (status != EFI_SUCCESS)
+ goto err_freepool;
+
++ if (prev_seed_size) {
++ /* wipe and free the old seed if we managed to install the new one */
++ memzero_explicit(prev_seed->bits, prev_seed_size);
++ efi_bs_call(free_pool, prev_seed);
++ }
+ return EFI_SUCCESS;
+
+ err_freepool:
++ memzero_explicit(seed, struct_size(seed, bits, seed_size));
+ efi_bs_call(free_pool, seed);
++ efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n");
++err_warn:
++ if (prev_seed)
++ efi_warn("Retaining bootloader-supplied seed only");
+ return status;
+ }
+diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
+index 238f3210970cf..bc5660f61c570 100644
+--- a/drivers/gpio/gpio-sifive.c
++++ b/drivers/gpio/gpio-sifive.c
+@@ -215,6 +215,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+ parent = irq_find_host(irq_parent);
++ of_node_put(irq_parent);
+ if (!parent) {
+ dev_err(dev, "no IRQ parent domain\n");
+ return -ENODEV;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index d597e2656c475..2fb7bf47f41ac 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -196,6 +196,7 @@ extern int amdgpu_emu_mode;
+ extern uint amdgpu_smu_memory_pool_size;
+ extern int amdgpu_smu_pptable_id;
+ extern uint amdgpu_dc_feature_mask;
++extern uint amdgpu_freesync_vid_mode;
+ extern uint amdgpu_dc_debug_mask;
+ extern uint amdgpu_dc_visual_confirm;
+ extern uint amdgpu_dm_abm_level;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+index 647220a8762dc..30f145dc8724e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+@@ -265,8 +265,10 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_
+ (&((struct amdgpu_fpriv *) \
+ ((struct drm_file *)(drm_priv))->driver_priv)->vm)
+
++int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
++ struct file *filp, u32 pasid);
+ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+- struct file *filp, u32 pasid,
++ struct file *filp,
+ void **process_info,
+ struct dma_fence **ef);
+ void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 6659630303a38..ba5a09c2b3ce6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1471,10 +1471,9 @@ static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
+ amdgpu_bo_unreserve(bo);
+ }
+
+-int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+- struct file *filp, u32 pasid,
+- void **process_info,
+- struct dma_fence **ef)
++int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
++ struct file *filp, u32 pasid)
++
+ {
+ struct amdgpu_fpriv *drv_priv;
+ struct amdgpu_vm *avm;
+@@ -1485,10 +1484,6 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+ return ret;
+ avm = &drv_priv->vm;
+
+- /* Already a compute VM? */
+- if (avm->process_info)
+- return -EINVAL;
+-
+ /* Free the original amdgpu allocated pasid,
+ * will be replaced with kfd allocated pasid.
+ */
+@@ -1497,14 +1492,36 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+ amdgpu_vm_set_pasid(adev, avm, 0);
+ }
+
+- /* Convert VM into a compute VM */
+- ret = amdgpu_vm_make_compute(adev, avm);
++ ret = amdgpu_vm_set_pasid(adev, avm, pasid);
+ if (ret)
+ return ret;
+
+- ret = amdgpu_vm_set_pasid(adev, avm, pasid);
++ return 0;
++}
++
++int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
++ struct file *filp,
++ void **process_info,
++ struct dma_fence **ef)
++{
++ struct amdgpu_fpriv *drv_priv;
++ struct amdgpu_vm *avm;
++ int ret;
++
++ ret = amdgpu_file_to_fpriv(filp, &drv_priv);
+ if (ret)
+ return ret;
++ avm = &drv_priv->vm;
++
++ /* Already a compute VM? */
++ if (avm->process_info)
++ return -EINVAL;
++
++ /* Convert VM into a compute VM */
++ ret = amdgpu_vm_make_compute(adev, avm);
++ if (ret)
++ return ret;
++
+ /* Initialize KFD part of the VM and process info */
+ ret = init_kfd_vm(avm, process_info, ef);
+ if (ret)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 379e65ea8afb1..adb369bb7295f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -177,6 +177,7 @@ int amdgpu_mes_kiq;
+ int amdgpu_noretry = -1;
+ int amdgpu_force_asic_type = -1;
+ int amdgpu_tmz = -1; /* auto */
++uint amdgpu_freesync_vid_mode;
+ int amdgpu_reset_method = -1; /* auto */
+ int amdgpu_num_kcq = -1;
+ int amdgpu_smartshift_bias;
+@@ -862,6 +863,32 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444);
+ MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
+ module_param_named(tmz, amdgpu_tmz, int, 0444);
+
++/**
++ * DOC: freesync_video (uint)
++ * Enable the optimization to adjust front porch timing to achieve seamless
++ * mode change experience when setting a freesync supported mode for which full
++ * modeset is not needed.
++ *
++ * The Display Core will add a set of modes derived from the base FreeSync
++ * video mode into the corresponding connector's mode list based on commonly
++ * used refresh rates and VRR range of the connected display, when users enable
++ * this feature. From the userspace perspective, they can see a seamless mode
++ * change experience when the change between different refresh rates under the
++ * same resolution. Additionally, userspace applications such as Video playback
++ * can read this modeset list and change the refresh rate based on the video
++ * frame rate. Finally, the userspace can also derive an appropriate mode for a
++ * particular refresh rate based on the FreeSync Mode and add it to the
++ * connector's mode list.
++ *
++ * Note: This is an experimental feature.
++ *
++ * The default value: 0 (off).
++ */
++MODULE_PARM_DESC(
++ freesync_video,
++ "Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
++module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
++
+ /**
+ * DOC: reset_method (int)
+ * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index bfe0fc258fc14..60ab2d952d5c5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -446,27 +446,24 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
+
+ /*
+ * If GTT is part of requested domains the check must succeed to
+- * allow fall back to GTT
++ * allow fall back to GTT.
+ */
+ if (domain & AMDGPU_GEM_DOMAIN_GTT) {
+ man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
+
+- if (size < man->size)
++ if (man && size < man->size)
+ return true;
+- else
+- goto fail;
+- }
+-
+- if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
++ else if (!man)
++ WARN_ON_ONCE("GTT domain requested but GTT mem manager uninitialized");
++ goto fail;
++ } else if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
+ man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
+
+- if (size < man->size)
++ if (man && size < man->size)
+ return true;
+- else
+- goto fail;
++ goto fail;
+ }
+
+-
+ /* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
+ return true;
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 6c83a519b3a1b..febf0e9f7af14 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -689,13 +689,13 @@ void kfd_process_destroy_wq(void)
+ }
+
+ static void kfd_process_free_gpuvm(struct kgd_mem *mem,
+- struct kfd_process_device *pdd, void *kptr)
++ struct kfd_process_device *pdd, void **kptr)
+ {
+ struct kfd_dev *dev = pdd->dev;
+
+- if (kptr) {
++ if (kptr && *kptr) {
+ amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(mem);
+- kptr = NULL;
++ *kptr = NULL;
+ }
+
+ amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv);
+@@ -795,7 +795,7 @@ static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd)
+ if (!qpd->ib_kaddr || !qpd->ib_base)
+ return;
+
+- kfd_process_free_gpuvm(qpd->ib_mem, pdd, qpd->ib_kaddr);
++ kfd_process_free_gpuvm(qpd->ib_mem, pdd, &qpd->ib_kaddr);
+ }
+
+ struct kfd_process *kfd_create_process(struct file *filep)
+@@ -1277,7 +1277,7 @@ static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd)
+ if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base)
+ return;
+
+- kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, qpd->cwsr_kaddr);
++ kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, &qpd->cwsr_kaddr);
+ }
+
+ void kfd_process_set_trap_handler(struct qcm_process_device *qpd,
+@@ -1581,9 +1581,9 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
+ p = pdd->process;
+ dev = pdd->dev;
+
+- ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(
+- dev->adev, drm_file, p->pasid,
+- &p->kgd_process_info, &p->ef);
++ ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, drm_file,
++ &p->kgd_process_info,
++ &p->ef);
+ if (ret) {
+ pr_err("Failed to create process VM object\n");
+ return ret;
+@@ -1598,13 +1598,19 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
+ if (ret)
+ goto err_init_cwsr;
+
++ ret = amdgpu_amdkfd_gpuvm_set_vm_pasid(dev->adev, drm_file, p->pasid);
++ if (ret)
++ goto err_set_pasid;
++
+ pdd->drm_file = drm_file;
+
+ return 0;
+
++err_set_pasid:
++ kfd_process_device_destroy_cwsr_dgpu(pdd);
+ err_init_cwsr:
++ kfd_process_device_destroy_ib_mem(pdd);
+ err_reserve_ib_mem:
+- kfd_process_device_free_bos(pdd);
+ pdd->drm_priv = NULL;
+
+ return ret;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+index 3f0a4a415907d..35a9b702508af 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+@@ -801,7 +801,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
+
+ p2plink->attr.name = "properties";
+ p2plink->attr.mode = KFD_SYSFS_FILE_MODE;
+- sysfs_attr_init(&iolink->attr);
++ sysfs_attr_init(&p2plink->attr);
+ ret = sysfs_create_file(p2plink->kobj, &p2plink->attr);
+ if (ret < 0)
+ return ret;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 895bbd20dd07a..68f2eb215e81c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5821,7 +5821,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+ */
+ DRM_DEBUG_DRIVER("No preferred mode found\n");
+ } else {
+- recalculate_timing = is_freesync_video_mode(&mode, aconnector);
++ recalculate_timing = amdgpu_freesync_vid_mode &&
++ is_freesync_video_mode(&mode, aconnector);
+ if (recalculate_timing) {
+ freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
+ drm_mode_copy(&saved_mode, &mode);
+@@ -6895,7 +6896,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
+ struct amdgpu_dm_connector *amdgpu_dm_connector =
+ to_amdgpu_dm_connector(connector);
+
+- if (!edid)
++ if (!(amdgpu_freesync_vid_mode && edid))
+ return;
+
+ if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
+@@ -8766,7 +8767,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ * TODO: Refactor this function to allow this check to work
+ * in all conditions.
+ */
+- if (dm_new_crtc_state->stream &&
++ if (amdgpu_freesync_vid_mode &&
++ dm_new_crtc_state->stream &&
+ is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
+ goto skip_modeset;
+
+@@ -8801,7 +8803,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ if (!dm_old_crtc_state->stream)
+ goto skip_modeset;
+
+- if (dm_new_crtc_state->stream &&
++ if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
+ is_timing_unchanged_for_freesync(new_crtc_state,
+ old_crtc_state)) {
+ new_crtc_state->mode_changed = false;
+@@ -8813,7 +8815,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ set_freesync_fixed_config(dm_new_crtc_state);
+
+ goto skip_modeset;
+- } else if (aconnector &&
++ } else if (amdgpu_freesync_vid_mode && aconnector &&
+ is_freesync_video_mode(&new_crtc_state->mode,
+ aconnector)) {
+ struct drm_display_mode *high_mode;
+diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c
+index 9f1c209d92511..e08ed0e9f1653 100644
+--- a/drivers/gpu/drm/i915/gvt/debugfs.c
++++ b/drivers/gpu/drm/i915/gvt/debugfs.c
+@@ -175,8 +175,13 @@ void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
+ */
+ void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
+ {
+- debugfs_remove_recursive(vgpu->debugfs);
+- vgpu->debugfs = NULL;
++ struct intel_gvt *gvt = vgpu->gvt;
++ struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++ if (minor->debugfs_root && gvt->debugfs_root) {
++ debugfs_remove_recursive(vgpu->debugfs);
++ vgpu->debugfs = NULL;
++ }
+ }
+
+ /**
+@@ -199,6 +204,10 @@ void intel_gvt_debugfs_init(struct intel_gvt *gvt)
+ */
+ void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
+ {
+- debugfs_remove_recursive(gvt->debugfs_root);
+- gvt->debugfs_root = NULL;
++ struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++ if (minor->debugfs_root) {
++ debugfs_remove_recursive(gvt->debugfs_root);
++ gvt->debugfs_root = NULL;
++ }
+ }
+diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
+index ce0eb03709c3f..80c60754a5c1c 100644
+--- a/drivers/gpu/drm/i915/gvt/gtt.c
++++ b/drivers/gpu/drm/i915/gvt/gtt.c
+@@ -1214,10 +1214,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
+ for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
+ ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
+ PAGE_SIZE, &dma_addr);
+- if (ret) {
+- ppgtt_invalidate_spt(spt);
+- return ret;
+- }
++ if (ret)
++ goto err;
+ sub_se.val64 = se->val64;
+
+ /* Copy the PAT field from PDE. */
+@@ -1236,6 +1234,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
+ ops->set_pfn(se, sub_spt->shadow_page.mfn);
+ ppgtt_set_shadow_entry(spt, se, index);
+ return 0;
++err:
++ /* Cancel the existing addess mappings of DMA addr. */
++ for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
++ gvt_vdbg_mm("invalidate 4K entry\n");
++ ppgtt_invalidate_pte(sub_spt, &sub_se);
++ }
++ /* Release the new allocated spt. */
++ trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
++ sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
++ ppgtt_free_spt(sub_spt);
++ return ret;
+ }
+
+ static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
+diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
+index d6fe94cd0fdb6..8342d95f56cbc 100644
+--- a/drivers/gpu/drm/i915/gvt/scheduler.c
++++ b/drivers/gpu/drm/i915/gvt/scheduler.c
+@@ -696,6 +696,7 @@ intel_vgpu_shadow_mm_pin(struct intel_vgpu_workload *workload)
+
+ if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT ||
+ !workload->shadow_mm->ppgtt_mm.shadowed) {
++ intel_vgpu_unpin_mm(workload->shadow_mm);
+ gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
+ return -EINVAL;
+ }
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index ea5f594955dfe..4b05f310071c0 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -615,6 +615,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ break;
+ }
+
++ if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG)
++ width = ipu_src_rect_width(new_state);
++ else
++ width = drm_rect_width(&new_state->src) >> 16;
++
+ eba = drm_plane_state_to_eba(new_state, 0);
+
+ /*
+@@ -623,8 +628,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ */
+ if (ipu_state->use_pre) {
+ axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
+- ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
+- ipu_src_rect_width(new_state),
++ ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width,
+ drm_rect_height(&new_state->src) >> 16,
+ fb->pitches[0], fb->format->format,
+ fb->modifier, &eba);
+@@ -679,9 +683,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ break;
+ }
+
+- ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
++ ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width);
+
+- width = ipu_src_rect_width(new_state);
+ height = drm_rect_height(&new_state->src) >> 16;
+ info = drm_format_info(fb->format->format);
+ ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+@@ -745,8 +748,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16);
+
+ ipu_cpmem_zero(ipu_plane->alpha_ch);
+- ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
+- ipu_src_rect_width(new_state),
++ ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width,
+ drm_rect_height(&new_state->src) >> 16);
+ ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
+ ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
+diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
+index d4b907889a21d..cd399b0b71814 100644
+--- a/drivers/gpu/drm/meson/meson_viu.c
++++ b/drivers/gpu/drm/meson/meson_viu.c
+@@ -436,15 +436,14 @@ void meson_viu_init(struct meson_drm *priv)
+
+ /* Initialize OSD1 fifo control register */
+ reg = VIU_OSD_DDR_PRIORITY_URGENT |
+- VIU_OSD_HOLD_FIFO_LINES(31) |
+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */
+
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
+- reg |= VIU_OSD_BURST_LENGTH_32;
++ reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
+ else
+- reg |= VIU_OSD_BURST_LENGTH_64;
++ reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));
+
+ writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
+ writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
+diff --git a/drivers/gpu/drm/mgag200/mgag200_pll.c b/drivers/gpu/drm/mgag200/mgag200_pll.c
+index 8065ca5d8de9a..4f55961848a84 100644
+--- a/drivers/gpu/drm/mgag200/mgag200_pll.c
++++ b/drivers/gpu/drm/mgag200/mgag200_pll.c
+@@ -269,7 +269,8 @@ static void mgag200_pixpll_update_g200se_04(struct mgag200_pll *pixpll,
+ pixpllcp = pixpllc->p - 1;
+ pixpllcs = pixpllc->s;
+
+- xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
++ // For G200SE A, BIT(7) should be set unconditionally.
++ xpixpllcm = BIT(7) | pixpllcm;
+ xpixpllcn = pixpllcn;
+ xpixpllcp = (pixpllcs << 3) | pixpllcp;
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
+index 2fa5afe212889..919e6cc049828 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
+@@ -82,6 +82,7 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ struct panfrost_gem_object *bo;
+ struct drm_panfrost_create_bo *args = data;
+ struct panfrost_gem_mapping *mapping;
++ int ret;
+
+ if (!args->size || args->pad ||
+ (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
+@@ -92,21 +93,29 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ !(args->flags & PANFROST_BO_NOEXEC))
+ return -EINVAL;
+
+- bo = panfrost_gem_create_with_handle(file, dev, args->size, args->flags,
+- &args->handle);
++ bo = panfrost_gem_create(dev, args->size, args->flags);
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
++ ret = drm_gem_handle_create(file, &bo->base.base, &args->handle);
++ if (ret)
++ goto out;
++
+ mapping = panfrost_gem_mapping_get(bo, priv);
+- if (!mapping) {
+- drm_gem_object_put(&bo->base.base);
+- return -EINVAL;
++ if (mapping) {
++ args->offset = mapping->mmnode.start << PAGE_SHIFT;
++ panfrost_gem_mapping_put(mapping);
++ } else {
++ /* This can only happen if the handle from
++ * drm_gem_handle_create() has already been guessed and freed
++ * by user space
++ */
++ ret = -EINVAL;
+ }
+
+- args->offset = mapping->mmnode.start << PAGE_SHIFT;
+- panfrost_gem_mapping_put(mapping);
+-
+- return 0;
++out:
++ drm_gem_object_put(&bo->base.base);
++ return ret;
+ }
+
+ /**
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
+index 293e799e2fe81..3c812fbd126fd 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
+@@ -235,12 +235,8 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
+ }
+
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+- struct drm_device *dev, size_t size,
+- u32 flags,
+- uint32_t *handle)
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
+ {
+- int ret;
+ struct drm_gem_shmem_object *shmem;
+ struct panfrost_gem_object *bo;
+
+@@ -256,16 +252,6 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv,
+ bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
+ bo->is_heap = !!(flags & PANFROST_BO_HEAP);
+
+- /*
+- * Allocate an id of idr table where the obj is registered
+- * and handle has the id what user can see.
+- */
+- ret = drm_gem_handle_create(file_priv, &shmem->base, handle);
+- /* drop reference from allocate - handle holds it now. */
+- drm_gem_object_put(&shmem->base);
+- if (ret)
+- return ERR_PTR(ret);
+-
+ return bo;
+ }
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
+index 8088d5fd8480e..ad2877eeeccdf 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
+@@ -69,10 +69,7 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev,
+ struct sg_table *sgt);
+
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+- struct drm_device *dev, size_t size,
+- u32 flags,
+- uint32_t *handle);
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags);
+
+ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
+ void panfrost_gem_close(struct drm_gem_object *obj,
+diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c
+index 945758f395236..3e1272695d993 100644
+--- a/drivers/infiniband/hw/mlx5/counters.c
++++ b/drivers/infiniband/hw/mlx5/counters.c
+@@ -278,7 +278,6 @@ static int do_get_hw_stats(struct ib_device *ibdev,
+ const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
+ struct mlx5_core_dev *mdev;
+ int ret, num_counters;
+- u32 mdev_port_num;
+
+ if (!stats)
+ return -EINVAL;
+@@ -299,8 +298,9 @@ static int do_get_hw_stats(struct ib_device *ibdev,
+ }
+
+ if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
+- mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
+- &mdev_port_num);
++ if (!port_num)
++ port_num = 1;
++ mdev = mlx5_ib_get_native_port_mdev(dev, port_num, NULL);
+ if (!mdev) {
+ /* If port is not affiliated yet, its in down state
+ * which doesn't have any counters yet, so it would be
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 40d9410ec3033..cf953d23d18da 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4502,6 +4502,40 @@ static bool mlx5_ib_modify_qp_allowed(struct mlx5_ib_dev *dev,
+ return false;
+ }
+
++static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr,
++ int attr_mask, enum ib_qp_type qp_type)
++{
++ int log_max_ra_res;
++ int log_max_ra_req;
++
++ if (qp_type == MLX5_IB_QPT_DCI) {
++ log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_res_dc);
++ log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_req_dc);
++ } else {
++ log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_res_qp);
++ log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++ log_max_ra_req_qp);
++ }
++
++ if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
++ attr->max_rd_atomic > log_max_ra_res) {
++ mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
++ attr->max_rd_atomic);
++ return false;
++ }
++
++ if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
++ attr->max_dest_rd_atomic > log_max_ra_req) {
++ mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
++ attr->max_dest_rd_atomic);
++ return false;
++ }
++ return true;
++}
++
+ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+ {
+@@ -4589,21 +4623,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ goto out;
+ }
+
+- if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+- attr->max_rd_atomic >
+- (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_res_qp))) {
+- mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
+- attr->max_rd_atomic);
+- goto out;
+- }
+-
+- if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+- attr->max_dest_rd_atomic >
+- (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_req_qp))) {
+- mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
+- attr->max_dest_rd_atomic);
++ if (!validate_rd_atomic(dev, attr, attr_mask, qp_type))
+ goto out;
+- }
+
+ if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+ err = 0;
+diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
+index e58a1e0cadd2e..9270977e6c7ff 100644
+--- a/drivers/net/bonding/bond_3ad.c
++++ b/drivers/net/bonding/bond_3ad.c
+@@ -1540,6 +1540,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)
+ slave_err(bond->dev, port->slave->dev,
+ "Port %d did not find a suitable aggregator\n",
+ port->actor_port_number);
++ return;
+ }
+ }
+ /* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 771f2a533d3f6..7807113e09100 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2653,10 +2653,12 @@ static void bond_miimon_link_change(struct bonding *bond,
+
+ static void bond_miimon_commit(struct bonding *bond)
+ {
+- struct slave *slave, *primary;
++ struct slave *slave, *primary, *active;
+ bool do_failover = false;
+ struct list_head *iter;
+
++ ASSERT_RTNL();
++
+ bond_for_each_slave(bond, slave, iter) {
+ switch (slave->link_new_state) {
+ case BOND_LINK_NOCHANGE:
+@@ -2699,8 +2701,8 @@ static void bond_miimon_commit(struct bonding *bond)
+
+ bond_miimon_link_change(bond, slave, BOND_LINK_UP);
+
+- if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
+- slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
++ active = rtnl_dereference(bond->curr_active_slave);
++ if (!active || slave == primary || slave->prio > active->prio)
+ do_failover = true;
+
+ continue;
+diff --git a/drivers/net/dsa/mv88e6xxx/Kconfig b/drivers/net/dsa/mv88e6xxx/Kconfig
+index 7a2445a34eb77..e3181d5471dfe 100644
+--- a/drivers/net/dsa/mv88e6xxx/Kconfig
++++ b/drivers/net/dsa/mv88e6xxx/Kconfig
+@@ -2,7 +2,6 @@
+ config NET_DSA_MV88E6XXX
+ tristate "Marvell 88E6xxx Ethernet switch fabric support"
+ depends on NET_DSA
+- depends on PTP_1588_CLOCK_OPTIONAL
+ select IRQ_DOMAIN
+ select NET_DSA_TAG_EDSA
+ select NET_DSA_TAG_DSA
+@@ -13,7 +12,8 @@ config NET_DSA_MV88E6XXX
+ config NET_DSA_MV88E6XXX_PTP
+ bool "PTP support for Marvell 88E6xxx"
+ default n
+- depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK
++ depends on (NET_DSA_MV88E6XXX = y && PTP_1588_CLOCK = y) || \
++ (NET_DSA_MV88E6XXX = m && PTP_1588_CLOCK)
+ help
+ Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
+ chips that support it.
+diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
+index 300c9345ee2be..3587f75807d0d 100644
+--- a/drivers/net/dsa/qca/qca8k-8xxx.c
++++ b/drivers/net/dsa/qca/qca8k-8xxx.c
+@@ -36,44 +36,6 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
+ *page = regaddr & 0x3ff;
+ }
+
+-static int
+-qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
+-{
+- u16 *cached_lo = &priv->mdio_cache.lo;
+- struct mii_bus *bus = priv->bus;
+- int ret;
+-
+- if (lo == *cached_lo)
+- return 0;
+-
+- ret = bus->write(bus, phy_id, regnum, lo);
+- if (ret < 0)
+- dev_err_ratelimited(&bus->dev,
+- "failed to write qca8k 32bit lo register\n");
+-
+- *cached_lo = lo;
+- return 0;
+-}
+-
+-static int
+-qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
+-{
+- u16 *cached_hi = &priv->mdio_cache.hi;
+- struct mii_bus *bus = priv->bus;
+- int ret;
+-
+- if (hi == *cached_hi)
+- return 0;
+-
+- ret = bus->write(bus, phy_id, regnum, hi);
+- if (ret < 0)
+- dev_err_ratelimited(&bus->dev,
+- "failed to write qca8k 32bit hi register\n");
+-
+- *cached_hi = hi;
+- return 0;
+-}
+-
+ static int
+ qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
+ {
+@@ -97,7 +59,7 @@ qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
+ }
+
+ static void
+-qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
++qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
+ {
+ u16 lo, hi;
+ int ret;
+@@ -105,9 +67,12 @@ qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
+ lo = val & 0xffff;
+ hi = (u16)(val >> 16);
+
+- ret = qca8k_set_lo(priv, phy_id, regnum, lo);
++ ret = bus->write(bus, phy_id, regnum, lo);
+ if (ret >= 0)
+- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
++ ret = bus->write(bus, phy_id, regnum + 1, hi);
++ if (ret < 0)
++ dev_err_ratelimited(&bus->dev,
++ "failed to write qca8k 32bit register\n");
+ }
+
+ static int
+@@ -146,7 +111,16 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
+
+ command = get_unaligned_le32(&mgmt_ethhdr->command);
+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
++
+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
++ /* Special case for len of 15 as this is the max value for len and needs to
++ * be increased before converting it from word to dword.
++ */
++ if (len == 15)
++ len++;
++
++ /* We can ignore odd value, we always round up them in the alloc function. */
++ len *= sizeof(u16);
+
+ /* Make sure the seq match the requested packet */
+ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
+@@ -193,17 +167,33 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ if (!skb)
+ return NULL;
+
+- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
+- * Actually for some reason the steps are:
+- * 0: nothing
+- * 1-4: first 4 byte
+- * 5-6: first 12 byte
+- * 7-15: all 16 byte
++ /* Hdr mgmt length value is in step of word size.
++ * As an example to process 4 byte of data the correct length to set is 2.
++ * To process 8 byte 4, 12 byte 6, 16 byte 8...
++ *
++ * Odd values will always return the next size on the ack packet.
++ * (length of 3 (6 byte) will always return 8 bytes of data)
++ *
++ * This means that a value of 15 (0xf) actually means reading/writing 32 bytes
++ * of data.
++ *
++ * To correctly calculate the length we devide the requested len by word and
++ * round up.
++ * On the ack function we can skip the odd check as we already handle the
++ * case here.
++ */
++ real_len = DIV_ROUND_UP(len, sizeof(u16));
++
++ /* We check if the result len is odd and we round up another time to
++ * the next size. (length of 3 will be increased to 4 as switch will always
++ * return 8 bytes)
+ */
+- if (len == 16)
+- real_len = 15;
+- else
+- real_len = len;
++ if (real_len % sizeof(u16) != 0)
++ real_len++;
++
++ /* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */
++ if (real_len == 16)
++ real_len--;
+
+ skb_reset_mac_header(skb);
+ skb_set_network_header(skb, skb->len);
+@@ -417,7 +407,7 @@ qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
+ if (ret < 0)
+ goto exit;
+
+- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+
+ exit:
+ mutex_unlock(&bus->mdio_lock);
+@@ -450,7 +440,7 @@ qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_
+
+ val &= ~mask;
+ val |= write_val;
+- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+
+ exit:
+ mutex_unlock(&bus->mdio_lock);
+@@ -725,14 +715,14 @@ qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
+ if (ret)
+ goto exit;
+
+- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+
+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+ QCA8K_MDIO_MASTER_BUSY);
+
+ exit:
+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
+- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+
+ mutex_unlock(&bus->mdio_lock);
+
+@@ -762,7 +752,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
+ if (ret)
+ goto exit;
+
+- qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+
+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+ QCA8K_MDIO_MASTER_BUSY);
+@@ -773,7 +763,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
+
+ exit:
+ /* even if the busy_wait timeouts try to clear the MASTER_EN */
+- qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
++ qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+
+ mutex_unlock(&bus->mdio_lock);
+
+@@ -1943,8 +1933,6 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
+ }
+
+ priv->mdio_cache.page = 0xffff;
+- priv->mdio_cache.lo = 0xffff;
+- priv->mdio_cache.hi = 0xffff;
+
+ /* Check the detected switch id */
+ ret = qca8k_read_switch_id(priv);
+diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
+index e36ecc9777f43..342e9d945dfbb 100644
+--- a/drivers/net/dsa/qca/qca8k.h
++++ b/drivers/net/dsa/qca/qca8k.h
+@@ -375,11 +375,6 @@ struct qca8k_mdio_cache {
+ * mdio writes
+ */
+ u16 page;
+-/* lo and hi can also be cached and from Documentation we can skip one
+- * extra mdio write if lo or hi is didn't change.
+- */
+- u16 lo;
+- u16 hi;
+ };
+
+ struct qca8k_pcs {
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index 8c8b4c88c7dea..451c3a1b62553 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2400,29 +2400,18 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
+ return -EOPNOTSUPP;
+ }
+
+- switch (func) {
+- case ENA_ADMIN_TOEPLITZ:
+- if (key) {
+- if (key_len != sizeof(hash_key->key)) {
+- netdev_err(ena_dev->net_device,
+- "key len (%u) doesn't equal the supported size (%zu)\n",
+- key_len, sizeof(hash_key->key));
+- return -EINVAL;
+- }
+- memcpy(hash_key->key, key, key_len);
+- rss->hash_init_val = init_val;
+- hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
++ if ((func == ENA_ADMIN_TOEPLITZ) && key) {
++ if (key_len != sizeof(hash_key->key)) {
++ netdev_err(ena_dev->net_device,
++ "key len (%u) doesn't equal the supported size (%zu)\n",
++ key_len, sizeof(hash_key->key));
++ return -EINVAL;
+ }
+- break;
+- case ENA_ADMIN_CRC32:
+- rss->hash_init_val = init_val;
+- break;
+- default:
+- netdev_err(ena_dev->net_device, "Invalid hash function (%d)\n",
+- func);
+- return -EINVAL;
++ memcpy(hash_key->key, key, key_len);
++ hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
+ }
+
++ rss->hash_init_val = init_val;
+ old_func = rss->hash_func;
+ rss->hash_func = func;
+ rc = ena_com_set_hash_function(ena_dev);
+diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+index 39242c5a17290..108506721bcfd 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -887,11 +887,7 @@ static int ena_set_tunable(struct net_device *netdev,
+ switch (tuna->id) {
+ case ETHTOOL_RX_COPYBREAK:
+ len = *(u32 *)data;
+- if (len > adapter->netdev->mtu) {
+- ret = -EINVAL;
+- break;
+- }
+- adapter->rx_copybreak = len;
++ ret = ena_set_rx_copybreak(adapter, len);
+ break;
+ default:
+ ret = -EINVAL;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 41c8213484769..413714f373ffd 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -374,9 +374,9 @@ static int ena_xdp_xmit(struct net_device *dev, int n,
+
+ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ {
++ u32 verdict = ENA_XDP_PASS;
+ struct bpf_prog *xdp_prog;
+ struct ena_ring *xdp_ring;
+- u32 verdict = XDP_PASS;
+ struct xdp_frame *xdpf;
+ u64 *xdp_stat;
+
+@@ -393,7 +393,7 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ if (unlikely(!xdpf)) {
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+- verdict = XDP_ABORTED;
++ verdict = ENA_XDP_DROP;
+ break;
+ }
+
+@@ -409,29 +409,35 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+
+ spin_unlock(&xdp_ring->xdp_tx_lock);
+ xdp_stat = &rx_ring->rx_stats.xdp_tx;
++ verdict = ENA_XDP_TX;
+ break;
+ case XDP_REDIRECT:
+ if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
+ xdp_stat = &rx_ring->rx_stats.xdp_redirect;
++ verdict = ENA_XDP_REDIRECT;
+ break;
+ }
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+- verdict = XDP_ABORTED;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_ABORTED:
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_aborted;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_DROP:
+ xdp_stat = &rx_ring->rx_stats.xdp_drop;
++ verdict = ENA_XDP_DROP;
+ break;
+ case XDP_PASS:
+ xdp_stat = &rx_ring->rx_stats.xdp_pass;
++ verdict = ENA_XDP_PASS;
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict);
+ xdp_stat = &rx_ring->rx_stats.xdp_invalid;
++ verdict = ENA_XDP_DROP;
+ }
+
+ ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
+@@ -512,16 +518,18 @@ static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
+ struct bpf_prog *prog,
+ int first, int count)
+ {
++ struct bpf_prog *old_bpf_prog;
+ struct ena_ring *rx_ring;
+ int i = 0;
+
+ for (i = first; i < count; i++) {
+ rx_ring = &adapter->rx_ring[i];
+- xchg(&rx_ring->xdp_bpf_prog, prog);
+- if (prog) {
++ old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
++
++ if (!old_bpf_prog && prog) {
+ ena_xdp_register_rxq_info(rx_ring);
+ rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
+- } else {
++ } else if (old_bpf_prog && !prog) {
+ ena_xdp_unregister_rxq_info(rx_ring);
+ rx_ring->rx_headroom = NET_SKB_PAD;
+ }
+@@ -672,6 +680,7 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
+ ring->ena_dev = adapter->ena_dev;
+ ring->per_napi_packets = 0;
+ ring->cpu = 0;
++ ring->numa_node = 0;
+ ring->no_interrupt_event_cnt = 0;
+ u64_stats_init(&ring->syncp);
+ }
+@@ -775,6 +784,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+ tx_ring->cpu = ena_irq->cpu;
++ tx_ring->numa_node = node;
+ return 0;
+
+ err_push_buf_intermediate_buf:
+@@ -907,6 +917,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+ rx_ring->cpu = ena_irq->cpu;
++ rx_ring->numa_node = node;
+
+ return 0;
+ }
+@@ -1619,12 +1630,12 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ * we expect, then we simply drop it
+ */
+ if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU))
+- return XDP_DROP;
++ return ENA_XDP_DROP;
+
+ ret = ena_xdp_execute(rx_ring, xdp);
+
+ /* The xdp program might expand the headers */
+- if (ret == XDP_PASS) {
++ if (ret == ENA_XDP_PASS) {
+ rx_info->page_offset = xdp->data - xdp->data_hard_start;
+ rx_ring->ena_bufs[0].len = xdp->data_end - xdp->data;
+ }
+@@ -1663,7 +1674,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ xdp_init_buff(&xdp, ENA_PAGE_SIZE, &rx_ring->xdp_rxq);
+
+ do {
+- xdp_verdict = XDP_PASS;
++ xdp_verdict = ENA_XDP_PASS;
+ skb = NULL;
+ ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
+ ena_rx_ctx.max_bufs = rx_ring->sgl_size;
+@@ -1691,7 +1702,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp);
+
+ /* allocate skb and fill it */
+- if (xdp_verdict == XDP_PASS)
++ if (xdp_verdict == ENA_XDP_PASS)
+ skb = ena_rx_skb(rx_ring,
+ rx_ring->ena_bufs,
+ ena_rx_ctx.descs,
+@@ -1709,14 +1720,15 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ /* Packets was passed for transmission, unmap it
+ * from RX side.
+ */
+- if (xdp_verdict == XDP_TX || xdp_verdict == XDP_REDIRECT) {
++ if (xdp_verdict & ENA_XDP_FORWARDED) {
+ ena_unmap_rx_buff(rx_ring,
+ &rx_ring->rx_buffer_info[req_id]);
+ rx_ring->rx_buffer_info[req_id].page = NULL;
+ }
+ }
+- if (xdp_verdict != XDP_PASS) {
++ if (xdp_verdict != ENA_XDP_PASS) {
+ xdp_flags |= xdp_verdict;
++ total_len += ena_rx_ctx.ena_bufs[0].len;
+ res_budget--;
+ continue;
+ }
+@@ -1760,7 +1772,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ ena_refill_rx_bufs(rx_ring, refill_required);
+ }
+
+- if (xdp_flags & XDP_REDIRECT)
++ if (xdp_flags & ENA_XDP_REDIRECT)
+ xdp_do_flush_map();
+
+ return work_done;
+@@ -1814,8 +1826,9 @@ static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
+ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
+ {
++ u32 rx_interval = tx_ring->smoothed_interval;
+ struct ena_eth_io_intr_reg intr_reg;
+- u32 rx_interval = 0;
++
+ /* Rx ring can be NULL when for XDP tx queues which don't have an
+ * accompanying rx_ring pair.
+ */
+@@ -1853,20 +1866,27 @@ static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ if (likely(tx_ring->cpu == cpu))
+ goto out;
+
++ tx_ring->cpu = cpu;
++ if (rx_ring)
++ rx_ring->cpu = cpu;
++
+ numa_node = cpu_to_node(cpu);
++
++ if (likely(tx_ring->numa_node == numa_node))
++ goto out;
++
+ put_cpu();
+
+ if (numa_node != NUMA_NO_NODE) {
+ ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node);
+- if (rx_ring)
++ tx_ring->numa_node = numa_node;
++ if (rx_ring) {
++ rx_ring->numa_node = numa_node;
+ ena_com_update_numa_node(rx_ring->ena_com_io_cq,
+ numa_node);
++ }
+ }
+
+- tx_ring->cpu = cpu;
+- if (rx_ring)
+- rx_ring->cpu = cpu;
+-
+ return;
+ out:
+ put_cpu();
+@@ -1987,11 +2007,10 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
+ if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
+ ena_adjust_adaptive_rx_intr_moderation(ena_napi);
+
++ ena_update_ring_numa_node(tx_ring, rx_ring);
+ ena_unmask_interrupt(tx_ring, rx_ring);
+ }
+
+- ena_update_ring_numa_node(tx_ring, rx_ring);
+-
+ ret = rx_work_done;
+ } else {
+ ret = budget;
+@@ -2378,7 +2397,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
+ ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+ ctx.msix_vector = msix_vector;
+ ctx.queue_size = tx_ring->ring_size;
+- ctx.numa_node = cpu_to_node(tx_ring->cpu);
++ ctx.numa_node = tx_ring->numa_node;
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+ if (rc) {
+@@ -2446,7 +2465,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
+ ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ ctx.msix_vector = msix_vector;
+ ctx.queue_size = rx_ring->ring_size;
+- ctx.numa_node = cpu_to_node(rx_ring->cpu);
++ ctx.numa_node = rx_ring->numa_node;
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+ if (rc) {
+@@ -2807,6 +2826,24 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+ return dev_was_up ? ena_up(adapter) : 0;
+ }
+
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak)
++{
++ struct ena_ring *rx_ring;
++ int i;
++
++ if (rx_copybreak > min_t(u16, adapter->netdev->mtu, ENA_PAGE_SIZE))
++ return -EINVAL;
++
++ adapter->rx_copybreak = rx_copybreak;
++
++ for (i = 0; i < adapter->num_io_queues; i++) {
++ rx_ring = &adapter->rx_ring[i];
++ rx_ring->rx_copybreak = rx_copybreak;
++ }
++
++ return 0;
++}
++
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
+ {
+ struct ena_com_dev *ena_dev = adapter->ena_dev;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+index 1bdce99bf6888..2cb141079474c 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -262,9 +262,11 @@ struct ena_ring {
+ bool disable_meta_caching;
+ u16 no_interrupt_event_cnt;
+
+- /* cpu for TPH */
++ /* cpu and NUMA for TPH */
+ int cpu;
+- /* number of tx/rx_buffer_info's entries */
++ int numa_node;
++
++ /* number of tx/rx_buffer_info's entries */
+ int ring_size;
+
+ enum ena_admin_placement_policy_type tx_mem_queue_type;
+@@ -392,6 +394,8 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count);
+
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak);
++
+ int ena_get_sset_count(struct net_device *netdev, int sset);
+
+ static inline void ena_reset_device(struct ena_adapter *adapter,
+@@ -409,6 +413,15 @@ enum ena_xdp_errors_t {
+ ENA_XDP_NO_ENOUGH_QUEUES,
+ };
+
++enum ENA_XDP_ACTIONS {
++ ENA_XDP_PASS = 0,
++ ENA_XDP_TX = BIT(0),
++ ENA_XDP_REDIRECT = BIT(1),
++ ENA_XDP_DROP = BIT(2)
++};
++
++#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
++
+ static inline bool ena_xdp_present(struct ena_adapter *adapter)
+ {
+ return !!adapter->xdp_bpf_prog;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+index f342bb8531891..2ee2cd4a1e356 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+@@ -1064,6 +1064,9 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
+
+ devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
+
++ tasklet_kill(&pdata->tasklet_dev);
++ tasklet_kill(&pdata->tasklet_ecc);
++
+ if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
+ devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+index 22d4fc547a0a3..a9ccc4258ee50 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+@@ -447,8 +447,10 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
+ xgbe_i2c_disable(pdata);
+ xgbe_i2c_clear_all_interrupts(pdata);
+
+- if (pdata->dev_irq != pdata->i2c_irq)
++ if (pdata->dev_irq != pdata->i2c_irq) {
+ devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
++ tasklet_kill(&pdata->tasklet_i2c);
++ }
+ }
+
+ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 4e97b48695220..0c5c1b1556830 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -1390,8 +1390,10 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
+ /* Disable auto-negotiation */
+ xgbe_an_disable_all(pdata);
+
+- if (pdata->dev_irq != pdata->an_irq)
++ if (pdata->dev_irq != pdata->an_irq) {
+ devm_free_irq(pdata->dev, pdata->an_irq, pdata);
++ tasklet_kill(&pdata->tasklet_an);
++ }
+
+ pdata->phy_if.phy_impl.stop(pdata);
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 57cabe20aa122..1b38295254e26 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -988,8 +988,7 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
+ dma_addr -= bp->rx_dma_offset;
+ dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
+ DMA_ATTR_WEAK_ORDERING);
+- skb = build_skb(page_address(page), BNXT_PAGE_MODE_BUF_SIZE +
+- bp->rx_dma_offset);
++ skb = build_skb(page_address(page), PAGE_SIZE);
+ if (!skb) {
+ __free_page(page);
+ return NULL;
+@@ -1922,7 +1921,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ dma_addr = rx_buf->mapping;
+
+ if (bnxt_xdp_attached(bp, rxr)) {
+- bnxt_xdp_buff_init(bp, rxr, cons, &data_ptr, &len, &xdp);
++ bnxt_xdp_buff_init(bp, rxr, cons, data_ptr, len, &xdp);
+ if (agg_bufs) {
+ u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp,
+ cp_cons, agg_bufs,
+@@ -1937,7 +1936,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ }
+
+ if (xdp_active) {
+- if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &len, event)) {
++ if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &data_ptr, &len, event)) {
+ rc = 1;
+ goto next_rx;
+ }
+@@ -3966,8 +3965,10 @@ void bnxt_set_ring_params(struct bnxt *bp)
+ bp->rx_agg_ring_mask = (bp->rx_agg_nr_pages * RX_DESC_CNT) - 1;
+
+ if (BNXT_RX_PAGE_MODE(bp)) {
+- rx_space = BNXT_PAGE_MODE_BUF_SIZE;
+- rx_size = BNXT_MAX_PAGE_MODE_MTU;
++ rx_space = PAGE_SIZE;
++ rx_size = PAGE_SIZE -
++ ALIGN(max(NET_SKB_PAD, XDP_PACKET_HEADROOM), 8) -
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ } else {
+ rx_size = SKB_DATA_ALIGN(BNXT_RX_COPY_THRESH + NET_IP_ALIGN);
+ rx_space = rx_size + NET_SKB_PAD +
+@@ -5370,15 +5371,16 @@ static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, u16 vnic_id)
+ req->flags = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_JUMBO_PLACEMENT);
+ req->enables = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_JUMBO_THRESH_VALID);
+
+- if (BNXT_RX_PAGE_MODE(bp) && !BNXT_RX_JUMBO_MODE(bp)) {
++ if (BNXT_RX_PAGE_MODE(bp)) {
++ req->jumbo_thresh = cpu_to_le16(bp->rx_buf_use_size);
++ } else {
+ req->flags |= cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV4 |
+ VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV6);
+ req->enables |=
+ cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_HDS_THRESHOLD_VALID);
++ req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
++ req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
+ }
+- /* thresholds not implemented in firmware yet */
+- req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
+- req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
+ req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
+ return hwrm_req_send(bp, req);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index d5fa43cfe5248..02741d499bf4a 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -591,12 +591,20 @@ struct nqe_cn {
+ #define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT)
+
+ #define BNXT_MAX_MTU 9500
+-#define BNXT_PAGE_MODE_BUF_SIZE \
++
++/* First RX buffer page in XDP multi-buf mode
++ *
++ * +-------------------------------------------------------------------------+
++ * | XDP_PACKET_HEADROOM | bp->rx_buf_use_size | skb_shared_info|
++ * | (bp->rx_dma_offset) | | |
++ * +-------------------------------------------------------------------------+
++ */
++#define BNXT_MAX_PAGE_MODE_MTU_SBUF \
+ ((unsigned int)PAGE_SIZE - VLAN_ETH_HLEN - NET_IP_ALIGN - \
+ XDP_PACKET_HEADROOM)
+ #define BNXT_MAX_PAGE_MODE_MTU \
+- BNXT_PAGE_MODE_BUF_SIZE - \
+- SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info))
++ (BNXT_MAX_PAGE_MODE_MTU_SBUF - \
++ SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info)))
+
+ #define BNXT_MIN_PKT_SIZE 52
+
+@@ -2131,7 +2139,6 @@ struct bnxt {
+ #define BNXT_DUMP_CRASH 1
+
+ struct bpf_prog *xdp_prog;
+- u8 xdp_has_frags;
+
+ struct bnxt_ptp_cfg *ptp_cfg;
+ u8 ptp_all_rx_tstamp;
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index c3065ec0a4798..36d5202c0aeec 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -177,7 +177,7 @@ bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
+ }
+
+ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+- u16 cons, u8 **data_ptr, unsigned int *len,
++ u16 cons, u8 *data_ptr, unsigned int len,
+ struct xdp_buff *xdp)
+ {
+ struct bnxt_sw_rx_bd *rx_buf;
+@@ -191,13 +191,10 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+ offset = bp->rx_offset;
+
+ mapping = rx_buf->mapping - bp->rx_dma_offset;
+- dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
+-
+- if (bp->xdp_has_frags)
+- buflen = BNXT_PAGE_MODE_BUF_SIZE + offset;
++ dma_sync_single_for_cpu(&pdev->dev, mapping + offset, len, bp->rx_dir);
+
+ xdp_init_buff(xdp, buflen, &rxr->xdp_rxq);
+- xdp_prepare_buff(xdp, *data_ptr - offset, offset, *len, false);
++ xdp_prepare_buff(xdp, data_ptr - offset, offset, len, false);
+ }
+
+ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+@@ -222,7 +219,8 @@ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+ * false - packet should be passed to the stack.
+ */
+ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+- struct xdp_buff xdp, struct page *page, unsigned int *len, u8 *event)
++ struct xdp_buff xdp, struct page *page, u8 **data_ptr,
++ unsigned int *len, u8 *event)
+ {
+ struct bpf_prog *xdp_prog = READ_ONCE(rxr->xdp_prog);
+ struct bnxt_tx_ring_info *txr;
+@@ -255,8 +253,10 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+ *event &= ~BNXT_RX_EVENT;
+
+ *len = xdp.data_end - xdp.data;
+- if (orig_data != xdp.data)
++ if (orig_data != xdp.data) {
+ offset = xdp.data - xdp.data_hard_start;
++ *data_ptr = xdp.data_hard_start + offset;
++ }
+
+ switch (act) {
+ case XDP_PASS:
+@@ -401,10 +401,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
+ netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n");
+ return -EOPNOTSUPP;
+ }
+- if (prog) {
++ if (prog)
+ tx_xdp = bp->rx_nr_rings;
+- bp->xdp_has_frags = prog->aux->xdp_has_frags;
+- }
+
+ tc = netdev_get_num_tc(dev);
+ if (!tc)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+index 505911ae095d3..ea430d6961df3 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+@@ -18,8 +18,8 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
+ struct xdp_buff *xdp);
+ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
+ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+- struct xdp_buff xdp, struct page *page, unsigned int *len,
+- u8 *event);
++ struct xdp_buff xdp, struct page *page, u8 **data_ptr,
++ unsigned int *len, u8 *event);
+ int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp);
+ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ struct xdp_frame **frames, u32 flags);
+@@ -27,7 +27,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr);
+
+ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+- u16 cons, u8 **data_ptr, unsigned int *len,
++ u16 cons, u8 *data_ptr, unsigned int len,
+ struct xdp_buff *xdp);
+ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+ struct xdp_buff *xdp);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+index 7d4ae467f3ad4..abcd7877f7d2a 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+@@ -233,6 +233,17 @@ struct hclgevf_mbx_arq_ring {
+ __le16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
+ };
+
++struct hclge_dev;
++
++#define HCLGE_MBX_OPCODE_MAX 256
++struct hclge_mbx_ops_param {
++ struct hclge_vport *vport;
++ struct hclge_mbx_vf_to_pf_cmd *req;
++ struct hclge_respond_to_vf_msg *resp_msg;
++};
++
++typedef int (*hclge_mbx_ops_fn)(struct hclge_mbx_ops_param *param);
++
+ #define hclge_mbx_ring_ptr_move_crq(crq) \
+ (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
+ #define hclge_mbx_tail_ptr_move_arq(arq) \
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 44d4265f109a8..d5d7fae354e7e 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -3813,18 +3813,16 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 l234info)
+ return 0;
+ }
+
+-static bool hns3_checksum_complete(struct hns3_enet_ring *ring,
++static void hns3_checksum_complete(struct hns3_enet_ring *ring,
+ struct sk_buff *skb, u32 ptype, u16 csum)
+ {
+ if (ptype == HNS3_INVALID_PTYPE ||
+ hns3_rx_ptype_tbl[ptype].ip_summed != CHECKSUM_COMPLETE)
+- return false;
++ return;
+
+ hns3_ring_stats_update(ring, csum_complete);
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->csum = csum_unfold((__force __sum16)csum);
+-
+- return true;
+ }
+
+ static void hns3_rx_handle_csum(struct sk_buff *skb, u32 l234info,
+@@ -3884,8 +3882,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
+ HNS3_RXD_PTYPE_S);
+
+- if (hns3_checksum_complete(ring, skb, ptype, csum))
+- return;
++ hns3_checksum_complete(ring, skb, ptype, csum);
+
+ /* check if hardware has done checksum */
+ if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
+@@ -3894,6 +3891,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) |
+ BIT(HNS3_RXD_OL3E_B) |
+ BIT(HNS3_RXD_OL4E_B)))) {
++ skb->ip_summed = CHECKSUM_NONE;
+ hns3_ring_stats_update(ring, l3l4_csum_err);
+
+ return;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 7e8a60f2401c9..d2dde3f1fb884 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -3713,9 +3713,17 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
+ return ret;
+ }
+
+- if (!reset || !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++ if (!reset ||
++ !test_bit(HCLGE_VPORT_STATE_INITED, &vport->state))
+ continue;
+
++ if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) &&
++ hdev->reset_type == HNAE3_FUNC_RESET) {
++ set_bit(HCLGE_VPORT_NEED_NOTIFY_RESET,
++ &vport->need_notify);
++ continue;
++ }
++
+ /* Inform VF to process the reset.
+ * hclge_inform_reset_assert_to_vf may fail if VF
+ * driver is not loaded.
+@@ -4412,18 +4420,25 @@ static void hclge_reset_service_task(struct hclge_dev *hdev)
+
+ static void hclge_update_vport_alive(struct hclge_dev *hdev)
+ {
++#define HCLGE_ALIVE_SECONDS_NORMAL 8
++
++ unsigned long alive_time = HCLGE_ALIVE_SECONDS_NORMAL * HZ;
+ int i;
+
+ /* start from vport 1 for PF is always alive */
+ for (i = 1; i < hdev->num_alloc_vport; i++) {
+ struct hclge_vport *vport = &hdev->vport[i];
+
+- if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ))
++ if (!test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) ||
++ !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++ continue;
++ if (time_after(jiffies, vport->last_active_jiffies +
++ alive_time)) {
+ clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+-
+- /* If vf is not alive, set to default value */
+- if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+- vport->mps = HCLGE_MAC_DEFAULT_FRAME;
++ dev_warn(&hdev->pdev->dev,
++ "VF %u heartbeat timeout\n",
++ i - HCLGE_VF_VPORT_START_NUM);
++ }
+ }
+ }
+
+@@ -7853,9 +7868,11 @@ int hclge_vport_start(struct hclge_vport *vport)
+ {
+ struct hclge_dev *hdev = vport->back;
+
++ set_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
+ set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
+ vport->last_active_jiffies = jiffies;
++ vport->need_notify = 0;
+
+ if (test_bit(vport->vport_id, hdev->vport_config_block)) {
+ if (vport->vport_id) {
+@@ -7873,7 +7890,9 @@ int hclge_vport_start(struct hclge_vport *vport)
+
+ void hclge_vport_stop(struct hclge_vport *vport)
+ {
++ clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
+ clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++ vport->need_notify = 0;
+ }
+
+ static int hclge_client_start(struct hnae3_handle *handle)
+@@ -8997,7 +9016,8 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
+ return 0;
+ }
+
+- dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %s\n",
++ dev_info(&hdev->pdev->dev,
++ "MAC of VF %d has been set to %s, will be active after VF reset\n",
+ vf, format_mac_addr);
+ return 0;
+ }
+@@ -10254,12 +10274,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
+ * for DEVICE_VERSION_V3, vf doesn't need to know about the port based
+ * VLAN state.
+ */
+- if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
+- test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+- (void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
+- vport->vport_id,
+- state, &vlan_info);
+-
++ if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) {
++ if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++ (void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
++ vport->vport_id,
++ state,
++ &vlan_info);
++ else
++ set_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
++ &vport->need_notify);
++ }
+ return 0;
+ }
+
+@@ -11723,7 +11747,7 @@ static void hclge_reset_vport_state(struct hclge_dev *hdev)
+ int i;
+
+ for (i = 0; i < hdev->num_alloc_vport; i++) {
+- hclge_vport_stop(vport);
++ clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+ vport++;
+ }
+ }
+@@ -12536,60 +12560,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
+ return ret;
+ }
+
+-static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
+ {
+- struct hclge_vport *vport = &hdev->vport[0];
+ struct hnae3_handle *handle = &vport->nic;
++ struct hclge_dev *hdev = vport->back;
++ bool uc_en = false;
++ bool mc_en = false;
+ u8 tmp_flags;
++ bool bc_en;
+ int ret;
+- u16 i;
+
+ if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
+ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
+ vport->last_promisc_flags = vport->overflow_promisc_flags;
+ }
+
+- if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) {
++ if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++ &vport->state))
++ return 0;
++
++ /* for PF */
++ if (!vport->vport_id) {
+ tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
+ ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
+ tmp_flags & HNAE3_MPE);
+- if (!ret) {
+- clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state);
++ if (!ret)
+ set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
+ &vport->state);
+- }
++ else
++ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++ &vport->state);
++ return ret;
+ }
+
+- for (i = 1; i < hdev->num_alloc_vport; i++) {
+- bool uc_en = false;
+- bool mc_en = false;
+- bool bc_en;
++ /* for VF */
++ if (vport->vf_info.trusted) {
++ uc_en = vport->vf_info.request_uc_en > 0 ||
++ vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
++ mc_en = vport->vf_info.request_mc_en > 0 ||
++ vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
++ }
++ bc_en = vport->vf_info.request_bc_en > 0;
+
+- vport = &hdev->vport[i];
++ ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
++ mc_en, bc_en);
++ if (ret) {
++ set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
++ return ret;
++ }
++ hclge_set_vport_vlan_fltr_change(vport);
+
+- if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state))
+- continue;
++ return 0;
++}
+
+- if (vport->vf_info.trusted) {
+- uc_en = vport->vf_info.request_uc_en > 0 ||
+- vport->overflow_promisc_flags &
+- HNAE3_OVERFLOW_UPE;
+- mc_en = vport->vf_info.request_mc_en > 0 ||
+- vport->overflow_promisc_flags &
+- HNAE3_OVERFLOW_MPE;
+- }
+- bc_en = vport->vf_info.request_bc_en > 0;
++static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++{
++ struct hclge_vport *vport;
++ int ret;
++ u16 i;
+
+- ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
+- mc_en, bc_en);
+- if (ret) {
+- set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+- &vport->state);
++ for (i = 0; i < hdev->num_alloc_vport; i++) {
++ vport = &hdev->vport[i];
++
++ ret = hclge_sync_vport_promisc_mode(vport);
++ if (ret)
+ return;
+- }
+- hclge_set_vport_vlan_fltr_change(vport);
+ }
+ }
+
+@@ -12726,6 +12761,11 @@ static void hclge_clear_vport_vf_info(struct hclge_vport *vport, int vfid)
+ struct hclge_vlan_info vlan_info;
+ int ret;
+
++ clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
++ clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++ vport->need_notify = 0;
++ vport->mps = 0;
++
+ /* after disable sriov, clean VF rate configured by PF */
+ ret = hclge_tm_qs_shaper_cfg(vport, 0);
+ if (ret)
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+index 18caddd541f8a..14473e29fe034 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+@@ -972,9 +972,15 @@ enum HCLGE_VPORT_STATE {
+ HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
+ HCLGE_VPORT_STATE_PROMISC_CHANGE,
+ HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
++ HCLGE_VPORT_STATE_INITED,
+ HCLGE_VPORT_STATE_MAX
+ };
+
++enum HCLGE_VPORT_NEED_NOTIFY {
++ HCLGE_VPORT_NEED_NOTIFY_RESET,
++ HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
++};
++
+ struct hclge_vlan_info {
+ u16 vlan_proto; /* so far support 802.1Q only */
+ u16 qos;
+@@ -1021,6 +1027,7 @@ struct hclge_vport {
+ struct hnae3_handle roce;
+
+ unsigned long state;
++ unsigned long need_notify;
+ unsigned long last_active_jiffies;
+ u32 mps; /* Max packet size */
+ struct hclge_vf_info vf_info;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index e1012f7f9b734..04ff9bf121853 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -124,17 +124,26 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
+ return status;
+ }
+
++static int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type)
++{
++ __le16 msg_data;
++ u8 dest_vfid;
++
++ dest_vfid = (u8)vport->vport_id;
++ msg_data = cpu_to_le16(reset_type);
++
++ /* send this requested info to VF */
++ return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
++ HCLGE_MBX_ASSERTING_RESET, dest_vfid);
++}
++
+ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
+ {
+ struct hclge_dev *hdev = vport->back;
+- __le16 msg_data;
+ u16 reset_type;
+- u8 dest_vfid;
+
+ BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX);
+
+- dest_vfid = (u8)vport->vport_id;
+-
+ if (hdev->reset_type == HNAE3_FUNC_RESET)
+ reset_type = HNAE3_VF_PF_FUNC_RESET;
+ else if (hdev->reset_type == HNAE3_FLR_RESET)
+@@ -142,11 +151,7 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
+ else
+ reset_type = HNAE3_VF_FUNC_RESET;
+
+- msg_data = cpu_to_le16(reset_type);
+-
+- /* send this requested info to VF */
+- return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
+- HCLGE_MBX_ASSERTING_RESET, dest_vfid);
++ return hclge_inform_vf_reset(vport, reset_type);
+ }
+
+ static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
+@@ -652,9 +657,56 @@ static int hclge_reset_vf(struct hclge_vport *vport)
+ return hclge_func_reset_cmd(hdev, vport->vport_id);
+ }
+
++static void hclge_notify_vf_config(struct hclge_vport *vport)
++{
++ struct hclge_dev *hdev = vport->back;
++ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
++ struct hclge_port_base_vlan_config *vlan_cfg;
++ int ret;
++
++ hclge_push_vf_link_status(vport);
++ if (test_bit(HCLGE_VPORT_NEED_NOTIFY_RESET, &vport->need_notify)) {
++ ret = hclge_inform_vf_reset(vport, HNAE3_VF_PF_FUNC_RESET);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "failed to inform VF %u reset!",
++ vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++ return;
++ }
++ vport->need_notify = 0;
++ return;
++ }
++
++ if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
++ test_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify)) {
++ vlan_cfg = &vport->port_base_vlan_cfg;
++ ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
++ vport->vport_id,
++ vlan_cfg->state,
++ &vlan_cfg->vlan_info);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "failed to inform VF %u port base vlan!",
++ vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++ return;
++ }
++ clear_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify);
++ }
++}
++
+ static void hclge_vf_keep_alive(struct hclge_vport *vport)
+ {
++ struct hclge_dev *hdev = vport->back;
++
+ vport->last_active_jiffies = jiffies;
++
++ if (test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) &&
++ !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
++ set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++ dev_info(&hdev->pdev->dev, "VF %u is alive!",
++ vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++ hclge_notify_vf_config(vport);
++ }
+ }
+
+ static int hclge_set_vf_mtu(struct hclge_vport *vport,
+@@ -779,17 +831,285 @@ static void hclge_handle_vf_tbl(struct hclge_vport *vport,
+ }
+ }
+
++static int
++hclge_mbx_map_ring_to_vector_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_map_unmap_ring_to_vf_vector(param->vport, true,
++ param->req);
++}
++
++static int
++hclge_mbx_unmap_ring_to_vector_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_map_unmap_ring_to_vf_vector(param->vport, false,
++ param->req);
++}
++
++static int
++hclge_mbx_get_ring_vector_map_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_get_vf_ring_vector_map(param->vport, param->req,
++ param->resp_msg);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "PF fail(%d) to get VF ring vector map\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_set_promisc_mode_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_set_vf_promisc_mode(param->vport, param->req);
++ return 0;
++}
++
++static int hclge_mbx_set_unicast_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_set_vf_uc_mac_addr(param->vport, param->req);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "PF fail(%d) to set VF UC MAC Addr\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_set_multicast_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_set_vf_mc_mac_addr(param->vport, param->req);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "PF fail(%d) to set VF MC MAC Addr\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_set_vlan_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_set_vf_vlan_cfg(param->vport, param->req, param->resp_msg);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "PF failed(%d) to config VF's VLAN\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_set_alive_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_set_vf_alive(param->vport, param->req);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "PF failed(%d) to set VF's ALIVE\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_get_qinfo_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_vf_queue_info(param->vport, param->resp_msg);
++ return 0;
++}
++
++static int hclge_mbx_get_qdepth_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_vf_queue_depth(param->vport, param->resp_msg);
++ return 0;
++}
++
++static int hclge_mbx_get_basic_info_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_basic_info(param->vport, param->resp_msg);
++ return 0;
++}
++
++static int hclge_mbx_get_link_status_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_push_vf_link_status(param->vport);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "failed to inform link stat to VF, ret = %d\n",
++ ret);
++ return ret;
++}
++
++static int hclge_mbx_queue_reset_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_mbx_reset_vf_queue(param->vport, param->req,
++ param->resp_msg);
++}
++
++static int hclge_mbx_reset_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_reset_vf(param->vport);
++}
++
++static int hclge_mbx_keep_alive_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_vf_keep_alive(param->vport);
++ return 0;
++}
++
++static int hclge_mbx_set_mtu_handler(struct hclge_mbx_ops_param *param)
++{
++ int ret;
++
++ ret = hclge_set_vf_mtu(param->vport, param->req);
++ if (ret)
++ dev_err(¶m->vport->back->pdev->dev,
++ "VF fail(%d) to set mtu\n", ret);
++ return ret;
++}
++
++static int hclge_mbx_get_qid_in_pf_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_get_queue_id_in_pf(param->vport, param->req,
++ param->resp_msg);
++}
++
++static int hclge_mbx_get_rss_key_handler(struct hclge_mbx_ops_param *param)
++{
++ return hclge_get_rss_key(param->vport, param->req, param->resp_msg);
++}
++
++static int hclge_mbx_get_link_mode_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_link_mode(param->vport, param->req);
++ return 0;
++}
++
++static int
++hclge_mbx_get_vf_flr_status_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_rm_vport_all_mac_table(param->vport, false,
++ HCLGE_MAC_ADDR_UC);
++ hclge_rm_vport_all_mac_table(param->vport, false,
++ HCLGE_MAC_ADDR_MC);
++ hclge_rm_vport_all_vlan_table(param->vport, false);
++ return 0;
++}
++
++static int hclge_mbx_vf_uninit_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_rm_vport_all_mac_table(param->vport, true,
++ HCLGE_MAC_ADDR_UC);
++ hclge_rm_vport_all_mac_table(param->vport, true,
++ HCLGE_MAC_ADDR_MC);
++ hclge_rm_vport_all_vlan_table(param->vport, true);
++ param->vport->mps = 0;
++ return 0;
++}
++
++static int hclge_mbx_get_media_type_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_vf_media_type(param->vport, param->resp_msg);
++ return 0;
++}
++
++static int hclge_mbx_push_link_status_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_handle_link_change_event(param->vport->back, param->req);
++ return 0;
++}
++
++static int hclge_mbx_get_mac_addr_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_get_vf_mac_addr(param->vport, param->resp_msg);
++ return 0;
++}
++
++static int hclge_mbx_ncsi_error_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_handle_ncsi_error(param->vport->back);
++ return 0;
++}
++
++static int hclge_mbx_handle_vf_tbl_handler(struct hclge_mbx_ops_param *param)
++{
++ hclge_handle_vf_tbl(param->vport, param->req);
++ return 0;
++}
++
++static const hclge_mbx_ops_fn hclge_mbx_ops_list[HCLGE_MBX_OPCODE_MAX] = {
++ [HCLGE_MBX_RESET] = hclge_mbx_reset_handler,
++ [HCLGE_MBX_SET_UNICAST] = hclge_mbx_set_unicast_handler,
++ [HCLGE_MBX_SET_MULTICAST] = hclge_mbx_set_multicast_handler,
++ [HCLGE_MBX_SET_VLAN] = hclge_mbx_set_vlan_handler,
++ [HCLGE_MBX_MAP_RING_TO_VECTOR] = hclge_mbx_map_ring_to_vector_handler,
++ [HCLGE_MBX_UNMAP_RING_TO_VECTOR] = hclge_mbx_unmap_ring_to_vector_handler,
++ [HCLGE_MBX_SET_PROMISC_MODE] = hclge_mbx_set_promisc_mode_handler,
++ [HCLGE_MBX_GET_QINFO] = hclge_mbx_get_qinfo_handler,
++ [HCLGE_MBX_GET_QDEPTH] = hclge_mbx_get_qdepth_handler,
++ [HCLGE_MBX_GET_BASIC_INFO] = hclge_mbx_get_basic_info_handler,
++ [HCLGE_MBX_GET_RSS_KEY] = hclge_mbx_get_rss_key_handler,
++ [HCLGE_MBX_GET_MAC_ADDR] = hclge_mbx_get_mac_addr_handler,
++ [HCLGE_MBX_GET_LINK_STATUS] = hclge_mbx_get_link_status_handler,
++ [HCLGE_MBX_QUEUE_RESET] = hclge_mbx_queue_reset_handler,
++ [HCLGE_MBX_KEEP_ALIVE] = hclge_mbx_keep_alive_handler,
++ [HCLGE_MBX_SET_ALIVE] = hclge_mbx_set_alive_handler,
++ [HCLGE_MBX_SET_MTU] = hclge_mbx_set_mtu_handler,
++ [HCLGE_MBX_GET_QID_IN_PF] = hclge_mbx_get_qid_in_pf_handler,
++ [HCLGE_MBX_GET_LINK_MODE] = hclge_mbx_get_link_mode_handler,
++ [HCLGE_MBX_GET_MEDIA_TYPE] = hclge_mbx_get_media_type_handler,
++ [HCLGE_MBX_VF_UNINIT] = hclge_mbx_vf_uninit_handler,
++ [HCLGE_MBX_HANDLE_VF_TBL] = hclge_mbx_handle_vf_tbl_handler,
++ [HCLGE_MBX_GET_RING_VECTOR_MAP] = hclge_mbx_get_ring_vector_map_handler,
++ [HCLGE_MBX_GET_VF_FLR_STATUS] = hclge_mbx_get_vf_flr_status_handler,
++ [HCLGE_MBX_PUSH_LINK_STATUS] = hclge_mbx_push_link_status_handler,
++ [HCLGE_MBX_NCSI_ERROR] = hclge_mbx_ncsi_error_handler,
++};
++
++static void hclge_mbx_request_handling(struct hclge_mbx_ops_param *param)
++{
++ hclge_mbx_ops_fn cmd_func = NULL;
++ struct hclge_dev *hdev;
++ int ret = 0;
++
++ hdev = param->vport->back;
++ cmd_func = hclge_mbx_ops_list[param->req->msg.code];
++ if (cmd_func)
++ ret = cmd_func(param);
++ else
++ dev_err(&hdev->pdev->dev,
++ "un-supported mailbox message, code = %u\n",
++ param->req->msg.code);
++
++ /* PF driver should not reply IMP */
++ if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
++ param->req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) {
++ param->resp_msg->status = ret;
++ if (time_is_before_jiffies(hdev->last_mbx_scheduled +
++ HCLGE_MBX_SCHED_TIMEOUT))
++ dev_warn(&hdev->pdev->dev,
++ "resp vport%u mbx(%u,%u) late\n",
++ param->req->mbx_src_vfid,
++ param->req->msg.code,
++ param->req->msg.subcode);
++
++ hclge_gen_resp_to_vf(param->vport, param->req, param->resp_msg);
++ }
++}
++
+ void hclge_mbx_handler(struct hclge_dev *hdev)
+ {
+ struct hclge_comm_cmq_ring *crq = &hdev->hw.hw.cmq.crq;
+ struct hclge_respond_to_vf_msg resp_msg;
+ struct hclge_mbx_vf_to_pf_cmd *req;
+- struct hclge_vport *vport;
++ struct hclge_mbx_ops_param param;
+ struct hclge_desc *desc;
+- bool is_del = false;
+ unsigned int flag;
+- int ret = 0;
+
++ param.resp_msg = &resp_msg;
+ /* handle all the mailbox requests in the queue */
+ while (!hclge_cmd_crq_empty(&hdev->hw)) {
+ if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE,
+@@ -814,152 +1134,16 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
+ continue;
+ }
+
+- vport = &hdev->vport[req->mbx_src_vfid];
+-
+ trace_hclge_pf_mbx_get(hdev, req);
+
+ /* clear the resp_msg before processing every mailbox message */
+ memset(&resp_msg, 0, sizeof(resp_msg));
+-
+- switch (req->msg.code) {
+- case HCLGE_MBX_MAP_RING_TO_VECTOR:
+- ret = hclge_map_unmap_ring_to_vf_vector(vport, true,
+- req);
+- break;
+- case HCLGE_MBX_UNMAP_RING_TO_VECTOR:
+- ret = hclge_map_unmap_ring_to_vf_vector(vport, false,
+- req);
+- break;
+- case HCLGE_MBX_GET_RING_VECTOR_MAP:
+- ret = hclge_get_vf_ring_vector_map(vport, req,
+- &resp_msg);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "PF fail(%d) to get VF ring vector map\n",
+- ret);
+- break;
+- case HCLGE_MBX_SET_PROMISC_MODE:
+- hclge_set_vf_promisc_mode(vport, req);
+- break;
+- case HCLGE_MBX_SET_UNICAST:
+- ret = hclge_set_vf_uc_mac_addr(vport, req);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "PF fail(%d) to set VF UC MAC Addr\n",
+- ret);
+- break;
+- case HCLGE_MBX_SET_MULTICAST:
+- ret = hclge_set_vf_mc_mac_addr(vport, req);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "PF fail(%d) to set VF MC MAC Addr\n",
+- ret);
+- break;
+- case HCLGE_MBX_SET_VLAN:
+- ret = hclge_set_vf_vlan_cfg(vport, req, &resp_msg);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "PF failed(%d) to config VF's VLAN\n",
+- ret);
+- break;
+- case HCLGE_MBX_SET_ALIVE:
+- ret = hclge_set_vf_alive(vport, req);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "PF failed(%d) to set VF's ALIVE\n",
+- ret);
+- break;
+- case HCLGE_MBX_GET_QINFO:
+- hclge_get_vf_queue_info(vport, &resp_msg);
+- break;
+- case HCLGE_MBX_GET_QDEPTH:
+- hclge_get_vf_queue_depth(vport, &resp_msg);
+- break;
+- case HCLGE_MBX_GET_BASIC_INFO:
+- hclge_get_basic_info(vport, &resp_msg);
+- break;
+- case HCLGE_MBX_GET_LINK_STATUS:
+- ret = hclge_push_vf_link_status(vport);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "failed to inform link stat to VF, ret = %d\n",
+- ret);
+- break;
+- case HCLGE_MBX_QUEUE_RESET:
+- ret = hclge_mbx_reset_vf_queue(vport, req, &resp_msg);
+- break;
+- case HCLGE_MBX_RESET:
+- ret = hclge_reset_vf(vport);
+- break;
+- case HCLGE_MBX_KEEP_ALIVE:
+- hclge_vf_keep_alive(vport);
+- break;
+- case HCLGE_MBX_SET_MTU:
+- ret = hclge_set_vf_mtu(vport, req);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "VF fail(%d) to set mtu\n", ret);
+- break;
+- case HCLGE_MBX_GET_QID_IN_PF:
+- ret = hclge_get_queue_id_in_pf(vport, req, &resp_msg);
+- break;
+- case HCLGE_MBX_GET_RSS_KEY:
+- ret = hclge_get_rss_key(vport, req, &resp_msg);
+- break;
+- case HCLGE_MBX_GET_LINK_MODE:
+- hclge_get_link_mode(vport, req);
+- break;
+- case HCLGE_MBX_GET_VF_FLR_STATUS:
+- case HCLGE_MBX_VF_UNINIT:
+- is_del = req->msg.code == HCLGE_MBX_VF_UNINIT;
+- hclge_rm_vport_all_mac_table(vport, is_del,
+- HCLGE_MAC_ADDR_UC);
+- hclge_rm_vport_all_mac_table(vport, is_del,
+- HCLGE_MAC_ADDR_MC);
+- hclge_rm_vport_all_vlan_table(vport, is_del);
+- break;
+- case HCLGE_MBX_GET_MEDIA_TYPE:
+- hclge_get_vf_media_type(vport, &resp_msg);
+- break;
+- case HCLGE_MBX_PUSH_LINK_STATUS:
+- hclge_handle_link_change_event(hdev, req);
+- break;
+- case HCLGE_MBX_GET_MAC_ADDR:
+- hclge_get_vf_mac_addr(vport, &resp_msg);
+- break;
+- case HCLGE_MBX_NCSI_ERROR:
+- hclge_handle_ncsi_error(hdev);
+- break;
+- case HCLGE_MBX_HANDLE_VF_TBL:
+- hclge_handle_vf_tbl(vport, req);
+- break;
+- default:
+- dev_err(&hdev->pdev->dev,
+- "un-supported mailbox message, code = %u\n",
+- req->msg.code);
+- break;
+- }
+-
+- /* PF driver should not reply IMP */
+- if (hnae3_get_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
+- req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) {
+- resp_msg.status = ret;
+- if (time_is_before_jiffies(hdev->last_mbx_scheduled +
+- HCLGE_MBX_SCHED_TIMEOUT))
+- dev_warn(&hdev->pdev->dev,
+- "resp vport%u mbx(%u,%u) late\n",
+- req->mbx_src_vfid,
+- req->msg.code,
+- req->msg.subcode);
+-
+- hclge_gen_resp_to_vf(vport, req, &resp_msg);
+- }
++ param.vport = &hdev->vport[req->mbx_src_vfid];
++ param.req = req;
++ hclge_mbx_request_handling(¶m);
+
+ crq->desc[crq->next_to_use].flag = 0;
+ hclge_mbx_ring_ptr_move_crq(crq);
+-
+- /* reinitialize ret after complete the mbx message processing */
+- ret = 0;
+ }
+
+ /* Write back CMDQ_RQ header pointer, M7 need this pointer */
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 26f87330173eb..c551508e69325 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -2767,7 +2767,8 @@ static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
+ struct pci_dev *pdev = hdev->pdev;
+ int ret = 0;
+
+- if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
++ if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
++ hdev->reset_type == HNAE3_FLR_RESET) &&
+ test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
+ hclgevf_misc_irq_uninit(hdev);
+ hclgevf_uninit_msi(hdev);
+diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c
+index 056c904b83ccb..79fa65d1cf201 100644
+--- a/drivers/net/ethernet/intel/ice/ice_xsk.c
++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c
+@@ -772,7 +772,7 @@ construct_skb:
+ static void
+ ice_clean_xdp_tx_buf(struct ice_tx_ring *xdp_ring, struct ice_tx_buf *tx_buf)
+ {
+- xdp_return_frame((struct xdp_frame *)tx_buf->raw_buf);
++ page_frag_free(tx_buf->raw_buf);
+ xdp_ring->xdp_tx_active--;
+ dma_unmap_single(xdp_ring->dev, dma_unmap_addr(tx_buf, dma),
+ dma_unmap_len(tx_buf, len), DMA_TO_DEVICE);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 9c2baa437c231..2926d754ade8e 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -977,6 +977,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ rbpool = cq->rbpool;
+ free_ptrs = cq->pool_ptrs;
+
++ get_cpu();
+ while (cq->pool_ptrs) {
+ if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
+ /* Schedule a WQ if we fails to free atleast half of the
+@@ -996,6 +997,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
+ cq->pool_ptrs--;
+ }
++ put_cpu();
+ cq->refill_task_sched = false;
+ }
+
+@@ -1333,6 +1335,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
++ get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) {
+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
+@@ -1341,18 +1344,24 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ sq = &qset->sq[qidx];
+ sq->sqb_count = 0;
+ sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL);
+- if (!sq->sqb_ptrs)
+- return -ENOMEM;
++ if (!sq->sqb_ptrs) {
++ err = -ENOMEM;
++ goto err_mem;
++ }
+
+ for (ptr = 0; ptr < num_sqbs; ptr++) {
+- if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+- return -ENOMEM;
++ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++ if (err)
++ goto err_mem;
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
+ sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
+ }
+ }
+
+- return 0;
++err_mem:
++ put_cpu();
++ return err ? -ENOMEM : 0;
++
+ fail:
+ otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ otx2_aura_pool_free(pfvf);
+@@ -1391,18 +1400,21 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
+ if (err)
+ goto fail;
+
++ get_cpu();
+ /* Allocate pointers and free them to aura/pool */
+ for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) {
+ pool = &pfvf->qset.pool[pool_id];
+ for (ptr = 0; ptr < num_ptrs; ptr++) {
+- if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+- return -ENOMEM;
++ err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++ if (err)
++ goto err_mem;
+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
+ bufptr + OTX2_HEAD_ROOM);
+ }
+ }
+-
+- return 0;
++err_mem:
++ put_cpu();
++ return err ? -ENOMEM : 0;
+ fail:
+ otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ otx2_aura_pool_free(pfvf);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 66c6a7017695d..97e9ec44a759b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -468,7 +468,7 @@ static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
+ bool new_state = val.vbool;
+
+ if (new_state && !MLX5_CAP_GEN(dev, roce) &&
+- !MLX5_CAP_GEN(dev, roce_rw_supported)) {
++ !(MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))) {
+ NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
+ return -EOPNOTSUPP;
+ }
+@@ -563,7 +563,7 @@ static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
+ union devlink_param_value val,
+ struct netlink_ext_ack *extack)
+ {
+- return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
++ return (val.vu32 >= 64 && val.vu32 <= 4096) ? 0 : -EINVAL;
+ }
+
+ static const struct devlink_param mlx5_devlink_params[] = {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+index 864ce0c393e61..f01f7dfdbcf88 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+@@ -2080,14 +2080,9 @@ out_err:
+ static void
+ mlx5_ct_tc_create_dbgfs(struct mlx5_tc_ct_priv *ct_priv)
+ {
+- bool is_fdb = ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB;
+ struct mlx5_tc_ct_debugfs *ct_dbgfs = &ct_priv->debugfs;
+- char dirname[16] = {};
+
+- if (sscanf(dirname, "ct_%s", is_fdb ? "fdb" : "nic") < 0)
+- return;
+-
+- ct_dbgfs->root = debugfs_create_dir(dirname, mlx5_debugfs_get_dev_root(ct_priv->dev));
++ ct_dbgfs->root = debugfs_create_dir("ct", mlx5_debugfs_get_dev_root(ct_priv->dev));
+ debugfs_create_atomic_t("offloaded", 0400, ct_dbgfs->root,
+ &ct_dbgfs->stats.offloaded);
+ debugfs_create_atomic_t("rx_dropped", 0400, ct_dbgfs->root,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index ff73d25bc6eb8..2aaf8ab857b8f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -222,7 +222,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ int err;
+
+ list_for_each_entry(flow, flow_list, tmp_list) {
+- if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
++ if (!mlx5e_is_offloaded_flow(flow))
+ continue;
+
+ attr = mlx5e_tc_get_encap_attr(flow);
+@@ -231,6 +231,13 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
+ esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
+
++ /* Clear pkt_reformat before checking slow path flag. Because
++ * in next iteration, the same flow is already set slow path
++ * flag, but still need to clear the pkt_reformat.
++ */
++ if (flow_flag_test(flow, SLOW))
++ continue;
++
+ /* update from encap rule to slow path rule */
+ spec = &flow->attr->parse_attr->spec;
+ rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
+index f5b26f5a7de46..054d80c4e65cf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
+@@ -273,6 +273,11 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv,
+ geneve_tlv_option_0_data, be32_to_cpu(opt_data_key));
+ MLX5_SET(fte_match_set_misc3, misc_3_c,
+ geneve_tlv_option_0_data, be32_to_cpu(opt_data_mask));
++ if (MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
++ ft_field_support.geneve_tlv_option_0_exist)) {
++ MLX5_SET_TO_ONES(fte_match_set_misc, misc_c, geneve_tlv_option_0_exist);
++ MLX5_SET_TO_ONES(fte_match_set_misc, misc_v, geneve_tlv_option_0_exist);
++ }
+
+ spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 6cf6a81775a85..5c16efb8be81d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -1146,7 +1146,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
+ sq->channel = c;
+ sq->uar_map = mdev->mlx5e_res.hw_objs.bfreg.map;
+ sq->min_inline_mode = params->tx_min_inline_mode;
+- sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
++ sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
+ sq->xsk_pool = xsk_pool;
+
+ sq->stats = sq->xsk_pool ?
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+index 60a73990017c2..6b4c9ffad95b2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+@@ -67,6 +67,7 @@ static void esw_acl_egress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ struct mlx5_flow_destination drop_ctr_dst = {};
+ struct mlx5_flow_destination *dst = NULL;
+ struct mlx5_fc *drop_counter = NULL;
+@@ -77,6 +78,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ */
+ int table_size = 2;
+ int dest_num = 0;
++ int actions_flag;
+ int err = 0;
+
+ if (vport->egress.legacy.drop_counter) {
+@@ -119,8 +121,11 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ vport->vport, vport->info.vlan, vport->info.qos);
+
+ /* Allowed vlan rule */
++ actions_flag = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++ if (vst_mode_steering)
++ actions_flag |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+ err = esw_egress_acl_vlan_create(esw, vport, NULL, vport->info.vlan,
+- MLX5_FLOW_CONTEXT_ACTION_ALLOW);
++ actions_flag);
+ if (err)
+ goto out;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+index b1a5199260f69..093ed86a0acd8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+@@ -139,11 +139,14 @@ static void esw_acl_ingress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ struct mlx5_flow_destination drop_ctr_dst = {};
+ struct mlx5_flow_destination *dst = NULL;
+ struct mlx5_flow_act flow_act = {};
+ struct mlx5_flow_spec *spec = NULL;
+ struct mlx5_fc *counter = NULL;
++ bool vst_check_cvlan = false;
++ bool vst_push_cvlan = false;
+ /* The ingress acl table contains 4 groups
+ * (2 active rules at the same time -
+ * 1 allow rule from one of the first 3 groups.
+@@ -203,7 +206,26 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ goto out;
+ }
+
+- if (vport->info.vlan || vport->info.qos)
++ if ((vport->info.vlan || vport->info.qos)) {
++ if (vst_mode_steering)
++ vst_push_cvlan = true;
++ else if (!MLX5_CAP_ESW(esw->dev, vport_cvlan_insert_always))
++ vst_check_cvlan = true;
++ }
++
++ if (vst_check_cvlan || vport->info.spoofchk)
++ spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
++
++ /* Create ingress allow rule */
++ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++ if (vst_push_cvlan) {
++ flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
++ flow_act.vlan[0].prio = vport->info.qos;
++ flow_act.vlan[0].vid = vport->info.vlan;
++ flow_act.vlan[0].ethtype = ETH_P_8021Q;
++ }
++
++ if (vst_check_cvlan)
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.cvlan_tag);
+
+@@ -218,9 +240,6 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ ether_addr_copy(smac_v, vport->info.mac);
+ }
+
+- /* Create ingress allow rule */
+- spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
+ vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec,
+ &flow_act, NULL, 0);
+ if (IS_ERR(vport->ingress.allow_rule)) {
+@@ -232,6 +251,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ goto out;
+ }
+
++ if (!vst_check_cvlan && !vport->info.spoofchk)
++ goto out;
++
+ memset(&flow_act, 0, sizeof(flow_act));
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
+ /* Attach drop flow counter */
+@@ -257,7 +279,8 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ return 0;
+
+ out:
+- esw_acl_ingress_lgcy_cleanup(esw, vport);
++ if (err)
++ esw_acl_ingress_lgcy_cleanup(esw, vport);
+ kvfree(spec);
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 59cffa49e4b58..940e893f3f097 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -161,10 +161,17 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u16 vport,
+ esw_vport_context.vport_cvlan_strip, 1);
+
+ if (set_flags & SET_VLAN_INSERT) {
+- /* insert only if no vlan in packet */
+- MLX5_SET(modify_esw_vport_context_in, in,
+- esw_vport_context.vport_cvlan_insert, 1);
+-
++ if (MLX5_CAP_ESW(dev, vport_cvlan_insert_always)) {
++ /* insert either if vlan exist in packet or not */
++ MLX5_SET(modify_esw_vport_context_in, in,
++ esw_vport_context.vport_cvlan_insert,
++ MLX5_VPORT_CVLAN_INSERT_ALWAYS);
++ } else {
++ /* insert only if no vlan in packet */
++ MLX5_SET(modify_esw_vport_context_in, in,
++ esw_vport_context.vport_cvlan_insert,
++ MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN);
++ }
+ MLX5_SET(modify_esw_vport_context_in, in,
+ esw_vport_context.cvlan_pcp, qos);
+ MLX5_SET(modify_esw_vport_context_in, in,
+@@ -774,6 +781,7 @@ static void esw_vport_cleanup_acl(struct mlx5_eswitch *esw,
+
+ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+ {
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ u16 vport_num = vport->vport;
+ int flags;
+ int err;
+@@ -800,8 +808,9 @@ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+
+ flags = (vport->info.vlan || vport->info.qos) ?
+ SET_VLAN_STRIP | SET_VLAN_INSERT : 0;
+- modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
+- vport->info.qos, flags);
++ if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering)
++ modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
++ vport->info.qos, flags);
+
+ return 0;
+ }
+@@ -1806,6 +1815,7 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ u16 vport, u16 vlan, u8 qos, u8 set_flags)
+ {
+ struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
++ bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ int err = 0;
+
+ if (IS_ERR(evport))
+@@ -1813,9 +1823,11 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ if (vlan > 4095 || qos > 7)
+ return -EINVAL;
+
+- err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
+- if (err)
+- return err;
++ if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering) {
++ err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
++ if (err)
++ return err;
++ }
+
+ evport->info.vlan = vlan;
+ evport->info.qos = qos;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 5ceed4e6c6581..03080e8161cba 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -513,6 +513,12 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
+ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ u16 vport, u16 vlan, u8 qos, u8 set_flags);
+
++static inline bool esw_vst_mode_is_steering(struct mlx5_eswitch *esw)
++{
++ return (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, pop_vlan) &&
++ MLX5_CAP_ESW_INGRESS_ACL(esw->dev, push_vlan));
++}
++
+ static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
+ u8 vlan_depth)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+index 2cf2c99484467..0ed239eadf394 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -674,6 +674,12 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
+ dev = container_of(priv, struct mlx5_core_dev, priv);
+ devlink = priv_to_devlink(dev);
+
++ mutex_lock(&dev->intf_state_mutex);
++ if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) {
++ mlx5_core_err(dev, "health works are not permitted at this stage\n");
++ return;
++ }
++ mutex_unlock(&dev->intf_state_mutex);
+ enter_error_state(dev, false);
+ if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
+ devl_lock(devlink);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+index c02b7b08fb4c1..2032d5c0ad86a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+@@ -70,6 +70,10 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
+ params->packet_merge.type = MLX5E_PACKET_MERGE_NONE;
+ params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
+ params->tunneled_offload_en = false;
++
++ /* CQE compression is not supported for IPoIB */
++ params->rx_cqe_compress_def = false;
++ MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
+ }
+
+ /* Called directly after IPoIB netdevice was created to initialize SW structs */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index bbe810f3b373a..c142011d20977 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -201,6 +201,7 @@ static void mlx5_ldev_free(struct kref *ref)
+ if (ldev->nb.notifier_call)
+ unregister_netdevice_notifier_net(&init_net, &ldev->nb);
+ mlx5_lag_mp_cleanup(ldev);
++ cancel_delayed_work_sync(&ldev->bond_work);
+ destroy_workqueue(ldev->wq);
+ mlx5_lag_mpesw_cleanup(ldev);
+ mutex_destroy(&ldev->lock);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index ac178796e484f..0a2f23a7082a8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -614,7 +614,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+ MLX5_SET(cmd_hca_cap, set_hca_cap, num_total_dynamic_vf_msix,
+ MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix));
+
+- if (MLX5_CAP_GEN(dev, roce_rw_supported))
++ if (MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))
+ MLX5_SET(cmd_hca_cap, set_hca_cap, roce,
+ mlx5_is_roce_on(dev));
+
+@@ -1017,6 +1017,8 @@ err_rl_cleanup:
+ err_tables_cleanup:
+ mlx5_geneve_destroy(dev->geneve);
+ mlx5_vxlan_destroy(dev->vxlan);
++ mlx5_cleanup_clock(dev);
++ mlx5_cleanup_reserved_gids(dev);
+ mlx5_cq_debugfs_cleanup(dev);
+ mlx5_fw_reset_cleanup(dev);
+ err_events_cleanup:
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
+index f141644e4372f..26c5cdf373c4d 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
+@@ -369,7 +369,7 @@ int lan966x_port_pcs_set(struct lan966x_port *port,
+ }
+
+ /* Take PCS out of reset */
+- lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
++ lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000) |
+ DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
+ DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
+ DEV_CLOCK_CFG_LINK_SPEED |
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index e58de119186a6..a2d0631f7ac71 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -819,7 +819,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
+ if (err)
+ goto cleanup_config;
+
+- if (!of_get_mac_address(np, sparx5->base_mac)) {
++ if (of_get_mac_address(np, sparx5->base_mac)) {
+ dev_info(sparx5->dev, "MAC addr was not set, use random MAC\n");
+ eth_random_addr(sparx5->base_mac);
+ sparx5->base_mac[5] = 0;
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 86ecb080b1536..cdcead614e9fa 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -1832,7 +1832,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 image_type,
+ u32 *nvram_offset_bytes,
+- u32 *nvram_size_bytes)
++ u32 *nvram_size_bytes,
++ bool b_can_sleep)
+ {
+ u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
+ struct mcp_file_att file_att;
+@@ -1846,7 +1847,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ &ret_mcp_resp,
+ &ret_mcp_param,
+ &ret_txn_size,
+- (u32 *)&file_att, false);
++ (u32 *)&file_att,
++ b_can_sleep);
+
+ /* Check response */
+ if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
+@@ -1873,7 +1875,9 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 nvram_offset_bytes,
+- u32 nvram_size_bytes, u32 *ret_buf)
++ u32 nvram_size_bytes,
++ u32 *ret_buf,
++ bool b_can_sleep)
+ {
+ u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
+ s32 bytes_left = nvram_size_bytes;
+@@ -1899,7 +1903,7 @@ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
+ &ret_mcp_resp,
+ &ret_mcp_param, &ret_read_size,
+ (u32 *)((u8 *)ret_buf + read_offset),
+- false))
++ b_can_sleep))
+ return DBG_STATUS_NVRAM_READ_FAILED;
+
+ /* Check response */
+@@ -3380,7 +3384,8 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
+ p_ptt,
+ NVM_TYPE_HW_DUMP_OUT,
+ &hw_dump_offset_bytes,
+- &hw_dump_size_bytes);
++ &hw_dump_size_bytes,
++ false);
+ if (status != DBG_STATUS_OK)
+ return 0;
+
+@@ -3397,7 +3402,9 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
+ status = qed_nvram_read(p_hwfn,
+ p_ptt,
+ hw_dump_offset_bytes,
+- hw_dump_size_bytes, dump_buf + offset);
++ hw_dump_size_bytes,
++ dump_buf + offset,
++ false);
+ if (status != DBG_STATUS_OK) {
+ DP_NOTICE(p_hwfn,
+ "Failed to read MCP HW Dump image from NVRAM\n");
+@@ -4123,7 +4130,9 @@ static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
+ return qed_find_nvram_image(p_hwfn,
+ p_ptt,
+ nvram_image_type,
+- trace_meta_offset, trace_meta_size);
++ trace_meta_offset,
++ trace_meta_size,
++ true);
+ }
+
+ /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
+@@ -4139,7 +4148,10 @@ static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
+ /* Read meta data from NVRAM */
+ status = qed_nvram_read(p_hwfn,
+ p_ptt,
+- nvram_offset_in_bytes, size_in_bytes, buf);
++ nvram_offset_in_bytes,
++ size_in_bytes,
++ buf,
++ true);
+ if (status != DBG_STATUS_OK)
+ return status;
+
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+index dbb800769cb63..c95d56e56c59a 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+@@ -2505,7 +2505,13 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter)
+ goto disable_mbx_intr;
+
+ qlcnic_83xx_clear_function_resources(adapter);
+- qlcnic_dcb_enable(adapter->dcb);
++
++ err = qlcnic_dcb_enable(adapter->dcb);
++ if (err) {
++ qlcnic_dcb_free(adapter->dcb);
++ goto disable_mbx_intr;
++ }
++
+ qlcnic_83xx_initialize_nic(adapter, 1);
+ qlcnic_dcb_get_info(adapter->dcb);
+
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+index 7519773eaca6e..22afa2be85fdb 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+@@ -41,11 +41,6 @@ struct qlcnic_dcb {
+ unsigned long state;
+ };
+
+-static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+-{
+- kfree(dcb);
+-}
+-
+ static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+ {
+ if (dcb && dcb->ops->get_hw_capability)
+@@ -112,9 +107,8 @@ static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+ dcb->ops->init_dcbnl_ops(dcb);
+ }
+
+-static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
++static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
+ {
+- if (dcb && qlcnic_dcb_attach(dcb))
+- qlcnic_clear_dcb_ops(dcb);
++ return dcb ? qlcnic_dcb_attach(dcb) : 0;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+index 28476b982bab6..44dac3c0908eb 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+@@ -2599,7 +2599,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ "Device does not support MSI interrupts\n");
+
+ if (qlcnic_82xx_check(adapter)) {
+- qlcnic_dcb_enable(adapter->dcb);
++ err = qlcnic_dcb_enable(adapter->dcb);
++ if (err) {
++ qlcnic_dcb_free(adapter->dcb);
++ dev_err(&pdev->dev, "Failed to enable DCB\n");
++ goto err_out_free_hw;
++ }
++
+ qlcnic_dcb_get_info(adapter->dcb);
+ err = qlcnic_setup_intr(adapter);
+
+diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
+index 8dcb49ed1f3d9..7fd9fe6a602bc 100644
+--- a/drivers/net/phy/xilinx_gmii2rgmii.c
++++ b/drivers/net/phy/xilinx_gmii2rgmii.c
+@@ -105,6 +105,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev)
+
+ if (!priv->phy_dev->drv) {
+ dev_info(dev, "Attached phy not ready\n");
++ put_device(&priv->phy_dev->mdio.dev);
+ return -EPROBE_DEFER;
+ }
+
+diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
+index f79333fe17836..7b3739b29c8f7 100644
+--- a/drivers/net/usb/rndis_host.c
++++ b/drivers/net/usb/rndis_host.c
+@@ -255,7 +255,8 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
+
+ off = le32_to_cpu(u.get_c->offset);
+ len = le32_to_cpu(u.get_c->len);
+- if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
++ if (unlikely((off > CONTROL_BUFFER_SIZE - 8) ||
++ (len > CONTROL_BUFFER_SIZE - 8 - off)))
+ goto response_error;
+
+ if (*reply_len != -1 && len != *reply_len)
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 466da01ba2e3e..909427d99a594 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -974,6 +974,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
+ xdp_set_return_frame_no_direct();
+ done = veth_xdp_rcv(rq, budget, &bq, &stats);
+
++ if (stats.xdp_redirect > 0)
++ xdp_do_flush();
++
+ if (done < budget && napi_complete_done(napi, done)) {
+ /* Write rx_notify_masked before reading ptr_ring */
+ smp_store_mb(rq->rx_notify_masked, false);
+@@ -987,8 +990,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
+
+ if (stats.xdp_tx > 0)
+ veth_xdp_flush(rq, &bq);
+- if (stats.xdp_redirect > 0)
+- xdp_do_flush();
+ xdp_clear_return_frame_no_direct();
+
+ return done;
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index c28c4a654615c..c312d16f580c9 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -1288,6 +1288,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ (le32_to_cpu(gdesc->dword[3]) &
+ VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ if ((le32_to_cpu(gdesc->dword[0]) &
++ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++ skb->csum_level = 1;
++ }
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ !(le32_to_cpu(gdesc->dword[0]) &
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+@@ -1297,6 +1301,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ } else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
+ (1 << VMXNET3_RCD_TUC_SHIFT))) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ if ((le32_to_cpu(gdesc->dword[0]) &
++ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++ skb->csum_level = 1;
++ }
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ !(le32_to_cpu(gdesc->dword[0]) &
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 5df7a0abc39d5..f7f40e3fe9cce 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -1385,8 +1385,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
+
+ /* loopback, multicast & non-ND link-local traffic; do not push through
+ * packet taps again. Reset pkt_type for upper layers to process skb.
+- * For strict packets with a source LLA, determine the dst using the
+- * original ifindex.
++ * For non-loopback strict packets, determine the dst using the original
++ * ifindex.
+ */
+ if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
+ skb->dev = vrf_dev;
+@@ -1395,7 +1395,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
+
+ if (skb->pkt_type == PACKET_LOOPBACK)
+ skb->pkt_type = PACKET_HOST;
+- else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)
++ else
+ vrf_ip6_input_dst(skb, vrf_dev, orig_iif);
+
+ goto out;
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index c3285242f74fb..a03752ef544f4 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2920,16 +2920,23 @@ static int vxlan_init(struct net_device *dev)
+ vxlan_vnigroup_init(vxlan);
+
+ dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+- if (!dev->tstats)
+- return -ENOMEM;
++ if (!dev->tstats) {
++ err = -ENOMEM;
++ goto err_vnigroup_uninit;
++ }
+
+ err = gro_cells_init(&vxlan->gro_cells, dev);
+- if (err) {
+- free_percpu(dev->tstats);
+- return err;
+- }
++ if (err)
++ goto err_free_percpu;
+
+ return 0;
++
++err_free_percpu:
++ free_percpu(dev->tstats);
++err_vnigroup_uninit:
++ if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
++ vxlan_vnigroup_uninit(vxlan);
++ return err;
+ }
+
+ static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan, __be32 vni)
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 30f0765fb9fd8..237f4ec2cffd7 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -327,9 +327,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+ }
+
+ #ifdef CONFIG_ATH9K_HTC_DEBUGFS
+-#define __STAT_SAFE(hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0)
+-#define CAB_STAT_INC(priv) ((priv)->debug.tx_stats.cab_queued++)
+-#define TX_QSTAT_INC(priv, q) ((priv)->debug.tx_stats.queue_stats[q]++)
++#define __STAT_SAFE(hif_dev, expr) do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0)
++#define CAB_STAT_INC(priv) do { ((priv)->debug.tx_stats.cab_queued++); } while (0)
++#define TX_QSTAT_INC(priv, q) do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0)
+
+ #define TX_STAT_INC(hif_dev, c) \
+ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
+@@ -378,10 +378,10 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
+ struct ethtool_stats *stats, u64 *data);
+ #else
+
+-#define TX_STAT_INC(hif_dev, c)
+-#define TX_STAT_ADD(hif_dev, c, a)
+-#define RX_STAT_INC(hif_dev, c)
+-#define RX_STAT_ADD(hif_dev, c, a)
++#define TX_STAT_INC(hif_dev, c) do { } while (0)
++#define TX_STAT_ADD(hif_dev, c, a) do { } while (0)
++#define RX_STAT_INC(hif_dev, c) do { } while (0)
++#define RX_STAT_ADD(hif_dev, c, a) do { } while (0)
+
+ #define CAB_STAT_INC(priv)
+ #define TX_QSTAT_INC(priv, c)
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 3582a28a1dcec..f06bae83e8ee0 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1069,6 +1069,18 @@ static u32 nvme_known_admin_effects(u8 opcode)
+ return 0;
+ }
+
++static u32 nvme_known_nvm_effects(u8 opcode)
++{
++ switch (opcode) {
++ case nvme_cmd_write:
++ case nvme_cmd_write_zeroes:
++ case nvme_cmd_write_uncor:
++ return NVME_CMD_EFFECTS_LBCC;
++ default:
++ return 0;
++ }
++}
++
+ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ {
+ u32 effects = 0;
+@@ -1076,16 +1088,24 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ if (ns) {
+ if (ns->head->effects)
+ effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
++ if (ns->head->ids.csi == NVME_CAP_CSS_NVM)
++ effects |= nvme_known_nvm_effects(opcode);
+ if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
+ dev_warn_once(ctrl->device,
+- "IO command:%02x has unhandled effects:%08x\n",
++ "IO command:%02x has unusual effects:%08x\n",
+ opcode, effects);
+- return 0;
+- }
+
+- if (ctrl->effects)
+- effects = le32_to_cpu(ctrl->effects->acs[opcode]);
+- effects |= nvme_known_admin_effects(opcode);
++ /*
++ * NVME_CMD_EFFECTS_CSE_MASK causes a freeze all I/O queues,
++ * which would deadlock when done on an I/O command. Note that
++ * We already warn about an unusual effect above.
++ */
++ effects &= ~NVME_CMD_EFFECTS_CSE_MASK;
++ } else {
++ if (ctrl->effects)
++ effects = le32_to_cpu(ctrl->effects->acs[opcode]);
++ effects |= nvme_known_admin_effects(opcode);
++ }
+
+ return effects;
+ }
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 70555022cb445..35352206b5dee 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -872,7 +872,7 @@ static inline void nvme_trace_bio_complete(struct request *req)
+ {
+ struct nvme_ns *ns = req->q->queuedata;
+
+- if (req->cmd_flags & REQ_NVME_MPATH)
++ if ((req->cmd_flags & REQ_NVME_MPATH) && req->bio)
+ trace_block_bio_complete(ns->head->disk->queue, req->bio);
+ }
+
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index fc8a957fad0ac..4aaa27cc8d2bd 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -164,26 +164,29 @@ out:
+
+ static void nvmet_get_cmd_effects_nvm(struct nvme_effects_log *log)
+ {
+- log->acs[nvme_admin_get_log_page] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_identify] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_abort_cmd] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_set_features] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_get_features] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_async_event] = cpu_to_le32(1 << 0);
+- log->acs[nvme_admin_keep_alive] = cpu_to_le32(1 << 0);
+-
+- log->iocs[nvme_cmd_read] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_write] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_flush] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_dsm] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_write_zeroes] = cpu_to_le32(1 << 0);
++ log->acs[nvme_admin_get_log_page] =
++ log->acs[nvme_admin_identify] =
++ log->acs[nvme_admin_abort_cmd] =
++ log->acs[nvme_admin_set_features] =
++ log->acs[nvme_admin_get_features] =
++ log->acs[nvme_admin_async_event] =
++ log->acs[nvme_admin_keep_alive] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
++
++ log->iocs[nvme_cmd_read] =
++ log->iocs[nvme_cmd_write] =
++ log->iocs[nvme_cmd_flush] =
++ log->iocs[nvme_cmd_dsm] =
++ log->iocs[nvme_cmd_write_zeroes] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+
+ static void nvmet_get_cmd_effects_zns(struct nvme_effects_log *log)
+ {
+- log->iocs[nvme_cmd_zone_append] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_zone_mgmt_send] = cpu_to_le32(1 << 0);
+- log->iocs[nvme_cmd_zone_mgmt_recv] = cpu_to_le32(1 << 0);
++ log->iocs[nvme_cmd_zone_append] =
++ log->iocs[nvme_cmd_zone_mgmt_send] =
++ log->iocs[nvme_cmd_zone_mgmt_recv] =
++ cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+
+ static void nvmet_execute_get_log_cmd_effects_ns(struct nvmet_req *req)
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 1c573e7a60bc8..f4bfaf1669fb3 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -1106,7 +1106,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
+ */
+ int __init early_init_dt_scan_memory(void)
+ {
+- int node;
++ int node, found_memory = 0;
+ const void *fdt = initial_boot_params;
+
+ fdt_for_each_subnode(node, fdt, 0) {
+@@ -1146,6 +1146,8 @@ int __init early_init_dt_scan_memory(void)
+
+ early_init_dt_add_memory_arch(base, size);
+
++ found_memory = 1;
++
+ if (!hotpluggable)
+ continue;
+
+@@ -1154,7 +1156,7 @@ int __init early_init_dt_scan_memory(void)
+ base, base + size);
+ }
+ }
+- return 0;
++ return found_memory;
+ }
+
+ int __init early_init_dt_scan_chosen(char *cmdline)
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 0feda8eb93b52..5e011520650de 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -767,6 +767,7 @@ struct qcom_qmp {
+ struct regulator_bulk_data *vregs;
+
+ struct qmp_phy **phys;
++ struct qmp_phy *usb_phy;
+
+ struct mutex phy_mutex;
+ int init_count;
+@@ -1607,7 +1608,7 @@ static int qcom_qmp_phy_combo_com_init(struct qmp_phy *qphy)
+ {
+ struct qcom_qmp *qmp = qphy->qmp;
+ const struct qmp_phy_cfg *cfg = qphy->cfg;
+- void __iomem *pcs = qphy->pcs;
++ struct qmp_phy *usb_phy = qmp->usb_phy;
+ void __iomem *dp_com = qmp->dp_com;
+ int ret;
+
+@@ -1663,13 +1664,13 @@ static int qcom_qmp_phy_combo_com_init(struct qmp_phy *qphy)
+ qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
+ }
+
+- if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
+- qphy_setbits(pcs,
+- cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+- cfg->pwrdn_ctrl);
++ if (usb_phy->cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++ qphy_setbits(usb_phy->pcs,
++ usb_phy->cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++ usb_phy->cfg->pwrdn_ctrl);
+ else
+- qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
+- cfg->pwrdn_ctrl);
++ qphy_setbits(usb_phy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
++ usb_phy->cfg->pwrdn_ctrl);
+
+ mutex_unlock(&qmp->phy_mutex);
+
+@@ -2576,6 +2577,8 @@ static int qcom_qmp_phy_combo_probe(struct platform_device *pdev)
+ goto err_node_put;
+ }
+
++ qmp->usb_phy = qmp->phys[id];
++
+ /*
+ * Register the pipe clock provided by phy.
+ * See function description to see details of this pipe clock.
+@@ -2591,6 +2594,9 @@ static int qcom_qmp_phy_combo_probe(struct platform_device *pdev)
+ id++;
+ }
+
++ if (!qmp->usb_phy)
++ return -EINVAL;
++
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (!IS_ERR(phy_provider))
+ dev_info(dev, "Registered Qcom-QMP phy\n");
+diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+index 8c42e76620333..92ed1213fe379 100644
+--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+@@ -172,6 +172,7 @@ static const struct attribute_group fivr_attribute_group = {
+ RFIM_SHOW(rfi_restriction_run_busy, 1)
+ RFIM_SHOW(rfi_restriction_err_code, 1)
+ RFIM_SHOW(rfi_restriction_data_rate, 1)
++RFIM_SHOW(rfi_restriction_data_rate_base, 1)
+ RFIM_SHOW(ddr_data_rate_point_0, 1)
+ RFIM_SHOW(ddr_data_rate_point_1, 1)
+ RFIM_SHOW(ddr_data_rate_point_2, 1)
+@@ -181,11 +182,13 @@ RFIM_SHOW(rfi_disable, 1)
+ RFIM_STORE(rfi_restriction_run_busy, 1)
+ RFIM_STORE(rfi_restriction_err_code, 1)
+ RFIM_STORE(rfi_restriction_data_rate, 1)
++RFIM_STORE(rfi_restriction_data_rate_base, 1)
+ RFIM_STORE(rfi_disable, 1)
+
+ static DEVICE_ATTR_RW(rfi_restriction_run_busy);
+ static DEVICE_ATTR_RW(rfi_restriction_err_code);
+ static DEVICE_ATTR_RW(rfi_restriction_data_rate);
++static DEVICE_ATTR_RW(rfi_restriction_data_rate_base);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_0);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_1);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_2);
+@@ -248,6 +251,7 @@ static struct attribute *dvfs_attrs[] = {
+ &dev_attr_rfi_restriction_run_busy.attr,
+ &dev_attr_rfi_restriction_err_code.attr,
+ &dev_attr_rfi_restriction_data_rate.attr,
++ &dev_attr_rfi_restriction_data_rate_base.attr,
+ &dev_attr_ddr_data_rate_point_0.attr,
+ &dev_attr_ddr_data_rate_point_1.attr,
+ &dev_attr_ddr_data_rate_point_2.attr,
+diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
+index 67b237c7a76a1..550ae64350df0 100644
+--- a/drivers/usb/dwc3/dwc3-xilinx.c
++++ b/drivers/usb/dwc3/dwc3-xilinx.c
+@@ -13,6 +13,7 @@
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/of_gpio.h>
+ #include <linux/of_platform.h>
+ #include <linux/pm_runtime.h>
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index c2075b90f3dfe..40f75ba53e80e 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1702,6 +1702,7 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
+ else if (!ret)
+ dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+
++ dep->flags &= ~DWC3_EP_DELAY_STOP;
+ return ret;
+ }
+
+@@ -3701,8 +3702,10 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
+ return;
+
++ if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
++ return;
++
+ if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+- (dep->flags & DWC3_EP_DELAY_STOP) ||
+ (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+ return;
+
+diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+index 90913365def43..444d6572b2d05 100644
+--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+@@ -1468,11 +1468,13 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac,
+ dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16);
+ eth_broadcast_addr(dmac_c);
+ ether_addr_copy(dmac_v, mac);
+- MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
++ if (ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN)) {
++ MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
++ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid);
++ }
+ if (tagged) {
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1);
+- MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid);
+- MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, vid);
++ MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, vid);
+ }
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+@@ -1684,7 +1686,7 @@ static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
+
+ /* Need recreate the flow table entry, so that the packet could forward back
+ */
+- mac_vlan_del(ndev, ndev->config.mac, 0, false);
++ mac_vlan_del(ndev, mac_back, 0, false);
+
+ if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
+ mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+index 225b7f5d8be35..6489f44bca1af 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+@@ -66,8 +66,7 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
+ {
+ struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
+
+- vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features,
+- VDPASIM_QUEUE_MAX, false,
++ vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, false,
+ (struct vring_desc *)(uintptr_t)vq->desc_addr,
+ (struct vring_avail *)
+ (uintptr_t)vq->driver_addr,
+@@ -680,7 +679,9 @@ static void vdpasim_free(struct vdpa_device *vdpa)
+ }
+
+ kvfree(vdpasim->buffer);
+- vhost_iotlb_free(vdpasim->iommu);
++ for (i = 0; i < vdpasim->dev_attr.nas; i++)
++ vhost_iotlb_reset(&vdpasim->iommu[i]);
++ kfree(vdpasim->iommu);
+ kfree(vdpasim->vqs);
+ kfree(vdpasim->config);
+ }
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+index c8bfea3b7db23..cc0534f8ae934 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+@@ -427,8 +427,10 @@ static int __init vdpasim_blk_init(void)
+ int ret;
+
+ ret = device_register(&vdpasim_blk_mgmtdev);
+- if (ret)
++ if (ret) {
++ put_device(&vdpasim_blk_mgmtdev);
+ return ret;
++ }
+
+ ret = vdpa_mgmtdev_register(&mgmt_dev);
+ if (ret)
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+index 886449e885026..c2e19dd064198 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+@@ -304,8 +304,10 @@ static int __init vdpasim_net_init(void)
+ int ret;
+
+ ret = device_register(&vdpasim_net_mgmtdev);
+- if (ret)
++ if (ret) {
++ put_device(&vdpasim_net_mgmtdev);
+ return ret;
++ }
+
+ ret = vdpa_mgmtdev_register(&mgmt_dev);
+ if (ret)
+diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
+index 04522077735b2..f4e375b1d903c 100644
+--- a/drivers/vdpa/virtio_pci/vp_vdpa.c
++++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
+@@ -629,7 +629,7 @@ static void vp_vdpa_remove(struct pci_dev *pdev)
+ mdev = vp_vdpa_mgtdev->mdev;
+ vp_modern_remove(mdev);
+ vdpa_mgmtdev_unregister(&vp_vdpa_mgtdev->mgtdev);
+- kfree(&vp_vdpa_mgtdev->mgtdev.id_table);
++ kfree(vp_vdpa_mgtdev->mgtdev.id_table);
+ kfree(mdev);
+ kfree(vp_vdpa_mgtdev);
+ }
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index 166044642fd5c..ec32f785dfdec 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -65,6 +65,10 @@ static DEFINE_IDA(vhost_vdpa_ida);
+
+ static dev_t vhost_vdpa_major;
+
++static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v,
++ struct vhost_iotlb *iotlb, u64 start,
++ u64 last, u32 asid);
++
+ static inline u32 iotlb_to_asid(struct vhost_iotlb *iotlb)
+ {
+ struct vhost_vdpa_as *as = container_of(iotlb, struct
+@@ -135,7 +139,7 @@ static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid)
+ return -EINVAL;
+
+ hlist_del(&as->hash_link);
+- vhost_iotlb_reset(&as->iotlb);
++ vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid);
+ kfree(as);
+
+ return 0;
+@@ -683,10 +687,20 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
+ mutex_unlock(&d->mutex);
+ return r;
+ }
++static void vhost_vdpa_general_unmap(struct vhost_vdpa *v,
++ struct vhost_iotlb_map *map, u32 asid)
++{
++ struct vdpa_device *vdpa = v->vdpa;
++ const struct vdpa_config_ops *ops = vdpa->config;
++ if (ops->dma_map) {
++ ops->dma_unmap(vdpa, asid, map->start, map->size);
++ } else if (ops->set_map == NULL) {
++ iommu_unmap(v->domain, map->start, map->size);
++ }
++}
+
+-static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v,
+- struct vhost_iotlb *iotlb,
+- u64 start, u64 last)
++static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb,
++ u64 start, u64 last, u32 asid)
+ {
+ struct vhost_dev *dev = &v->vdev;
+ struct vhost_iotlb_map *map;
+@@ -703,13 +717,13 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v,
+ unpin_user_page(page);
+ }
+ atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
++ vhost_vdpa_general_unmap(v, map, asid);
+ vhost_iotlb_map_free(iotlb, map);
+ }
+ }
+
+-static void vhost_vdpa_va_unmap(struct vhost_vdpa *v,
+- struct vhost_iotlb *iotlb,
+- u64 start, u64 last)
++static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb,
++ u64 start, u64 last, u32 asid)
+ {
+ struct vhost_iotlb_map *map;
+ struct vdpa_map_file *map_file;
+@@ -718,20 +732,21 @@ static void vhost_vdpa_va_unmap(struct vhost_vdpa *v,
+ map_file = (struct vdpa_map_file *)map->opaque;
+ fput(map_file->file);
+ kfree(map_file);
++ vhost_vdpa_general_unmap(v, map, asid);
+ vhost_iotlb_map_free(iotlb, map);
+ }
+ }
+
+ static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v,
+- struct vhost_iotlb *iotlb,
+- u64 start, u64 last)
++ struct vhost_iotlb *iotlb, u64 start,
++ u64 last, u32 asid)
+ {
+ struct vdpa_device *vdpa = v->vdpa;
+
+ if (vdpa->use_va)
+- return vhost_vdpa_va_unmap(v, iotlb, start, last);
++ return vhost_vdpa_va_unmap(v, iotlb, start, last, asid);
+
+- return vhost_vdpa_pa_unmap(v, iotlb, start, last);
++ return vhost_vdpa_pa_unmap(v, iotlb, start, last, asid);
+ }
+
+ static int perm_to_iommu_flags(u32 perm)
+@@ -798,17 +813,12 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v,
+ const struct vdpa_config_ops *ops = vdpa->config;
+ u32 asid = iotlb_to_asid(iotlb);
+
+- vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1);
++ vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1, asid);
+
+- if (ops->dma_map) {
+- ops->dma_unmap(vdpa, asid, iova, size);
+- } else if (ops->set_map) {
++ if (ops->set_map) {
+ if (!v->in_batch)
+ ops->set_map(vdpa, asid, iotlb);
+- } else {
+- iommu_unmap(v->domain, iova, size);
+ }
+-
+ /* If we are in the middle of batch processing, delay the free
+ * of AS until BATCH_END.
+ */
+@@ -1162,14 +1172,14 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v)
+ struct vhost_vdpa_as *as;
+ u32 asid;
+
+- vhost_dev_cleanup(&v->vdev);
+- kfree(v->vdev.vqs);
+-
+ for (asid = 0; asid < v->vdpa->nas; asid++) {
+ as = asid_to_as(v, asid);
+ if (as)
+ vhost_vdpa_remove_as(v, asid);
+ }
++
++ vhost_dev_cleanup(&v->vdev);
++ kfree(v->vdev.vqs);
+ }
+
+ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
+diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
+index 40097826cff0b..3c2359570df9d 100644
+--- a/drivers/vhost/vhost.c
++++ b/drivers/vhost/vhost.c
+@@ -2053,7 +2053,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ struct vhost_dev *dev = vq->dev;
+ struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem;
+ struct iovec *_iov;
+- u64 s = 0;
++ u64 s = 0, last = addr + len - 1;
+ int ret = 0;
+
+ while ((u64)len > s) {
+@@ -2063,7 +2063,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ break;
+ }
+
+- map = vhost_iotlb_itree_first(umem, addr, addr + len - 1);
++ map = vhost_iotlb_itree_first(umem, addr, last);
+ if (map == NULL || map->start > addr) {
+ if (umem != dev->iotlb) {
+ ret = -EFAULT;
+diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
+index 11f59dd06a74e..828c293065657 100644
+--- a/drivers/vhost/vringh.c
++++ b/drivers/vhost/vringh.c
+@@ -1102,7 +1102,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ struct vhost_iotlb_map *map;
+ struct vhost_iotlb *iotlb = vrh->iotlb;
+ int ret = 0;
+- u64 s = 0;
++ u64 s = 0, last = addr + len - 1;
+
+ spin_lock(vrh->iotlb_lock);
+
+@@ -1114,8 +1114,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ break;
+ }
+
+- map = vhost_iotlb_itree_first(iotlb, addr,
+- addr + len - 1);
++ map = vhost_iotlb_itree_first(iotlb, addr, last);
+ if (!map || map->start > addr) {
+ ret = -EINVAL;
+ break;
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index 5703775af1297..10a7d23731fef 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -959,7 +959,14 @@ static int __init vhost_vsock_init(void)
+ VSOCK_TRANSPORT_F_H2G);
+ if (ret < 0)
+ return ret;
+- return misc_register(&vhost_vsock_misc);
++
++ ret = misc_register(&vhost_vsock_misc);
++ if (ret) {
++ vsock_core_unregister(&vhost_transport.transport);
++ return ret;
++ }
++
++ return 0;
+ };
+
+ static void __exit vhost_vsock_exit(void)
+diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
+index 68bba2688f4c1..3d1bca3bcd4fd 100644
+--- a/drivers/video/fbdev/matrox/matroxfb_base.c
++++ b/drivers/video/fbdev/matrox/matroxfb_base.c
+@@ -1377,8 +1377,8 @@ static struct video_board vbG200 = {
+ .lowlevel = &matrox_G100
+ };
+ static struct video_board vbG200eW = {
+- .maxvram = 0x100000,
+- .maxdisplayable = 0x800000,
++ .maxvram = 0x1000000,
++ .maxdisplayable = 0x0800000,
+ .accelID = FB_ACCEL_MATROX_MGAG200,
+ .lowlevel = &matrox_G100
+ };
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index 06be0644dd376..6ce704d3bdd27 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -424,6 +424,7 @@ void btrfs_init_root_block_rsv(struct btrfs_root *root)
+ case BTRFS_CSUM_TREE_OBJECTID:
+ case BTRFS_EXTENT_TREE_OBJECTID:
+ case BTRFS_FREE_SPACE_TREE_OBJECTID:
++ case BTRFS_BLOCK_GROUP_TREE_OBJECTID:
+ root->block_rsv = &fs_info->delayed_refs_rsv;
+ break;
+ case BTRFS_ROOT_TREE_OBJECTID:
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index bad06add93d7e..8e77acdecd252 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -280,14 +280,9 @@ struct btrfs_super_block {
+ /* the UUID written into btree blocks */
+ u8 metadata_uuid[BTRFS_FSID_SIZE];
+
+- /* Extent tree v2 */
+- __le64 block_group_root;
+- __le64 block_group_root_generation;
+- u8 block_group_root_level;
+-
+ /* future expansion */
+- u8 reserved8[7];
+- __le64 reserved[25];
++ u8 reserved8[8];
++ __le64 reserved[27];
+ u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
+ struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
+
+@@ -307,7 +302,8 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
+ #define BTRFS_FEATURE_COMPAT_RO_SUPP \
+ (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \
+ BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID | \
+- BTRFS_FEATURE_COMPAT_RO_VERITY)
++ BTRFS_FEATURE_COMPAT_RO_VERITY | \
++ BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE)
+
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL
+@@ -2391,17 +2387,6 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
+ BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
+ num_devices, 64);
+
+-/*
+- * For extent tree v2 we overload the extent root with the block group root, as
+- * we will have multiple extent roots.
+- */
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup,
+- extent_root, 64);
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup,
+- extent_root_gen, 64);
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level,
+- struct btrfs_root_backup, extent_root_level, 8);
+-
+ /* struct btrfs_balance_item */
+ BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64);
+
+@@ -2534,13 +2519,6 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
+ BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
+ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
+ uuid_tree_generation, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block,
+- block_group_root, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation,
+- struct btrfs_super_block,
+- block_group_root_generation, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block,
+- block_group_root_level, 8);
+
+ int btrfs_super_csum_size(const struct btrfs_super_block *s);
+ const char *btrfs_super_csum_name(u16 csum_type);
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index aa4bc213d301b..23bb51e46e596 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -167,11 +167,9 @@ static bool btrfs_supported_super_csum(u16 csum_type)
+ * Return 0 if the superblock checksum type matches the checksum value of that
+ * algorithm. Pass the raw disk superblock data.
+ */
+-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+- char *raw_disk_sb)
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++ const struct btrfs_super_block *disk_sb)
+ {
+- struct btrfs_super_block *disk_sb =
+- (struct btrfs_super_block *)raw_disk_sb;
+ char result[BTRFS_CSUM_SIZE];
+ SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
+
+@@ -182,7 +180,7 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+ * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
+ * filled with zeros and is included in the checksum.
+ */
+- crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
++ crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE,
+ BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result);
+
+ if (memcmp(disk_sb->csum, result, fs_info->csum_size))
+@@ -1524,6 +1522,9 @@ static struct btrfs_root *btrfs_get_global_root(struct btrfs_fs_info *fs_info,
+ if (objectid == BTRFS_UUID_TREE_OBJECTID)
+ return btrfs_grab_root(fs_info->uuid_root) ?
+ fs_info->uuid_root : ERR_PTR(-ENOENT);
++ if (objectid == BTRFS_BLOCK_GROUP_TREE_OBJECTID)
++ return btrfs_grab_root(fs_info->block_group_root) ?
++ fs_info->block_group_root : ERR_PTR(-ENOENT);
+ if (objectid == BTRFS_FREE_SPACE_TREE_OBJECTID) {
+ struct btrfs_root *root = btrfs_global_root(fs_info, &key);
+
+@@ -1980,14 +1981,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ btrfs_set_backup_chunk_root_level(root_backup,
+ btrfs_header_level(info->chunk_root->node));
+
+- if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+- btrfs_set_backup_block_group_root(root_backup,
+- info->block_group_root->node->start);
+- btrfs_set_backup_block_group_root_gen(root_backup,
+- btrfs_header_generation(info->block_group_root->node));
+- btrfs_set_backup_block_group_root_level(root_backup,
+- btrfs_header_level(info->block_group_root->node));
+- } else {
++ if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
+ struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+@@ -2529,10 +2523,24 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
+ if (ret)
+ return ret;
+
+- location.objectid = BTRFS_DEV_TREE_OBJECTID;
+ location.type = BTRFS_ROOT_ITEM_KEY;
+ location.offset = 0;
+
++ if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE)) {
++ location.objectid = BTRFS_BLOCK_GROUP_TREE_OBJECTID;
++ root = btrfs_read_tree_root(tree_root, &location);
++ if (IS_ERR(root)) {
++ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
++ ret = PTR_ERR(root);
++ goto out;
++ }
++ } else {
++ set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
++ fs_info->block_group_root = root;
++ }
++ }
++
++ location.objectid = BTRFS_DEV_TREE_OBJECTID;
+ root = btrfs_read_tree_root(tree_root, &location);
+ if (IS_ERR(root)) {
+ if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
+@@ -2602,8 +2610,8 @@ out:
+ * 1, 2 2nd and 3rd backup copy
+ * -1 skip bytenr check
+ */
+-static int validate_super(struct btrfs_fs_info *fs_info,
+- struct btrfs_super_block *sb, int mirror_num)
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++ struct btrfs_super_block *sb, int mirror_num)
+ {
+ u64 nodesize = btrfs_super_nodesize(sb);
+ u64 sectorsize = btrfs_super_sectorsize(sb);
+@@ -2705,6 +2713,18 @@ static int validate_super(struct btrfs_fs_info *fs_info,
+ ret = -EINVAL;
+ }
+
++ /*
++ * Artificial requirement for block-group-tree to force newer features
++ * (free-space-tree, no-holes) so the test matrix is smaller.
++ */
++ if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
++ (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
++ !btrfs_fs_incompat(fs_info, NO_HOLES))) {
++ btrfs_err(fs_info,
++ "block-group-tree feature requires fres-space-tree and no-holes");
++ ret = -EINVAL;
++ }
++
+ if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
+ BTRFS_FSID_SIZE) != 0) {
+ btrfs_err(fs_info,
+@@ -2787,7 +2807,7 @@ static int validate_super(struct btrfs_fs_info *fs_info,
+ */
+ static int btrfs_validate_mount_super(struct btrfs_fs_info *fs_info)
+ {
+- return validate_super(fs_info, fs_info->super_copy, 0);
++ return btrfs_validate_super(fs_info, fs_info->super_copy, 0);
+ }
+
+ /*
+@@ -2801,7 +2821,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
+ {
+ int ret;
+
+- ret = validate_super(fs_info, sb, -1);
++ ret = btrfs_validate_super(fs_info, sb, -1);
+ if (ret < 0)
+ goto out;
+ if (!btrfs_supported_super_csum(btrfs_super_csum_type(sb))) {
+@@ -2862,17 +2882,7 @@ static int load_important_roots(struct btrfs_fs_info *fs_info)
+ btrfs_warn(fs_info, "couldn't read tree root");
+ return ret;
+ }
+-
+- if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+- return 0;
+-
+- bytenr = btrfs_super_block_group_root(sb);
+- gen = btrfs_super_block_group_root_generation(sb);
+- level = btrfs_super_block_group_root_level(sb);
+- ret = load_super_root(fs_info->block_group_root, bytenr, gen, level);
+- if (ret)
+- btrfs_warn(fs_info, "couldn't read block group root");
+- return ret;
++ return 0;
+ }
+
+ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
+@@ -2884,16 +2894,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
+ int ret = 0;
+ int i;
+
+- if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+- struct btrfs_root *root;
+-
+- root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID,
+- GFP_KERNEL);
+- if (!root)
+- return -ENOMEM;
+- fs_info->block_group_root = root;
+- }
+-
+ for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
+ if (handle_error) {
+ if (!IS_ERR(tree_root->node))
+@@ -3281,6 +3281,114 @@ out:
+ return ret;
+ }
+
++/*
++ * Do various sanity and dependency checks of different features.
++ *
++ * @is_rw_mount: If the mount is read-write.
++ *
++ * This is the place for less strict checks (like for subpage or artificial
++ * feature dependencies).
++ *
++ * For strict checks or possible corruption detection, see
++ * btrfs_validate_super().
++ *
++ * This should be called after btrfs_parse_options(), as some mount options
++ * (space cache related) can modify on-disk format like free space tree and
++ * screw up certain feature dependencies.
++ */
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
++{
++ struct btrfs_super_block *disk_super = fs_info->super_copy;
++ u64 incompat = btrfs_super_incompat_flags(disk_super);
++ const u64 compat_ro = btrfs_super_compat_ro_flags(disk_super);
++ const u64 compat_ro_unsupp = (compat_ro & ~BTRFS_FEATURE_COMPAT_RO_SUPP);
++
++ if (incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP) {
++ btrfs_err(fs_info,
++ "cannot mount because of unknown incompat features (0x%llx)",
++ incompat);
++ return -EINVAL;
++ }
++
++ /* Runtime limitation for mixed block groups. */
++ if ((incompat & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
++ (fs_info->sectorsize != fs_info->nodesize)) {
++ btrfs_err(fs_info,
++"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
++ fs_info->nodesize, fs_info->sectorsize);
++ return -EINVAL;
++ }
++
++ /* Mixed backref is an always-enabled feature. */
++ incompat |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
++
++ /* Set compression related flags just in case. */
++ if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
++ incompat |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
++ else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
++ incompat |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD;
++
++ /*
++ * An ancient flag, which should really be marked deprecated.
++ * Such runtime limitation doesn't really need a incompat flag.
++ */
++ if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
++ incompat |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
++
++ if (compat_ro_unsupp && is_rw_mount) {
++ btrfs_err(fs_info,
++ "cannot mount read-write because of unknown compat_ro features (0x%llx)",
++ compat_ro);
++ return -EINVAL;
++ }
++
++ /*
++ * We have unsupported RO compat features, although RO mounted, we
++ * should not cause any metadata writes, including log replay.
++ * Or we could screw up whatever the new feature requires.
++ */
++ if (compat_ro_unsupp && btrfs_super_log_root(disk_super) &&
++ !btrfs_test_opt(fs_info, NOLOGREPLAY)) {
++ btrfs_err(fs_info,
++"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay",
++ compat_ro);
++ return -EINVAL;
++ }
++
++ /*
++ * Artificial limitations for block group tree, to force
++ * block-group-tree to rely on no-holes and free-space-tree.
++ */
++ if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
++ (!btrfs_fs_incompat(fs_info, NO_HOLES) ||
++ !btrfs_test_opt(fs_info, FREE_SPACE_TREE))) {
++ btrfs_err(fs_info,
++"block-group-tree feature requires no-holes and free-space-tree features");
++ return -EINVAL;
++ }
++
++ /*
++ * Subpage runtime limitation on v1 cache.
++ *
++ * V1 space cache still has some hard codeed PAGE_SIZE usage, while
++ * we're already defaulting to v2 cache, no need to bother v1 as it's
++ * going to be deprecated anyway.
++ */
++ if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
++ btrfs_warn(fs_info,
++ "v1 space cache is not supported for page size %lu with sectorsize %u",
++ PAGE_SIZE, fs_info->sectorsize);
++ return -EINVAL;
++ }
++
++ /* This can be called by remount, we need to protect the super block. */
++ spin_lock(&fs_info->super_lock);
++ btrfs_set_super_incompat_flags(disk_super, incompat);
++ spin_unlock(&fs_info->super_lock);
++
++ return 0;
++}
++
+ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices,
+ char *options)
+ {
+@@ -3361,7 +3469,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
+ * We want to check superblock checksum, the type is stored inside.
+ * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
+ */
+- if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) {
++ if (btrfs_check_super_csum(fs_info, disk_super)) {
+ btrfs_err(fs_info, "superblock checksum mismatch");
+ err = -EINVAL;
+ btrfs_release_disk_super(disk_super);
+@@ -3430,72 +3538,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
+ goto fail_alloc;
+ }
+
+- features = btrfs_super_incompat_flags(disk_super) &
+- ~BTRFS_FEATURE_INCOMPAT_SUPP;
+- if (features) {
+- btrfs_err(fs_info,
+- "cannot mount because of unsupported optional features (0x%llx)",
+- features);
+- err = -EINVAL;
+- goto fail_alloc;
+- }
+-
+- features = btrfs_super_incompat_flags(disk_super);
+- features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
+- if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
+- features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
+- else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
+- features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD;
+-
+- /*
+- * Flag our filesystem as having big metadata blocks if they are bigger
+- * than the page size.
+- */
+- if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
+- features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
+-
+- /*
+- * mixed block groups end up with duplicate but slightly offset
+- * extent buffers for the same range. It leads to corruptions
+- */
+- if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
+- (sectorsize != nodesize)) {
+- btrfs_err(fs_info,
+-"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
+- nodesize, sectorsize);
+- goto fail_alloc;
+- }
+-
+- /*
+- * Needn't use the lock because there is no other task which will
+- * update the flag.
+- */
+- btrfs_set_super_incompat_flags(disk_super, features);
+-
+- features = btrfs_super_compat_ro_flags(disk_super) &
+- ~BTRFS_FEATURE_COMPAT_RO_SUPP;
+- if (!sb_rdonly(sb) && features) {
+- btrfs_err(fs_info,
+- "cannot mount read-write because of unsupported optional features (0x%llx)",
+- features);
+- err = -EINVAL;
+- goto fail_alloc;
+- }
+- /*
+- * We have unsupported RO compat features, although RO mounted, we
+- * should not cause any metadata write, including log replay.
+- * Or we could screw up whatever the new feature requires.
+- */
+- if (unlikely(features && btrfs_super_log_root(disk_super) &&
+- !btrfs_test_opt(fs_info, NOLOGREPLAY))) {
+- btrfs_err(fs_info,
+-"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay",
+- features);
+- err = -EINVAL;
++ ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
++ if (ret < 0) {
++ err = ret;
+ goto fail_alloc;
+ }
+
+-
+ if (sectorsize < PAGE_SIZE) {
+ struct btrfs_subpage_info *subpage_info;
+
+@@ -3835,7 +3883,7 @@ static void btrfs_end_super_write(struct bio *bio)
+ }
+
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+- int copy_num)
++ int copy_num, bool drop_cache)
+ {
+ struct btrfs_super_block *super;
+ struct page *page;
+@@ -3853,6 +3901,19 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+ if (bytenr + BTRFS_SUPER_INFO_SIZE >= bdev_nr_bytes(bdev))
+ return ERR_PTR(-EINVAL);
+
++ if (drop_cache) {
++ /* This should only be called with the primary sb. */
++ ASSERT(copy_num == 0);
++
++ /*
++ * Drop the page of the primary superblock, so later read will
++ * always read from the device.
++ */
++ invalidate_inode_pages2_range(mapping,
++ bytenr >> PAGE_SHIFT,
++ (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
++ }
++
+ page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ if (IS_ERR(page))
+ return ERR_CAST(page);
+@@ -3884,7 +3945,7 @@ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev)
+ * later supers, using BTRFS_SUPER_MIRROR_MAX instead
+ */
+ for (i = 0; i < 1; i++) {
+- super = btrfs_read_dev_one_super(bdev, i);
++ super = btrfs_read_dev_one_super(bdev, i, false);
+ if (IS_ERR(super))
+ continue;
+
+diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
+index 47ad8e0a2d33f..7322af63c0cc7 100644
+--- a/fs/btrfs/disk-io.h
++++ b/fs/btrfs/disk-io.h
+@@ -42,14 +42,19 @@ struct extent_buffer *btrfs_find_create_tree_block(
+ void btrfs_clean_tree_block(struct extent_buffer *buf);
+ void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
+ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++ const struct btrfs_super_block *disk_sb);
+ int __cold open_ctree(struct super_block *sb,
+ struct btrfs_fs_devices *fs_devices,
+ char *options);
+ void __cold close_ctree(struct btrfs_fs_info *fs_info);
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++ struct btrfs_super_block *sb, int mirror_num);
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
+ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
+ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+- int copy_num);
++ int copy_num, bool drop_cache);
+ int btrfs_commit_super(struct btrfs_fs_info *fs_info);
+ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
+ struct btrfs_key *key);
+@@ -103,7 +108,7 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
+
+ static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
+ {
+- if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
++ if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE))
+ return fs_info->block_group_root;
+ return btrfs_extent_root(fs_info, 0);
+ }
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index cf4f19e80e2f7..0982995177a6d 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -2377,7 +2377,16 @@ static int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
+ &map_length, &bioc, mirror_num);
+ if (ret)
+ goto out_counter_dec;
+- BUG_ON(mirror_num != bioc->mirror_num);
++ /*
++ * This happens when dev-replace is also running, and the
++ * mirror_num indicates the dev-replace target.
++ *
++ * In this case, we don't need to do anything, as the read
++ * error just means the replace progress hasn't reached our
++ * read range, and later replace routine would handle it well.
++ */
++ if (mirror_num != bioc->mirror_num)
++ goto out_counter_dec;
+ }
+
+ sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 4fff0067bd2a9..c498d5e164eb0 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3750,13 +3750,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
+ di_args->bytes_used = btrfs_device_get_bytes_used(dev);
+ di_args->total_bytes = btrfs_device_get_total_bytes(dev);
+ memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
+- if (dev->name) {
+- strncpy(di_args->path, rcu_str_deref(dev->name),
+- sizeof(di_args->path) - 1);
+- di_args->path[sizeof(di_args->path) - 1] = 0;
+- } else {
++ if (dev->name)
++ strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path));
++ else
+ di_args->path[0] = '\0';
+- }
+
+ out:
+ rcu_read_unlock();
+diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h
+index 5c1a617eb25de..5c2b66d155ef7 100644
+--- a/fs/btrfs/rcu-string.h
++++ b/fs/btrfs/rcu-string.h
+@@ -18,7 +18,11 @@ static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask)
+ (len * sizeof(char)), mask);
+ if (!ret)
+ return ret;
+- strncpy(ret->str, src, len);
++ /* Warn if the source got unexpectedly truncated. */
++ if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
++ kfree(ret);
++ return NULL;
++ }
+ return ret;
+ }
+
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index ad3ce9700eaf3..01c381e75cdbb 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2012,14 +2012,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ if (ret)
+ goto restore;
+
+- /* V1 cache is not supported for subpage mount. */
+- if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
+- btrfs_warn(fs_info,
+- "v1 space cache is not supported for page size %lu with sectorsize %u",
+- PAGE_SIZE, fs_info->sectorsize);
+- ret = -EINVAL;
++ ret = btrfs_check_features(fs_info, !(*flags & SB_RDONLY));
++ if (ret < 0)
+ goto restore;
+- }
++
+ btrfs_remount_begin(fs_info, old_opts, *flags);
+ btrfs_resize_thread_pool(fs_info,
+ fs_info->thread_pool_size, old_thread_pool_size);
+@@ -2115,15 +2111,6 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ ret = -EINVAL;
+ goto restore;
+ }
+- if (btrfs_super_compat_ro_flags(fs_info->super_copy) &
+- ~BTRFS_FEATURE_COMPAT_RO_SUPP) {
+- btrfs_err(fs_info,
+- "can not remount read-write due to unsupported optional flags 0x%llx",
+- btrfs_super_compat_ro_flags(fs_info->super_copy) &
+- ~BTRFS_FEATURE_COMPAT_RO_SUPP);
+- ret = -EINVAL;
+- goto restore;
+- }
+ if (fs_info->fs_devices->rw_devices == 0) {
+ ret = -EACCES;
+ goto restore;
+@@ -2562,11 +2549,87 @@ static int btrfs_freeze(struct super_block *sb)
+ return btrfs_commit_transaction(trans);
+ }
+
++static int check_dev_super(struct btrfs_device *dev)
++{
++ struct btrfs_fs_info *fs_info = dev->fs_info;
++ struct btrfs_super_block *sb;
++ u16 csum_type;
++ int ret = 0;
++
++ /* This should be called with fs still frozen. */
++ ASSERT(test_bit(BTRFS_FS_FROZEN, &fs_info->flags));
++
++ /* Missing dev, no need to check. */
++ if (!dev->bdev)
++ return 0;
++
++ /* Only need to check the primary super block. */
++ sb = btrfs_read_dev_one_super(dev->bdev, 0, true);
++ if (IS_ERR(sb))
++ return PTR_ERR(sb);
++
++ /* Verify the checksum. */
++ csum_type = btrfs_super_csum_type(sb);
++ if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) {
++ btrfs_err(fs_info, "csum type changed, has %u expect %u",
++ csum_type, btrfs_super_csum_type(fs_info->super_copy));
++ ret = -EUCLEAN;
++ goto out;
++ }
++
++ if (btrfs_check_super_csum(fs_info, sb)) {
++ btrfs_err(fs_info, "csum for on-disk super block no longer matches");
++ ret = -EUCLEAN;
++ goto out;
++ }
++
++ /* Btrfs_validate_super() includes fsid check against super->fsid. */
++ ret = btrfs_validate_super(fs_info, sb, 0);
++ if (ret < 0)
++ goto out;
++
++ if (btrfs_super_generation(sb) != fs_info->last_trans_committed) {
++ btrfs_err(fs_info, "transid mismatch, has %llu expect %llu",
++ btrfs_super_generation(sb),
++ fs_info->last_trans_committed);
++ ret = -EUCLEAN;
++ goto out;
++ }
++out:
++ btrfs_release_disk_super(sb);
++ return ret;
++}
++
+ static int btrfs_unfreeze(struct super_block *sb)
+ {
+ struct btrfs_fs_info *fs_info = btrfs_sb(sb);
++ struct btrfs_device *device;
++ int ret = 0;
+
++ /*
++ * Make sure the fs is not changed by accident (like hibernation then
++ * modified by other OS).
++ * If we found anything wrong, we mark the fs error immediately.
++ *
++ * And since the fs is frozen, no one can modify the fs yet, thus
++ * we don't need to hold device_list_mutex.
++ */
++ list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
++ ret = check_dev_super(device);
++ if (ret < 0) {
++ btrfs_handle_fs_error(fs_info, ret,
++ "super block on devid %llu got modified unexpectedly",
++ device->devid);
++ break;
++ }
++ }
+ clear_bit(BTRFS_FS_FROZEN, &fs_info->flags);
++
++ /*
++ * We still return 0, to allow VFS layer to unfreeze the fs even the
++ * above checks failed. Since the fs is either fine or read-only, we're
++ * safe to continue, without causing further damage.
++ */
+ return 0;
+ }
+
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index 00b97e6eb5078..897367ba68d2a 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -286,6 +286,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
+ BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
+ BTRFS_FEAT_ATTR_INCOMPAT(metadata_uuid, METADATA_UUID);
+ BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
++BTRFS_FEAT_ATTR_COMPAT_RO(block_group_tree, BLOCK_GROUP_TREE);
+ BTRFS_FEAT_ATTR_INCOMPAT(raid1c34, RAID1C34);
+ #ifdef CONFIG_BLK_DEV_ZONED
+ BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED);
+@@ -317,6 +318,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
+ BTRFS_FEAT_ATTR_PTR(metadata_uuid),
+ BTRFS_FEAT_ATTR_PTR(free_space_tree),
+ BTRFS_FEAT_ATTR_PTR(raid1c34),
++ BTRFS_FEAT_ATTR_PTR(block_group_tree),
+ #ifdef CONFIG_BLK_DEV_ZONED
+ BTRFS_FEAT_ATTR_PTR(zoned),
+ #endif
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 0bec10740ad39..8fab3b2749571 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -1912,14 +1912,6 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
+ super->cache_generation = 0;
+ if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags))
+ super->uuid_tree_generation = root_item->generation;
+-
+- if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+- root_item = &fs_info->block_group_root->root_item;
+-
+- super->block_group_root = root_item->bytenr;
+- super->block_group_root_generation = root_item->generation;
+- super->block_group_root_level = root_item->level;
+- }
+ }
+
+ int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
+diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
+index b6cf39f4e7e48..072ab9a1374b5 100644
+--- a/fs/btrfs/tree-defrag.c
++++ b/fs/btrfs/tree-defrag.c
+@@ -31,8 +31,10 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ goto out;
+
+ path = btrfs_alloc_path();
+- if (!path)
+- return -ENOMEM;
++ if (!path) {
++ ret = -ENOMEM;
++ goto out;
++ }
+
+ level = btrfs_header_level(root->node);
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 6f006430115a3..55c8bf9a5c890 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -2029,7 +2029,7 @@ void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info,
+ struct page *page;
+ int ret;
+
+- disk_super = btrfs_read_dev_one_super(bdev, copy_num);
++ disk_super = btrfs_read_dev_one_super(bdev, copy_num, false);
+ if (IS_ERR(disk_super))
+ continue;
+
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 02b5c0ac56547..af8dbcf932ab1 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2910,7 +2910,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
+
+ while (true) {
+ flags &= CEPH_FILE_MODE_MASK;
+- if (atomic_read(&fi->num_locks))
++ if (vfs_inode_has_locks(inode))
+ flags |= CHECK_FILELOCK;
+ _got = 0;
+ ret = try_get_cap_refs(inode, need, want, endoff,
+diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
+index 3e2843e86e274..b191426bf880c 100644
+--- a/fs/ceph/locks.c
++++ b/fs/ceph/locks.c
+@@ -32,18 +32,14 @@ void __init ceph_flock_init(void)
+
+ static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
+ {
+- struct ceph_file_info *fi = dst->fl_file->private_data;
+ struct inode *inode = file_inode(dst->fl_file);
+ atomic_inc(&ceph_inode(inode)->i_filelock_ref);
+- atomic_inc(&fi->num_locks);
+ }
+
+ static void ceph_fl_release_lock(struct file_lock *fl)
+ {
+- struct ceph_file_info *fi = fl->fl_file->private_data;
+ struct inode *inode = file_inode(fl->fl_file);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+- atomic_dec(&fi->num_locks);
+ if (atomic_dec_and_test(&ci->i_filelock_ref)) {
+ /* clear error when all locks are released */
+ spin_lock(&ci->i_ceph_lock);
+diff --git a/fs/ceph/super.h b/fs/ceph/super.h
+index 40630e6f691c7..ae4126f634101 100644
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -788,7 +788,6 @@ struct ceph_file_info {
+ struct list_head rw_contexts;
+
+ u32 filp_gen;
+- atomic_t num_locks;
+ };
+
+ struct ceph_dir_file_info {
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 5d93154572c01..4ef2d08de5b65 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -292,9 +292,10 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
+ continue;
+ }
+ kref_get(&iface->refcount);
++ break;
+ }
+
+- if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) {
++ if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
+ rc = 1;
+ iface = NULL;
+ cifs_dbg(FYI, "unable to find a suitable iface\n");
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 74052b51655ec..05c9c75360fab 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -530,7 +530,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ p = buf;
+
+ spin_lock(&ses->iface_lock);
+- ses->iface_count = 0;
+ /*
+ * Go through iface_list and do kref_put to remove
+ * any unused ifaces. ifaces in use will be removed
+@@ -540,6 +539,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ iface_head) {
+ iface->is_active = 0;
+ kref_put(&iface->refcount, release_iface);
++ ses->iface_count--;
+ }
+ spin_unlock(&ses->iface_lock);
+
+@@ -617,6 +617,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ /* just get a ref so that it doesn't get picked/freed */
+ iface->is_active = 1;
+ kref_get(&iface->refcount);
++ ses->iface_count++;
+ spin_unlock(&ses->iface_lock);
+ goto next_iface;
+ } else if (ret < 0) {
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 2eae6e038f38a..ac083526c1155 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5063,30 +5063,31 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+ ext4_has_feature_journal_needs_recovery(sb)) {
+ ext4_msg(sb, KERN_ERR, "required journal recovery "
+ "suppressed and not mounted read-only");
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ } else {
+ /* Nojournal mode, all journal mount options are illegal */
+- if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
+- ext4_msg(sb, KERN_ERR, "can't mount with "
+- "journal_checksum, fs mounted w/o journal");
+- goto failed_mount_wq;
+- }
+ if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "journal_async_commit, fs mounted w/o journal");
+- goto failed_mount_wq;
++ goto failed_mount3a;
++ }
++
++ if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
++ ext4_msg(sb, KERN_ERR, "can't mount with "
++ "journal_checksum, fs mounted w/o journal");
++ goto failed_mount3a;
+ }
+ if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "commit=%lu, fs mounted w/o journal",
+ sbi->s_commit_interval / HZ);
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ }
+ if (EXT4_MOUNT_DATA_FLAGS &
+ (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "data=, fs mounted w/o journal");
+- goto failed_mount_wq;
++ goto failed_mount3a;
+ }
+ sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
+ clear_opt(sb, JOURNAL_CHECKSUM);
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index a0746be3c1de7..80d17c520d0ba 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -458,15 +458,16 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ /* panic? */
+ return -EIO;
+
++ res = -EIO;
+ if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
+- return -EIO;
++ goto out;
+ fd.search_key->cat = HFS_I(main_inode)->cat_key;
+ if (hfs_brec_find(&fd))
+- /* panic? */
+ goto out;
+
+ if (S_ISDIR(main_inode->i_mode)) {
+- WARN_ON(fd.entrylength < sizeof(struct hfs_cat_dir));
++ if (fd.entrylength < sizeof(struct hfs_cat_dir))
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_dir));
+ if (rec.type != HFS_CDR_DIR ||
+@@ -479,6 +480,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_dir));
+ } else if (HFS_IS_RSRC(inode)) {
++ if (fd.entrylength < sizeof(struct hfs_cat_file))
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ hfs_inode_write_fork(inode, rec.file.RExtRec,
+@@ -486,7 +489,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ } else {
+- WARN_ON(fd.entrylength < sizeof(struct hfs_cat_file));
++ if (fd.entrylength < sizeof(struct hfs_cat_file))
++ goto out;
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ if (rec.type != HFS_CDR_FIL ||
+@@ -503,9 +507,10 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ sizeof(struct hfs_cat_file));
+ }
++ res = 0;
+ out:
+ hfs_find_exit(&fd);
+- return 0;
++ return res;
+ }
+
+ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index c5a5c7b90d727..93b2290addd59 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -322,7 +322,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+ dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
+ dn_len = le16_to_cpu(authblob->DomainName.Length);
+
+- if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
++ if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len ||
++ nt_len < CIFS_ENCPWD_SIZE)
+ return -EINVAL;
+
+ /* TODO : use domain name that imported from configuration file */
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
+index 756ad631c019a..eab9950b5a683 100644
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -310,9 +310,12 @@ int ksmbd_conn_handler_loop(void *p)
+
+ /* 4 for rfc1002 length field */
+ size = pdu_size + 4;
+- conn->request_buf = kvmalloc(size, GFP_KERNEL);
++ conn->request_buf = kvmalloc(size,
++ GFP_KERNEL |
++ __GFP_NOWARN |
++ __GFP_NORETRY);
+ if (!conn->request_buf)
+- continue;
++ break;
+
+ memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf));
+ if (!ksmbd_smb_request(conn))
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 7a9497a7b0a30..a71a7cc0e5762 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1926,13 +1926,13 @@ int smb2_tree_connect(struct ksmbd_work *work)
+ if (conn->posix_ext_supported)
+ status.tree_conn->posix_extensions = true;
+
+-out_err1:
+ rsp->StructureSize = cpu_to_le16(16);
++ inc_rfc1001_len(work->response_buf, 16);
++out_err1:
+ rsp->Capabilities = 0;
+ rsp->Reserved = 0;
+ /* default manual caching */
+ rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING;
+- inc_rfc1001_len(work->response_buf, 16);
+
+ if (!IS_ERR(treename))
+ kfree(treename);
+@@ -1965,6 +1965,9 @@ out_err1:
+ rsp->hdr.Status = STATUS_ACCESS_DENIED;
+ }
+
++ if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
++ smb2_set_err_rsp(work);
++
+ return rc;
+ }
+
+diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c
+index 143bba4e4db81..434891db42a2c 100644
+--- a/fs/ksmbd/transport_tcp.c
++++ b/fs/ksmbd/transport_tcp.c
+@@ -295,6 +295,7 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ struct msghdr ksmbd_msg;
+ struct kvec *iov;
+ struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
++ int max_retry = 2;
+
+ iov = get_conn_iovec(t, nr_segs);
+ if (!iov)
+@@ -321,9 +322,11 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
+ total_read = -EAGAIN;
+ break;
+- } else if (length == -ERESTARTSYS || length == -EAGAIN) {
++ } else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
++ max_retry) {
+ usleep_range(1000, 2000);
+ length = 0;
++ max_retry--;
+ continue;
+ } else if (length <= 0) {
+ total_read = -EAGAIN;
+diff --git a/fs/locks.c b/fs/locks.c
+index 607f94a0e789f..7dc129cc1a267 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -2669,6 +2669,29 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ }
+ EXPORT_SYMBOL_GPL(vfs_cancel_lock);
+
++/**
++ * vfs_inode_has_locks - are any file locks held on @inode?
++ * @inode: inode to check for locks
++ *
++ * Return true if there are any FL_POSIX or FL_FLOCK locks currently
++ * set on @inode.
++ */
++bool vfs_inode_has_locks(struct inode *inode)
++{
++ struct file_lock_context *ctx;
++ bool ret;
++
++ ctx = smp_load_acquire(&inode->i_flctx);
++ if (!ctx)
++ return false;
++
++ spin_lock(&ctx->flc_lock);
++ ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
++ spin_unlock(&ctx->flc_lock);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(vfs_inode_has_locks);
++
+ #ifdef CONFIG_PROC_FS
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 2960d0a8e8f9a..355164a527540 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -3528,6 +3528,17 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
+ case nfserr_noent:
+ xdr_truncate_encode(xdr, start_offset);
+ goto skip_entry;
++ case nfserr_jukebox:
++ /*
++ * The pseudoroot should only display dentries that lead to
++ * exports. If we get EJUKEBOX here, then we can't tell whether
++ * this entry should be included. Just fail the whole READDIR
++ * with NFS4ERR_DELAY in that case, and hope that the situation
++ * will resolve itself by the client's next attempt.
++ */
++ if (cd->rd_fhp->fh_export->ex_flags & NFSEXP_V4ROOT)
++ goto fail;
++ fallthrough;
+ default:
+ /*
+ * If the client requested the RDATTR_ERROR attribute,
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
+index 4bb5baa17040f..011c556caa1e7 100644
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -447,8 +447,8 @@ static void nfsd_shutdown_net(struct net *net)
+ {
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+
+- nfsd_file_cache_shutdown_net(net);
+ nfs4_state_shutdown_net(net);
++ nfsd_file_cache_shutdown_net(net);
+ if (nn->lockd_up) {
+ lockd_down(net);
+ nn->lockd_up = false;
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 4f2ffc7ef296f..f31c0389a2e7d 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -486,10 +486,10 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
+
+ new_valid = ntfs_up_block(sb, min_t(u64, ni->i_valid, new_size));
+
+- ni_lock(ni);
+-
+ truncate_setsize(inode, new_size);
+
++ ni_lock(ni);
++
+ down_write(&ni->file.run_lock);
+ err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size,
+ &new_valid, ni->mi.sbi->options->prealloc, NULL);
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index b9a83820e1adf..3c380140515da 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -600,7 +600,7 @@ static void udf_do_extend_final_block(struct inode *inode,
+ */
+ if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
+ return;
+- added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
++ added_bytes = new_elen - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ last_ext->extLength += added_bytes;
+ UDF_I(inode)->i_lenExtents += added_bytes;
+
+diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h
+index b1b5720d89a59..ee657452f122a 100644
+--- a/include/linux/dsa/tag_qca.h
++++ b/include/linux/dsa/tag_qca.h
+@@ -45,8 +45,8 @@ struct sk_buff;
+ QCA_HDR_MGMT_COMMAND_LEN + \
+ QCA_HDR_MGMT_DATA1_LEN)
+
+-#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */
+-#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */
++#define QCA_HDR_MGMT_DATA2_LEN 28 /* Other 28 byte for the mdio data */
++#define QCA_HDR_MGMT_PADDING_LEN 18 /* Padding to reach the min Ethernet packet */
+
+ #define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \
+ QCA_HDR_LEN + \
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index f87b2f5db9f83..4f51616f01b21 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1139,8 +1139,6 @@ void efi_check_for_embedded_firmwares(void);
+ static inline void efi_check_for_embedded_firmwares(void) { }
+ #endif
+
+-efi_status_t efi_random_get_seed(void);
+-
+ #define arch_efi_call_virt(p, f, args...) ((p)->f(args))
+
+ /*
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 8e79a761c56c5..17a1a57adbe00 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1170,6 +1170,7 @@ extern int locks_delete_block(struct file_lock *);
+ extern int vfs_test_lock(struct file *, struct file_lock *);
+ extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
+ extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
++bool vfs_inode_has_locks(struct inode *inode);
+ extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
+ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
+ extern void lease_get_mtime(struct inode *, struct timespec64 *time);
+@@ -1284,6 +1285,11 @@ static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ return 0;
+ }
+
++static inline bool vfs_inode_has_locks(struct inode *inode)
++{
++ return false;
++}
++
+ static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
+ {
+ return -ENOLCK;
+diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
+index b5f58fd37a0f7..4b00221f57e26 100644
+--- a/include/linux/mlx5/device.h
++++ b/include/linux/mlx5/device.h
+@@ -1088,6 +1088,11 @@ enum {
+ MLX5_VPORT_ADMIN_STATE_AUTO = 0x2,
+ };
+
++enum {
++ MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN = 0x1,
++ MLX5_VPORT_CVLAN_INSERT_ALWAYS = 0x3,
++};
++
+ enum {
+ MLX5_L3_PROT_TYPE_IPV4 = 0,
+ MLX5_L3_PROT_TYPE_IPV6 = 1,
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 4acd5610e96bc..e640c27b1b6df 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -877,7 +877,8 @@ struct mlx5_ifc_e_switch_cap_bits {
+ u8 vport_svlan_insert[0x1];
+ u8 vport_cvlan_insert_if_not_exist[0x1];
+ u8 vport_cvlan_insert_overwrite[0x1];
+- u8 reserved_at_5[0x2];
++ u8 reserved_at_5[0x1];
++ u8 vport_cvlan_insert_always[0x1];
+ u8 esw_shared_ingress_acl[0x1];
+ u8 esw_uplink_ingress_acl[0x1];
+ u8 root_ft_on_other_esw[0x1];
+diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
+index ada1296c87d50..72f5ebc5c97a9 100644
+--- a/include/linux/netfilter/ipset/ip_set.h
++++ b/include/linux/netfilter/ipset/ip_set.h
+@@ -197,7 +197,7 @@ struct ip_set_region {
+ };
+
+ /* Max range where every element is added/deleted in one step */
+-#define IPSET_MAX_RANGE (1<<20)
++#define IPSET_MAX_RANGE (1<<14)
+
+ /* The max revision number supported by any set type + 1 */
+ #define IPSET_REVISION_MAX 9
+diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
+index cd188a527d169..3b35b6f6533aa 100644
+--- a/include/linux/sunrpc/rpc_pipe_fs.h
++++ b/include/linux/sunrpc/rpc_pipe_fs.h
+@@ -92,6 +92,11 @@ extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
+ char __user *, size_t);
+ extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
+
++/* returns true if the msg is in-flight, i.e., already eaten by the peer */
++static inline bool rpc_msg_is_inflight(const struct rpc_pipe_msg *msg) {
++ return (msg->copied != 0 && list_empty(&msg->list));
++}
++
+ struct rpc_clnt;
+ extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
+ extern int rpc_remove_client_dir(struct rpc_clnt *);
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index cdb7db9b0e252..1daededfa75ed 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -311,17 +311,29 @@ struct nft_set_iter {
+ /**
+ * struct nft_set_desc - description of set elements
+ *
++ * @ktype: key type
+ * @klen: key length
++ * @dtype: data type
+ * @dlen: data length
++ * @objtype: object type
++ * @flags: flags
+ * @size: number of set elements
++ * @policy: set policy
++ * @gc_int: garbage collector interval
+ * @field_len: length of each field in concatenation, bytes
+ * @field_count: number of concatenated fields in element
+ * @expr: set must support for expressions
+ */
+ struct nft_set_desc {
++ u32 ktype;
+ unsigned int klen;
++ u32 dtype;
+ unsigned int dlen;
++ u32 objtype;
+ unsigned int size;
++ u32 policy;
++ u32 gc_int;
++ u64 timeout;
+ u8 field_len[NFT_REG32_COUNT];
+ u8 field_count;
+ bool expr;
+@@ -580,7 +592,9 @@ void *nft_set_catchall_gc(const struct nft_set *set);
+
+ static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
+ {
+- return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
++ u32 gc_int = READ_ONCE(set->gc_int);
++
++ return gc_int ? msecs_to_jiffies(gc_int) : HZ;
+ }
+
+ /**
+@@ -1551,6 +1565,9 @@ struct nft_trans_rule {
+ struct nft_trans_set {
+ struct nft_set *set;
+ u32 set_id;
++ u32 gc_int;
++ u64 timeout;
++ bool update;
+ bool bound;
+ };
+
+@@ -1560,6 +1577,12 @@ struct nft_trans_set {
+ (((struct nft_trans_set *)trans->data)->set_id)
+ #define nft_trans_set_bound(trans) \
+ (((struct nft_trans_set *)trans->data)->bound)
++#define nft_trans_set_update(trans) \
++ (((struct nft_trans_set *)trans->data)->update)
++#define nft_trans_set_timeout(trans) \
++ (((struct nft_trans_set *)trans->data)->timeout)
++#define nft_trans_set_gc_int(trans) \
++ (((struct nft_trans_set *)trans->data)->gc_int)
+
+ struct nft_trans_chain {
+ bool update;
+diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
+index 7ada84e4a3ed1..5655e89b962be 100644
+--- a/include/uapi/linux/btrfs.h
++++ b/include/uapi/linux/btrfs.h
+@@ -290,6 +290,12 @@ struct btrfs_ioctl_fs_info_args {
+ #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1)
+ #define BTRFS_FEATURE_COMPAT_RO_VERITY (1ULL << 2)
+
++/*
++ * Put all block group items into a dedicated block group tree, greatly
++ * reducing mount time for large filesystem due to better locality.
++ */
++#define BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE (1ULL << 3)
++
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
+ #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index b8a39be3bcb4c..9c49a1a4cedaa 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2206,7 +2206,7 @@ int io_run_task_work_sig(void)
+ /* when returns >0, the caller should retry */
+ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ struct io_wait_queue *iowq,
+- ktime_t timeout)
++ ktime_t *timeout)
+ {
+ int ret;
+ unsigned long check_cq;
+@@ -2224,7 +2224,7 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ if (check_cq & BIT(IO_CHECK_CQ_DROPPED_BIT))
+ return -EBADR;
+ }
+- if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
++ if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
+ return -ETIME;
+ return 1;
+ }
+@@ -2289,7 +2289,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ }
+ prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
+ TASK_INTERRUPTIBLE);
+- ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
++ ret = io_cqring_wait_schedule(ctx, &iowq, &timeout);
+ cond_resched();
+ } while (ret > 0);
+
+@@ -3725,8 +3725,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
+ return -EEXIST;
+
+ if (ctx->restricted) {
+- if (opcode >= IORING_REGISTER_LAST)
+- return -EINVAL;
+ opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
+ if (!test_bit(opcode, ctx->restrictions.register_op))
+ return -EACCES;
+@@ -3882,6 +3880,9 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
+ long ret = -EBADF;
+ struct fd f;
+
++ if (opcode >= IORING_REGISTER_LAST)
++ return -EINVAL;
++
+ f = fdget(fd);
+ if (!f.file)
+ return -EBADF;
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index 41b67eb83ab3f..2fb6d8e196e69 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -501,6 +501,10 @@ again:
+ /* reset fops->func and fops->trampoline for re-register */
+ tr->fops->func = NULL;
+ tr->fops->trampoline = 0;
++
++ /* reset im->image memory attr for arch_prepare_bpf_trampoline */
++ set_memory_nx((long)im->image, 1);
++ set_memory_rw((long)im->image, 1);
+ goto again;
+ }
+ #endif
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 8464d95805d08..1f50dce8765d5 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -425,7 +425,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
+ * the status change is visible to another thread
+ */
+ smp_wmb();
+- req->status = status;
++ WRITE_ONCE(req->status, status);
+
+ wake_up(&req->wq);
+ p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
+@@ -587,7 +587,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
+ /* if we haven't received a response for oldreq,
+ * remove it from the list
+ */
+- if (oldreq->status == REQ_STATUS_SENT) {
++ if (READ_ONCE(oldreq->status) == REQ_STATUS_SENT) {
+ if (c->trans_mod->cancelled)
+ c->trans_mod->cancelled(c, oldreq);
+ }
+@@ -672,7 +672,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+ }
+ again:
+ /* Wait for the response */
+- err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
++ err = wait_event_killable(req->wq,
++ READ_ONCE(req->status) >= REQ_STATUS_RCVD);
+
+ /* Make sure our req is coherent with regard to updates in other
+ * threads - echoes to wmb() in the callback
+@@ -686,7 +687,7 @@ again:
+ goto again;
+ }
+
+- if (req->status == REQ_STATUS_ERROR) {
++ if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
+ p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+ err = req->t_err;
+ }
+@@ -699,7 +700,7 @@ again:
+ p9_client_flush(c, req);
+
+ /* if we received the response anyway, don't signal error */
+- if (req->status == REQ_STATUS_RCVD)
++ if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
+ err = 0;
+ }
+ recalc_sigpending:
+@@ -768,7 +769,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+ if (err != -ERESTARTSYS)
+ goto recalc_sigpending;
+ }
+- if (req->status == REQ_STATUS_ERROR) {
++ if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
+ p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+ err = req->t_err;
+ }
+@@ -781,7 +782,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+ p9_client_flush(c, req);
+
+ /* if we received the response anyway, don't signal error */
+- if (req->status == REQ_STATUS_RCVD)
++ if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
+ err = 0;
+ }
+ recalc_sigpending:
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 080b5de3e1ed8..a2eb1363d293b 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -202,11 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+
+ list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ list_move(&req->req_list, &cancel_list);
+- req->status = REQ_STATUS_ERROR;
++ WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ }
+ list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ list_move(&req->req_list, &cancel_list);
+- req->status = REQ_STATUS_ERROR;
++ WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ }
+
+ spin_unlock(&m->req_lock);
+@@ -467,7 +467,7 @@ static void p9_write_work(struct work_struct *work)
+
+ req = list_entry(m->unsent_req_list.next, struct p9_req_t,
+ req_list);
+- req->status = REQ_STATUS_SENT;
++ WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
+ list_move_tail(&req->req_list, &m->req_list);
+
+@@ -676,7 +676,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+ return m->err;
+
+ spin_lock(&m->req_lock);
+- req->status = REQ_STATUS_UNSENT;
++ WRITE_ONCE(req->status, REQ_STATUS_UNSENT);
+ list_add_tail(&req->req_list, &m->unsent_req_list);
+ spin_unlock(&m->req_lock);
+
+@@ -703,7 +703,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+
+ if (req->status == REQ_STATUS_UNSENT) {
+ list_del(&req->req_list);
+- req->status = REQ_STATUS_FLSHD;
++ WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
+ p9_req_put(client, req);
+ ret = 0;
+ }
+@@ -732,7 +732,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ * remove it from the list.
+ */
+ list_del(&req->req_list);
+- req->status = REQ_STATUS_FLSHD;
++ WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
+ spin_unlock(&m->req_lock);
+
+ p9_req_put(client, req);
+diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
+index d817d3745238b..d8b0a6f3b15e5 100644
+--- a/net/9p/trans_rdma.c
++++ b/net/9p/trans_rdma.c
+@@ -507,7 +507,7 @@ dont_need_post_recv:
+ * because doing if after could erase the REQ_STATUS_RCVD
+ * status in case of a very fast reply.
+ */
+- req->status = REQ_STATUS_SENT;
++ WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ err = ib_post_send(rdma->qp, &wr, NULL);
+ if (err)
+ goto send_error;
+@@ -517,7 +517,7 @@ dont_need_post_recv:
+
+ /* Handle errors that happened during or while preparing the send: */
+ send_error:
+- req->status = REQ_STATUS_ERROR;
++ WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ kfree(c);
+ p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err);
+
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index b84d35cf68994..947c038a0470c 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -263,7 +263,7 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
+
+ p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
+
+- req->status = REQ_STATUS_SENT;
++ WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ req_retry:
+ spin_lock_irqsave(&chan->lock, flags);
+
+@@ -469,7 +469,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
+ inlen = n;
+ }
+ }
+- req->status = REQ_STATUS_SENT;
++ WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ req_retry_pinned:
+ spin_lock_irqsave(&chan->lock, flags);
+
+@@ -532,9 +532,10 @@ req_retry_pinned:
+ spin_unlock_irqrestore(&chan->lock, flags);
+ kicked = 1;
+ p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
+- err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
++ err = wait_event_killable(req->wq,
++ READ_ONCE(req->status) >= REQ_STATUS_RCVD);
+ // RERROR needs reply (== error string) in static data
+- if (req->status == REQ_STATUS_RCVD &&
++ if (READ_ONCE(req->status) == REQ_STATUS_RCVD &&
+ unlikely(req->rc.sdata[4] == P9_RERROR))
+ handle_rerror(req, in_hdr_len, offs, in_pages);
+
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 0f862d5a59601..a103aed854658 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -157,7 +157,7 @@ again:
+ &masked_prod, masked_cons,
+ XEN_9PFS_RING_SIZE(ring));
+
+- p9_req->status = REQ_STATUS_SENT;
++ WRITE_ONCE(p9_req->status, REQ_STATUS_SENT);
+ virt_wmb(); /* write ring before updating pointer */
+ prod += size;
+ ring->intf->out_prod = prod;
+@@ -212,7 +212,7 @@ static void p9_xen_response(struct work_struct *work)
+ dev_warn(&priv->dev->dev,
+ "requested packet size too big: %d for tag %d with capacity %zd\n",
+ h.size, h.tag, req->rc.capacity);
+- req->status = REQ_STATUS_ERROR;
++ WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ goto recv_error;
+ }
+
+diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
+index 2809cbd6b7f74..d8cb4b2a076b4 100644
+--- a/net/caif/cfctrl.c
++++ b/net/caif/cfctrl.c
+@@ -269,11 +269,15 @@ int cfctrl_linkup_request(struct cflayer *layer,
+ default:
+ pr_warn("Request setup of bad link type = %d\n",
+ param->linktype);
++ cfpkt_destroy(pkt);
+ return -EINVAL;
+ }
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+- if (!req)
++ if (!req) {
++ cfpkt_destroy(pkt);
+ return -ENOMEM;
++ }
++
+ req->client_layer = user_layer;
+ req->cmd = CFCTRL_CMD_LINK_SETUP;
+ req->param = *param;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 3aae1885b9702..50d685be517d5 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3182,15 +3182,18 @@ static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
+
+ static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
+ {
++ void *old_data;
++
+ /* skb_ensure_writable() is not needed here, as we're
+ * already working on an uncloned skb.
+ */
+ if (unlikely(!pskb_may_pull(skb, off + len)))
+ return -ENOMEM;
+
+- skb_postpull_rcsum(skb, skb->data + off, len);
+- memmove(skb->data + len, skb->data, off);
++ old_data = skb->data;
+ __skb_pull(skb, len);
++ skb_postpull_rcsum(skb, old_data + off, len);
++ memmove(skb->data, old_data, off);
+
+ return 0;
+ }
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 971969cc7e17f..fb01211a255b0 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -1037,12 +1037,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
+ }
+ EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+
++static int inet_ulp_can_listen(const struct sock *sk)
++{
++ const struct inet_connection_sock *icsk = inet_csk(sk);
++
++ if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
++ return -EINVAL;
++
++ return 0;
++}
++
+ int inet_csk_listen_start(struct sock *sk)
+ {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ struct inet_sock *inet = inet_sk(sk);
+ int err;
+
++ err = inet_ulp_can_listen(sk);
++ if (unlikely(err))
++ return err;
++
+ reqsk_queue_alloc(&icsk->icsk_accept_queue);
+
+ sk->sk_ack_backlog = 0;
+diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
+index 9ae50b1bd8444..05b6077b9f2c3 100644
+--- a/net/ipv4/tcp_ulp.c
++++ b/net/ipv4/tcp_ulp.c
+@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
+ if (sk->sk_socket)
+ clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+
++ err = -EINVAL;
++ if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
++ goto out_err;
++
+ err = ulp_ops->init(sk);
+ if (err)
+ goto out_err;
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 42d5e0a7952ae..a2cc25cca33e1 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2310,7 +2310,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ /* otherwise tcp will dispose of the ssk and subflow ctx */
+ if (ssk->sk_state == TCP_LISTEN) {
+ tcp_set_state(ssk, TCP_CLOSE);
+- mptcp_subflow_queue_clean(ssk);
++ mptcp_subflow_queue_clean(sk, ssk);
+ inet_csk_listen_stop(ssk);
+ }
+ __tcp_close(ssk, 0);
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index c1eaa16855921..df6937c8cf544 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -610,7 +610,7 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ struct mptcp_subflow_context *subflow);
+ void __mptcp_subflow_send_ack(struct sock *ssk);
+ void mptcp_subflow_reset(struct sock *ssk);
+-void mptcp_subflow_queue_clean(struct sock *ssk);
++void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
+ void mptcp_sock_graft(struct sock *sk, struct socket *parent);
+ struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
+ bool __mptcp_close(struct sock *sk, long timeout);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 613f515fedf0a..9d3701fdb2937 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1733,7 +1733,7 @@ static void subflow_state_change(struct sock *sk)
+ }
+ }
+
+-void mptcp_subflow_queue_clean(struct sock *listener_ssk)
++void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk)
+ {
+ struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
+ struct mptcp_sock *msk, *next, *head = NULL;
+@@ -1782,8 +1782,23 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
+
+ do_cancel_work = __mptcp_close(sk, 0);
+ release_sock(sk);
+- if (do_cancel_work)
++ if (do_cancel_work) {
++ /* lockdep will report a false positive ABBA deadlock
++ * between cancel_work_sync and the listener socket.
++ * The involved locks belong to different sockets WRT
++ * the existing AB chain.
++ * Using a per socket key is problematic as key
++ * deregistration requires process context and must be
++ * performed at socket disposal time, in atomic
++ * context.
++ * Just tell lockdep to consider the listener socket
++ * released here.
++ */
++ mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
+ mptcp_cancel_work(sk);
++ mutex_acquire(&listener_sk->sk_lock.dep_map,
++ SINGLE_DEPTH_NESTING, 0, _RET_IP_);
++ }
+ sock_put(sk);
+ }
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 6b31746f9be3b..751ac89b07a56 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1698,9 +1698,10 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+ ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
+ ip_set_unlock(set);
+ retried = true;
+- } while (ret == -EAGAIN &&
+- set->variant->resize &&
+- (ret = set->variant->resize(set, retried)) == 0);
++ } while (ret == -ERANGE ||
++ (ret == -EAGAIN &&
++ set->variant->resize &&
++ (ret = set->variant->resize(set, retried)) == 0));
+
+ if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
+ return 0;
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index 75d556d71652d..24adcdd7a0b16 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -98,11 +98,11 @@ static int
+ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ip4 *h = set->data;
++ struct hash_ip4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ip4_elem e = { 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, hosts;
++ u32 ip = 0, ip_to = 0, hosts, i = 0;
+ int ret = 0;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -147,14 +147,14 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
+
+- /* 64bit division is not allowed on 32bit */
+- if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+- for (; ip <= ip_to;) {
++ for (; ip <= ip_to; i++) {
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ip4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
+index 153de3457423e..a22ec1a6f6ec8 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
+@@ -97,11 +97,11 @@ static int
+ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipmark4 *h = set->data;
++ struct hash_ipmark4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0;
++ u32 ip, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -148,13 +148,14 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ip_set_mask_from_to(ip, ip_to, cidr);
+ }
+
+- if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+- for (; ip <= ip_to; ip++) {
++ for (; ip <= ip_to; ip++, i++) {
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipmark4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
+index 7303138e46be1..10481760a9b25 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipport.c
++++ b/net/netfilter/ipset/ip_set_hash_ipport.c
+@@ -105,11 +105,11 @@ static int
+ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipport4 *h = set->data;
++ struct hash_ipport4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipport4_elem e = { .ip = 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0, p = 0, port, port_to;
++ u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -173,17 +173,18 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+ p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ : port;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.ip = htonl(ip);
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipport4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
+index 334fb1ad0e86c..39a01934b1536 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
+@@ -108,11 +108,11 @@ static int
+ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipportip4 *h = set->data;
++ struct hash_ipportip4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipportip4_elem e = { .ip = 0 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip, ip_to = 0, p = 0, port, port_to;
++ u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -180,17 +180,18 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+ p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ : port;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.ip = htonl(ip);
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipportip4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+index 7df94f437f600..5c6de605a9fb7 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+@@ -160,12 +160,12 @@ static int
+ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_ipportnet4 *h = set->data;
++ struct hash_ipportnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+- u32 ip2_from = 0, ip2_to = 0, ip2;
++ u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ bool with_ports = false;
+ u8 cidr;
+ int ret;
+@@ -253,9 +253,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
+- if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+-
+ ip2_to = ip2_from;
+ if (tb[IPSET_ATTR_IP2_TO]) {
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
+@@ -282,9 +279,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ for (; p <= port_to; p++) {
+ e.port = htons(p);
+ do {
++ i++;
+ e.ip2 = htonl(ip2);
+ ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr);
+ e.cidr = cidr - 1;
++ if (i > IPSET_MAX_RANGE) {
++ hash_ipportnet4_data_next(&h->next,
++ &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
+index 1422739d9aa25..ce0a9ce5a91f1 100644
+--- a/net/netfilter/ipset/ip_set_hash_net.c
++++ b/net/netfilter/ipset/ip_set_hash_net.c
+@@ -136,11 +136,11 @@ static int
+ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_net4 *h = set->data;
++ struct hash_net4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_net4_elem e = { .cidr = HOST_MASK };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, ipn, n = 0;
++ u32 ip = 0, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -188,19 +188,16 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ if (ip + UINT_MAX == ip_to)
+ return -IPSET_ERR_HASH_RANGE;
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+ do {
++ i++;
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_net4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
+index 9810f5bf63f5e..0310732862362 100644
+--- a/net/netfilter/ipset/ip_set_hash_netiface.c
++++ b/net/netfilter/ipset/ip_set_hash_netiface.c
+@@ -202,7 +202,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0, ipn, n = 0;
++ u32 ip = 0, ip_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -256,19 +256,16 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+ do {
++ i++;
+ e.ip = htonl(ip);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netiface4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
+index 3d09eefe998a7..c07b70bf32db4 100644
+--- a/net/netfilter/ipset/ip_set_hash_netnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netnet.c
+@@ -163,13 +163,12 @@ static int
+ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netnet4 *h = set->data;
++ struct hash_netnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0;
+- u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
+- u64 n = 0, m = 0;
++ u32 ip2 = 0, ip2_from = 0, ip2_to = 0, i = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -245,19 +244,6 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+- n++;
+- } while (ipn++ < ip_to);
+- ipn = ip2_from;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+- m++;
+- } while (ipn++ < ip2_to);
+-
+- if (n*m > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+@@ -270,7 +256,12 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ e.ip[0] = htonl(ip);
+ ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ do {
++ i++;
+ e.ip[1] = htonl(ip2);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netnet4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
+index 09cf72eb37f8d..d1a0628df4ef3 100644
+--- a/net/netfilter/ipset/ip_set_hash_netport.c
++++ b/net/netfilter/ipset/ip_set_hash_netport.c
+@@ -154,12 +154,11 @@ static int
+ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netport4 *h = set->data;
++ struct hash_netport4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
+- u64 n = 0;
++ u32 port, port_to, p = 0, ip = 0, ip_to = 0, i = 0;
+ bool with_ports = false;
+ u8 cidr;
+ int ret;
+@@ -236,14 +235,6 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
+- n++;
+- } while (ipn++ < ip_to);
+-
+- if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip);
+@@ -255,8 +246,12 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ e.ip = htonl(ip);
+ ip = ip_set_range_to_cidr(ip, ip_to, &cidr);
+ e.cidr = cidr - 1;
+- for (; p <= port_to; p++) {
++ for (; p <= port_to; p++, i++) {
+ e.port = htons(p);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netport4_data_next(&h->next, &e);
++ return -ERANGE;
++ }
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
+index 19bcdb3141f6e..005a7ce87217e 100644
+--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
+@@ -173,17 +173,26 @@ hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
+ return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+ }
+
++static u32
++hash_netportnet4_range_to_cidr(u32 from, u32 to, u8 *cidr)
++{
++ if (from == 0 && to == UINT_MAX) {
++ *cidr = 0;
++ return to;
++ }
++ return ip_set_range_to_cidr(from, to, cidr);
++}
++
+ static int
+ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+- const struct hash_netportnet4 *h = set->data;
++ struct hash_netportnet4 *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netportnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+- u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
+- u64 n = 0, m = 0;
++ u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -285,19 +294,6 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
+- ipn = ip;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+- n++;
+- } while (ipn++ < ip_to);
+- ipn = ip2_from;
+- do {
+- ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+- m++;
+- } while (ipn++ < ip2_to);
+-
+- if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
+- return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+@@ -310,13 +306,19 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ do {
+ e.ip[0] = htonl(ip);
+- ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
++ ip = hash_netportnet4_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ for (; p <= port_to; p++) {
+ e.port = htons(p);
+ do {
++ i++;
+ e.ip[1] = htonl(ip2);
+- ip2 = ip_set_range_to_cidr(ip2, ip2_to,
+- &e.cidr[1]);
++ if (i > IPSET_MAX_RANGE) {
++ hash_netportnet4_data_next(&h->next,
++ &e);
++ return -ERANGE;
++ }
++ ip2 = hash_netportnet4_range_to_cidr(ip2,
++ ip2_to, &e.cidr[1]);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 7977f0422ecf6..e0c156bb0b172 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -465,8 +465,9 @@ static int nft_delrule_by_chain(struct nft_ctx *ctx)
+ return 0;
+ }
+
+-static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+- struct nft_set *set)
++static int __nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++ struct nft_set *set,
++ const struct nft_set_desc *desc)
+ {
+ struct nft_trans *trans;
+
+@@ -474,17 +475,28 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+ if (trans == NULL)
+ return -ENOMEM;
+
+- if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
++ if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] && !desc) {
+ nft_trans_set_id(trans) =
+ ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
+ nft_activate_next(ctx->net, set);
+ }
+ nft_trans_set(trans) = set;
++ if (desc) {
++ nft_trans_set_update(trans) = true;
++ nft_trans_set_gc_int(trans) = desc->gc_int;
++ nft_trans_set_timeout(trans) = desc->timeout;
++ }
+ nft_trans_commit_list_add_tail(ctx->net, trans);
+
+ return 0;
+ }
+
++static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++ struct nft_set *set)
++{
++ return __nft_trans_set_add(ctx, msg_type, set, NULL);
++}
++
+ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
+ {
+ int err;
+@@ -3732,8 +3744,7 @@ static bool nft_set_ops_candidate(const struct nft_set_type *type, u32 flags)
+ static const struct nft_set_ops *
+ nft_select_set_ops(const struct nft_ctx *ctx,
+ const struct nlattr * const nla[],
+- const struct nft_set_desc *desc,
+- enum nft_set_policies policy)
++ const struct nft_set_desc *desc)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+ const struct nft_set_ops *ops, *bops;
+@@ -3762,7 +3773,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
+ if (!ops->estimate(desc, flags, &est))
+ continue;
+
+- switch (policy) {
++ switch (desc->policy) {
+ case NFT_SET_POL_PERFORMANCE:
+ if (est.lookup < best.lookup)
+ break;
+@@ -3997,8 +4008,10 @@ static int nf_tables_fill_set_concat(struct sk_buff *skb,
+ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ const struct nft_set *set, u16 event, u16 flags)
+ {
+- struct nlmsghdr *nlh;
++ u64 timeout = READ_ONCE(set->timeout);
++ u32 gc_int = READ_ONCE(set->gc_int);
+ u32 portid = ctx->portid;
++ struct nlmsghdr *nlh;
+ struct nlattr *nest;
+ u32 seq = ctx->seq;
+ int i;
+@@ -4034,13 +4047,13 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
+ goto nla_put_failure;
+
+- if (set->timeout &&
++ if (timeout &&
+ nla_put_be64(skb, NFTA_SET_TIMEOUT,
+- nf_jiffies64_to_msecs(set->timeout),
++ nf_jiffies64_to_msecs(timeout),
+ NFTA_SET_PAD))
+ goto nla_put_failure;
+- if (set->gc_int &&
+- nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
++ if (gc_int &&
++ nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(gc_int)))
+ goto nla_put_failure;
+
+ if (set->policy != NFT_SET_POL_PERFORMANCE) {
+@@ -4341,15 +4354,94 @@ static int nf_tables_set_desc_parse(struct nft_set_desc *desc,
+ return err;
+ }
+
++static int nft_set_expr_alloc(struct nft_ctx *ctx, struct nft_set *set,
++ const struct nlattr * const *nla,
++ struct nft_expr **exprs, int *num_exprs,
++ u32 flags)
++{
++ struct nft_expr *expr;
++ int err, i;
++
++ if (nla[NFTA_SET_EXPR]) {
++ expr = nft_set_elem_expr_alloc(ctx, set, nla[NFTA_SET_EXPR]);
++ if (IS_ERR(expr)) {
++ err = PTR_ERR(expr);
++ goto err_set_expr_alloc;
++ }
++ exprs[0] = expr;
++ (*num_exprs)++;
++ } else if (nla[NFTA_SET_EXPRESSIONS]) {
++ struct nlattr *tmp;
++ int left;
++
++ if (!(flags & NFT_SET_EXPR)) {
++ err = -EINVAL;
++ goto err_set_expr_alloc;
++ }
++ i = 0;
++ nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
++ if (i == NFT_SET_EXPR_MAX) {
++ err = -E2BIG;
++ goto err_set_expr_alloc;
++ }
++ if (nla_type(tmp) != NFTA_LIST_ELEM) {
++ err = -EINVAL;
++ goto err_set_expr_alloc;
++ }
++ expr = nft_set_elem_expr_alloc(ctx, set, tmp);
++ if (IS_ERR(expr)) {
++ err = PTR_ERR(expr);
++ goto err_set_expr_alloc;
++ }
++ exprs[i++] = expr;
++ (*num_exprs)++;
++ }
++ }
++
++ return 0;
++
++err_set_expr_alloc:
++ for (i = 0; i < *num_exprs; i++)
++ nft_expr_destroy(ctx, exprs[i]);
++
++ return err;
++}
++
++static bool nft_set_is_same(const struct nft_set *set,
++ const struct nft_set_desc *desc,
++ struct nft_expr *exprs[], u32 num_exprs, u32 flags)
++{
++ int i;
++
++ if (set->ktype != desc->ktype ||
++ set->dtype != desc->dtype ||
++ set->flags != flags ||
++ set->klen != desc->klen ||
++ set->dlen != desc->dlen ||
++ set->field_count != desc->field_count ||
++ set->num_exprs != num_exprs)
++ return false;
++
++ for (i = 0; i < desc->field_count; i++) {
++ if (set->field_len[i] != desc->field_len[i])
++ return false;
++ }
++
++ for (i = 0; i < num_exprs; i++) {
++ if (set->exprs[i]->ops != exprs[i]->ops)
++ return false;
++ }
++
++ return true;
++}
++
+ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- u32 ktype, dtype, flags, policy, gc_int, objtype;
+ struct netlink_ext_ack *extack = info->extack;
+ u8 genmask = nft_genmask_next(info->net);
+ u8 family = info->nfmsg->nfgen_family;
+ const struct nft_set_ops *ops;
+- struct nft_expr *expr = NULL;
+ struct net *net = info->net;
+ struct nft_set_desc desc;
+ struct nft_table *table;
+@@ -4357,10 +4449,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ struct nft_set *set;
+ struct nft_ctx ctx;
+ size_t alloc_size;
+- u64 timeout;
++ int num_exprs = 0;
+ char *name;
+ int err, i;
+ u16 udlen;
++ u32 flags;
+ u64 size;
+
+ if (nla[NFTA_SET_TABLE] == NULL ||
+@@ -4371,10 +4464,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+
+ memset(&desc, 0, sizeof(desc));
+
+- ktype = NFT_DATA_VALUE;
++ desc.ktype = NFT_DATA_VALUE;
+ if (nla[NFTA_SET_KEY_TYPE] != NULL) {
+- ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
+- if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
++ desc.ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
++ if ((desc.ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
+ return -EINVAL;
+ }
+
+@@ -4399,17 +4492,17 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ return -EOPNOTSUPP;
+ }
+
+- dtype = 0;
++ desc.dtype = 0;
+ if (nla[NFTA_SET_DATA_TYPE] != NULL) {
+ if (!(flags & NFT_SET_MAP))
+ return -EINVAL;
+
+- dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
+- if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
+- dtype != NFT_DATA_VERDICT)
++ desc.dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
++ if ((desc.dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
++ desc.dtype != NFT_DATA_VERDICT)
+ return -EINVAL;
+
+- if (dtype != NFT_DATA_VERDICT) {
++ if (desc.dtype != NFT_DATA_VERDICT) {
+ if (nla[NFTA_SET_DATA_LEN] == NULL)
+ return -EINVAL;
+ desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
+@@ -4424,34 +4517,34 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (!(flags & NFT_SET_OBJECT))
+ return -EINVAL;
+
+- objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
+- if (objtype == NFT_OBJECT_UNSPEC ||
+- objtype > NFT_OBJECT_MAX)
++ desc.objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
++ if (desc.objtype == NFT_OBJECT_UNSPEC ||
++ desc.objtype > NFT_OBJECT_MAX)
+ return -EOPNOTSUPP;
+ } else if (flags & NFT_SET_OBJECT)
+ return -EINVAL;
+ else
+- objtype = NFT_OBJECT_UNSPEC;
++ desc.objtype = NFT_OBJECT_UNSPEC;
+
+- timeout = 0;
++ desc.timeout = 0;
+ if (nla[NFTA_SET_TIMEOUT] != NULL) {
+ if (!(flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
+
+- err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &timeout);
++ err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &desc.timeout);
+ if (err)
+ return err;
+ }
+- gc_int = 0;
++ desc.gc_int = 0;
+ if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
+ if (!(flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
+- gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
++ desc.gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
+ }
+
+- policy = NFT_SET_POL_PERFORMANCE;
++ desc.policy = NFT_SET_POL_PERFORMANCE;
+ if (nla[NFTA_SET_POLICY] != NULL)
+- policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
++ desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
+
+ if (nla[NFTA_SET_DESC] != NULL) {
+ err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
+@@ -4483,6 +4576,8 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ return PTR_ERR(set);
+ }
+ } else {
++ struct nft_expr *exprs[NFT_SET_EXPR_MAX] = {};
++
+ if (info->nlh->nlmsg_flags & NLM_F_EXCL) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
+ return -EEXIST;
+@@ -4490,13 +4585,29 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE)
+ return -EOPNOTSUPP;
+
+- return 0;
++ err = nft_set_expr_alloc(&ctx, set, nla, exprs, &num_exprs, flags);
++ if (err < 0)
++ return err;
++
++ err = 0;
++ if (!nft_set_is_same(set, &desc, exprs, num_exprs, flags)) {
++ NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
++ err = -EEXIST;
++ }
++
++ for (i = 0; i < num_exprs; i++)
++ nft_expr_destroy(&ctx, exprs[i]);
++
++ if (err < 0)
++ return err;
++
++ return __nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set, &desc);
+ }
+
+ if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
+ return -ENOENT;
+
+- ops = nft_select_set_ops(&ctx, nla, &desc, policy);
++ ops = nft_select_set_ops(&ctx, nla, &desc);
+ if (IS_ERR(ops))
+ return PTR_ERR(ops);
+
+@@ -4536,18 +4647,18 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ set->table = table;
+ write_pnet(&set->net, net);
+ set->ops = ops;
+- set->ktype = ktype;
++ set->ktype = desc.ktype;
+ set->klen = desc.klen;
+- set->dtype = dtype;
+- set->objtype = objtype;
++ set->dtype = desc.dtype;
++ set->objtype = desc.objtype;
+ set->dlen = desc.dlen;
+ set->flags = flags;
+ set->size = desc.size;
+- set->policy = policy;
++ set->policy = desc.policy;
+ set->udlen = udlen;
+ set->udata = udata;
+- set->timeout = timeout;
+- set->gc_int = gc_int;
++ set->timeout = desc.timeout;
++ set->gc_int = desc.gc_int;
+
+ set->field_count = desc.field_count;
+ for (i = 0; i < desc.field_count; i++)
+@@ -4557,43 +4668,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ if (err < 0)
+ goto err_set_init;
+
+- if (nla[NFTA_SET_EXPR]) {
+- expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
+- if (IS_ERR(expr)) {
+- err = PTR_ERR(expr);
+- goto err_set_expr_alloc;
+- }
+- set->exprs[0] = expr;
+- set->num_exprs++;
+- } else if (nla[NFTA_SET_EXPRESSIONS]) {
+- struct nft_expr *expr;
+- struct nlattr *tmp;
+- int left;
+-
+- if (!(flags & NFT_SET_EXPR)) {
+- err = -EINVAL;
+- goto err_set_expr_alloc;
+- }
+- i = 0;
+- nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
+- if (i == NFT_SET_EXPR_MAX) {
+- err = -E2BIG;
+- goto err_set_expr_alloc;
+- }
+- if (nla_type(tmp) != NFTA_LIST_ELEM) {
+- err = -EINVAL;
+- goto err_set_expr_alloc;
+- }
+- expr = nft_set_elem_expr_alloc(&ctx, set, tmp);
+- if (IS_ERR(expr)) {
+- err = PTR_ERR(expr);
+- goto err_set_expr_alloc;
+- }
+- set->exprs[i++] = expr;
+- set->num_exprs++;
+- }
+- }
++ err = nft_set_expr_alloc(&ctx, set, nla, set->exprs, &num_exprs, flags);
++ if (err < 0)
++ goto err_set_destroy;
+
++ set->num_exprs = num_exprs;
+ set->handle = nf_tables_alloc_handle(table);
+
+ err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
+@@ -4607,7 +4686,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ err_set_expr_alloc:
+ for (i = 0; i < set->num_exprs; i++)
+ nft_expr_destroy(&ctx, set->exprs[i]);
+-
++err_set_destroy:
+ ops->destroy(set);
+ err_set_init:
+ kfree(set->name);
+@@ -5960,7 +6039,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ return err;
+ } else if (set->flags & NFT_SET_TIMEOUT &&
+ !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+- timeout = set->timeout;
++ timeout = READ_ONCE(set->timeout);
+ }
+
+ expiration = 0;
+@@ -6061,7 +6140,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ if (err < 0)
+ goto err_parse_key_end;
+
+- if (timeout != set->timeout) {
++ if (timeout != READ_ONCE(set->timeout)) {
+ err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
+ if (err < 0)
+ goto err_parse_key_end;
+@@ -8977,14 +9056,20 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ break;
+ case NFT_MSG_NEWSET:
+- nft_clear(net, nft_trans_set(trans));
+- /* This avoids hitting -EBUSY when deleting the table
+- * from the transaction.
+- */
+- if (nft_set_is_anonymous(nft_trans_set(trans)) &&
+- !list_empty(&nft_trans_set(trans)->bindings))
+- trans->ctx.table->use--;
++ if (nft_trans_set_update(trans)) {
++ struct nft_set *set = nft_trans_set(trans);
+
++ WRITE_ONCE(set->timeout, nft_trans_set_timeout(trans));
++ WRITE_ONCE(set->gc_int, nft_trans_set_gc_int(trans));
++ } else {
++ nft_clear(net, nft_trans_set(trans));
++ /* This avoids hitting -EBUSY when deleting the table
++ * from the transaction.
++ */
++ if (nft_set_is_anonymous(nft_trans_set(trans)) &&
++ !list_empty(&nft_trans_set(trans)->bindings))
++ trans->ctx.table->use--;
++ }
+ nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
+ NFT_MSG_NEWSET, GFP_KERNEL);
+ nft_trans_destroy(trans);
+@@ -9206,6 +9291,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
+ nft_trans_destroy(trans);
+ break;
+ case NFT_MSG_NEWSET:
++ if (nft_trans_set_update(trans)) {
++ nft_trans_destroy(trans);
++ break;
++ }
+ trans->ctx.table->use--;
+ if (nft_trans_set_bound(trans)) {
+ nft_trans_destroy(trans);
+diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
+index 7c62417ccfd78..32a08ae9ad117 100644
+--- a/net/nfc/netlink.c
++++ b/net/nfc/netlink.c
+@@ -1497,6 +1497,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ u32 dev_idx, se_idx;
+ u8 *apdu;
+ size_t apdu_len;
++ int rc;
+
+ if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
+ !info->attrs[NFC_ATTR_SE_INDEX] ||
+@@ -1510,25 +1511,37 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ if (!dev)
+ return -ENODEV;
+
+- if (!dev->ops || !dev->ops->se_io)
+- return -ENOTSUPP;
++ if (!dev->ops || !dev->ops->se_io) {
++ rc = -EOPNOTSUPP;
++ goto put_dev;
++ }
+
+ apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
+- if (apdu_len == 0)
+- return -EINVAL;
++ if (apdu_len == 0) {
++ rc = -EINVAL;
++ goto put_dev;
++ }
+
+ apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
+- if (!apdu)
+- return -EINVAL;
++ if (!apdu) {
++ rc = -EINVAL;
++ goto put_dev;
++ }
+
+ ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
+- if (!ctx)
+- return -ENOMEM;
++ if (!ctx) {
++ rc = -ENOMEM;
++ goto put_dev;
++ }
+
+ ctx->dev_idx = dev_idx;
+ ctx->se_idx = se_idx;
+
+- return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++ rc = nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++
++put_dev:
++ nfc_put_device(dev);
++ return rc;
+ }
+
+ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+@@ -1551,14 +1564,21 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
+
+ dev = nfc_get_device(dev_idx);
+- if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
++ if (!dev)
+ return -ENODEV;
+
++ if (!dev->vendor_cmds || !dev->n_vendor_cmds) {
++ err = -ENODEV;
++ goto put_dev;
++ }
++
+ if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
+ data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
+ data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
+- if (data_len == 0)
+- return -EINVAL;
++ if (data_len == 0) {
++ err = -EINVAL;
++ goto put_dev;
++ }
+ } else {
+ data = NULL;
+ data_len = 0;
+@@ -1573,10 +1593,14 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ dev->cur_cmd_info = info;
+ err = cmd->doit(dev, data, data_len);
+ dev->cur_cmd_info = NULL;
+- return err;
++ goto put_dev;
+ }
+
+- return -EOPNOTSUPP;
++ err = -EOPNOTSUPP;
++
++put_dev:
++ nfc_put_device(dev);
++ return err;
+ }
+
+ /* message building helper */
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+index 742c7d49a9581..8d1ef858db87d 100644
+--- a/net/sched/cls_tcindex.c
++++ b/net/sched/cls_tcindex.c
+@@ -332,7 +332,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ struct tcindex_filter_result *r, struct nlattr **tb,
+ struct nlattr *est, u32 flags, struct netlink_ext_ack *extack)
+ {
+- struct tcindex_filter_result new_filter_result, *old_r = r;
++ struct tcindex_filter_result new_filter_result;
+ struct tcindex_data *cp = NULL, *oldp;
+ struct tcindex_filter *f = NULL; /* make gcc behave */
+ struct tcf_result cr = {};
+@@ -401,7 +401,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ err = tcindex_filter_result_init(&new_filter_result, cp, net);
+ if (err < 0)
+ goto errout_alloc;
+- if (old_r)
++ if (r)
+ cr = r->res;
+
+ err = -EBUSY;
+@@ -478,14 +478,6 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ tcf_bind_filter(tp, &cr, base);
+ }
+
+- if (old_r && old_r != r) {
+- err = tcindex_filter_result_init(old_r, cp, net);
+- if (err < 0) {
+- kfree(f);
+- goto errout_alloc;
+- }
+- }
+-
+ oldp = p;
+ r->res = cr;
+ tcf_exts_change(&r->exts, &e);
+diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
+index 816fd0d7ba38a..28e1897e0da70 100644
+--- a/net/sched/sch_atm.c
++++ b/net/sched/sch_atm.c
+@@ -397,10 +397,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ result = tcf_classify(skb, NULL, fl, &res, true);
+ if (result < 0)
+ continue;
++ if (result == TC_ACT_SHOT)
++ goto done;
++
+ flow = (struct atm_flow_data *)res.class;
+ if (!flow)
+ flow = lookup_flow(sch, res.classid);
+- goto done;
++ goto drop;
+ }
+ }
+ flow = NULL;
+diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
+index ba99ce05cd527..5d9f4f259d693 100644
+--- a/net/sched/sch_cbq.c
++++ b/net/sched/sch_cbq.c
+@@ -230,6 +230,8 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ result = tcf_classify(skb, NULL, fl, &res, true);
+ if (!fl || result < 0)
+ goto fallback;
++ if (result == TC_ACT_SHOT)
++ return NULL;
+
+ cl = (void *)res.class;
+ if (!cl) {
+@@ -250,8 +252,6 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ case TC_ACT_TRAP:
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ fallthrough;
+- case TC_ACT_SHOT:
+- return NULL;
+ case TC_ACT_RECLASSIFY:
+ return cbq_reclassify(skb, cl);
+ }
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 7bb247c51e2f6..2d7b1e03110ae 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -302,7 +302,7 @@ __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth
+ list_for_each_entry(pos, &pipe->in_downcall, list) {
+ if (!uid_eq(pos->uid, uid))
+ continue;
+- if (auth && pos->auth->service != auth->service)
++ if (pos->auth->service != auth->service)
+ continue;
+ refcount_inc(&pos->count);
+ return pos;
+@@ -686,6 +686,21 @@ out:
+ return err;
+ }
+
++static struct gss_upcall_msg *
++gss_find_downcall(struct rpc_pipe *pipe, kuid_t uid)
++{
++ struct gss_upcall_msg *pos;
++ list_for_each_entry(pos, &pipe->in_downcall, list) {
++ if (!uid_eq(pos->uid, uid))
++ continue;
++ if (!rpc_msg_is_inflight(&pos->msg))
++ continue;
++ refcount_inc(&pos->count);
++ return pos;
++ }
++ return NULL;
++}
++
+ #define MSG_BUF_MAXSIZE 1024
+
+ static ssize_t
+@@ -732,7 +747,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ err = -ENOENT;
+ /* Find a matching upcall */
+ spin_lock(&pipe->lock);
+- gss_msg = __gss_find_upcall(pipe, uid, NULL);
++ gss_msg = gss_find_downcall(pipe, uid);
+ if (gss_msg == NULL) {
+ spin_unlock(&pipe->lock);
+ goto err_put_ctx;
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index fb9d9e271845d..ddd2625bed90d 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -570,6 +570,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ BYT_RT5640_SSP0_AIF1 |
+ BYT_RT5640_MCLK_EN),
+ },
++ {
++ /* Advantech MICA-071 */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
++ },
++ /* OVCD Th = 1500uA to reliable detect head-phones vs -set */
++ .driver_data = (void *)(BYT_RT5640_IN3_MAP |
++ BYT_RT5640_JD_SRC_JD2_IN4N |
++ BYT_RT5640_OVCD_TH_1500UA |
++ BYT_RT5640_OVCD_SF_0P75 |
++ BYT_RT5640_MONO_SPEAKER |
++ BYT_RT5640_DIFF_MIC |
++ BYT_RT5640_MCLK_EN),
++ },
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
+diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
+index c99b5e6c026c1..694a2d94a2228 100644
+--- a/sound/soc/sof/core.c
++++ b/sound/soc/sof/core.c
+@@ -472,19 +472,10 @@ EXPORT_SYMBOL(snd_sof_device_remove);
+ int snd_sof_device_shutdown(struct device *dev)
+ {
+ struct snd_sof_dev *sdev = dev_get_drvdata(dev);
+- struct snd_sof_pdata *pdata = sdev->pdata;
+
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
+ cancel_work_sync(&sdev->probe_work);
+
+- /*
+- * make sure clients and machine driver(s) are unregistered to force
+- * all userspace devices to be closed prior to the DSP shutdown sequence
+- */
+- sof_unregister_clients(sdev);
+-
+- snd_sof_machine_unregister(sdev, pdata);
+-
+ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
+ return snd_sof_shutdown(sdev);
+
+diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
+index eddfd77ad90f4..0ab111814f1c5 100644
+--- a/sound/soc/sof/intel/hda-dsp.c
++++ b/sound/soc/sof/intel/hda-dsp.c
+@@ -901,6 +901,78 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
+ return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
+ }
+
++static unsigned int hda_dsp_check_for_dma_streams(struct snd_sof_dev *sdev)
++{
++ struct hdac_bus *bus = sof_to_bus(sdev);
++ struct hdac_stream *s;
++ unsigned int active_streams = 0;
++ int sd_offset;
++ u32 val;
++
++ list_for_each_entry(s, &bus->stream_list, list) {
++ sd_offset = SOF_STREAM_SD_OFFSET(s);
++ val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
++ sd_offset);
++ if (val & SOF_HDA_SD_CTL_DMA_START)
++ active_streams |= BIT(s->index);
++ }
++
++ return active_streams;
++}
++
++static int hda_dsp_s5_quirk(struct snd_sof_dev *sdev)
++{
++ int ret;
++
++ /*
++ * Do not assume a certain timing between the prior
++ * suspend flow, and running of this quirk function.
++ * This is needed if the controller was just put
++ * to reset before calling this function.
++ */
++ usleep_range(500, 1000);
++
++ /*
++ * Take controller out of reset to flush DMA
++ * transactions.
++ */
++ ret = hda_dsp_ctrl_link_reset(sdev, false);
++ if (ret < 0)
++ return ret;
++
++ usleep_range(500, 1000);
++
++ /* Restore state for shutdown, back to reset */
++ ret = hda_dsp_ctrl_link_reset(sdev, true);
++ if (ret < 0)
++ return ret;
++
++ return ret;
++}
++
++int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev)
++{
++ unsigned int active_streams;
++ int ret, ret2;
++
++ /* check if DMA cleanup has been successful */
++ active_streams = hda_dsp_check_for_dma_streams(sdev);
++
++ sdev->system_suspend_target = SOF_SUSPEND_S3;
++ ret = snd_sof_suspend(sdev->dev);
++
++ if (active_streams) {
++ dev_warn(sdev->dev,
++ "There were active DSP streams (%#x) at shutdown, trying to recover\n",
++ active_streams);
++ ret2 = hda_dsp_s5_quirk(sdev);
++ if (ret2 < 0)
++ dev_err(sdev->dev, "shutdown recovery failed (%d)\n", ret2);
++ }
++
++ return ret;
++}
++
+ int hda_dsp_shutdown(struct snd_sof_dev *sdev)
+ {
+ sdev->system_suspend_target = SOF_SUSPEND_S3;
+diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
+index 5ef3e8775e364..554891e78cca5 100644
+--- a/sound/soc/sof/intel/hda.h
++++ b/sound/soc/sof/intel/hda.h
+@@ -578,6 +578,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev);
++int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev);
+ int hda_dsp_shutdown(struct snd_sof_dev *sdev);
+ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
+ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
+diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
+index 6dfb4786c7824..0173e5b255daa 100644
+--- a/sound/soc/sof/intel/tgl.c
++++ b/sound/soc/sof/intel/tgl.c
+@@ -60,7 +60,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
+ memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
+
+ /* probe/remove/shutdown */
+- sof_tgl_ops.shutdown = hda_dsp_shutdown;
++ sof_tgl_ops.shutdown = hda_dsp_shutdown_dma_flush;
+
+ if (sdev->pdata->ipc_type == SOF_IPC) {
+ /* doorbell */
+diff --git a/sound/soc/sof/mediatek/mtk-adsp-common.c b/sound/soc/sof/mediatek/mtk-adsp-common.c
+index 1e0769c668a7b..de8dbe27cd0de 100644
+--- a/sound/soc/sof/mediatek/mtk-adsp-common.c
++++ b/sound/soc/sof/mediatek/mtk-adsp-common.c
+@@ -60,7 +60,7 @@ void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags)
+ {
+ char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
+ struct sof_ipc_dsp_oops_xtensa xoops;
+- struct sof_ipc_panic_info panic_info;
++ struct sof_ipc_panic_info panic_info = {};
+ u32 stack[MTK_ADSP_STACK_DUMP_SIZE];
+ u32 status;
+
+diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
+index ea40ae52cd2c7..2bc9231d86b66 100644
+--- a/tools/perf/builtin-lock.c
++++ b/tools/perf/builtin-lock.c
+@@ -1539,6 +1539,7 @@ static int __cmd_report(bool display_info)
+
+ /* for lock function check */
+ symbol_conf.sort_by_name = true;
++ symbol_conf.allow_aliases = true;
+ symbol__init(&session->header.env);
+
+ if (!perf_session__has_traces(session, "lock record"))
+@@ -1613,6 +1614,7 @@ static int __cmd_contention(int argc, const char **argv)
+
+ /* for lock function check */
+ symbol_conf.sort_by_name = true;
++ symbol_conf.allow_aliases = true;
+ symbol__init(&session->header.env);
+
+ if (use_bpf) {
+diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
+index 3c2df7522f6fc..1c82377ed78b9 100644
+--- a/tools/perf/util/bpf_counter_cgroup.c
++++ b/tools/perf/util/bpf_counter_cgroup.c
+@@ -116,27 +116,19 @@ static int bperf_load_program(struct evlist *evlist)
+
+ /* open single copy of the events w/o cgroup */
+ err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1);
+- if (err) {
+- pr_err("Failed to open first cgroup events\n");
+- goto out;
+- }
++ if (err == 0)
++ evsel->supported = true;
+
+ map_fd = bpf_map__fd(skel->maps.events);
+ perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) {
+ int fd = FD(evsel, j);
+ __u32 idx = evsel->core.idx * total_cpus + cpu.cpu;
+
+- err = bpf_map_update_elem(map_fd, &idx, &fd,
+- BPF_ANY);
+- if (err < 0) {
+- pr_err("Failed to update perf_event fd\n");
+- goto out;
+- }
++ bpf_map_update_elem(map_fd, &idx, &fd, BPF_ANY);
+ }
+
+ evsel->cgrp = leader_cgrp;
+ }
+- evsel->supported = true;
+
+ if (evsel->cgrp == cgrp)
+ continue;
+diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
+index e99b41f9be45a..cd978c240e0dd 100644
+--- a/tools/perf/util/cgroup.c
++++ b/tools/perf/util/cgroup.c
+@@ -224,6 +224,19 @@ static int add_cgroup_name(const char *fpath, const struct stat *sb __maybe_unus
+ return 0;
+ }
+
++static int check_and_add_cgroup_name(const char *fpath)
++{
++ struct cgroup_name *cn;
++
++ list_for_each_entry(cn, &cgroup_list, list) {
++ if (!strcmp(cn->name, fpath))
++ return 0;
++ }
++
++ /* pretend if it's added by ftw() */
++ return add_cgroup_name(fpath, NULL, FTW_D, NULL);
++}
++
+ static void release_cgroup_list(void)
+ {
+ struct cgroup_name *cn;
+@@ -242,7 +255,7 @@ static int list_cgroups(const char *str)
+ struct cgroup_name *cn;
+ char *s;
+
+- /* use given name as is - for testing purpose */
++ /* use given name as is when no regex is given */
+ for (;;) {
+ p = strchr(str, ',');
+ e = p ? p : eos;
+@@ -253,13 +266,13 @@ static int list_cgroups(const char *str)
+ s = strndup(str, e - str);
+ if (!s)
+ return -1;
+- /* pretend if it's added by ftw() */
+- ret = add_cgroup_name(s, NULL, FTW_D, NULL);
++
++ ret = check_and_add_cgroup_name(s);
+ free(s);
+- if (ret)
++ if (ret < 0)
+ return -1;
+ } else {
+- if (add_cgroup_name("", NULL, FTW_D, NULL) < 0)
++ if (check_and_add_cgroup_name("/") < 0)
+ return -1;
+ }
+
+diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
+index a7f68c309545d..fc16299c915f9 100644
+--- a/tools/perf/util/data.c
++++ b/tools/perf/util/data.c
+@@ -132,6 +132,7 @@ int perf_data__open_dir(struct perf_data *data)
+ file->size = st.st_size;
+ }
+
++ closedir(dir);
+ if (!files)
+ return -EINVAL;
+
+@@ -140,6 +141,7 @@ int perf_data__open_dir(struct perf_data *data)
+ return 0;
+
+ out_err:
++ closedir(dir);
+ close_dir(files, nr);
+ return ret;
+ }
+diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
+index 609ca16715018..623527edeac1e 100644
+--- a/tools/perf/util/dwarf-aux.c
++++ b/tools/perf/util/dwarf-aux.c
+@@ -308,26 +308,13 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
+ {
+ Dwarf_Attribute attr;
+
+- if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
++ if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL ||
+ dwarf_formudata(&attr, result) != 0)
+ return -ENOENT;
+
+ return 0;
+ }
+
+-/* Get attribute and translate it as a sdata */
+-static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
+- Dwarf_Sword *result)
+-{
+- Dwarf_Attribute attr;
+-
+- if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
+- dwarf_formsdata(&attr, result) != 0)
+- return -ENOENT;
+-
+- return 0;
+-}
+-
+ /**
+ * die_is_signed_type - Check whether a type DIE is signed or not
+ * @tp_die: a DIE of a type
+@@ -467,9 +454,9 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
+ /* Get the call file index number in CU DIE */
+ static int die_get_call_fileno(Dwarf_Die *in_die)
+ {
+- Dwarf_Sword idx;
++ Dwarf_Word idx;
+
+- if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
++ if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0)
+ return (int)idx;
+ else
+ return -ENOENT;
+@@ -478,9 +465,9 @@ static int die_get_call_fileno(Dwarf_Die *in_die)
+ /* Get the declared file index number in CU DIE */
+ static int die_get_decl_fileno(Dwarf_Die *pdie)
+ {
+- Dwarf_Sword idx;
++ Dwarf_Word idx;
+
+- if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
++ if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0)
+ return (int)idx;
+ else
+ return -ENOENT;
+diff --git a/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh b/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
+index b5af08af85595..4a110bb01e53e 100755
+--- a/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
++++ b/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
+@@ -18,14 +18,15 @@ readonly V4_ADDR1=10.0.10.2
+ readonly V6_ADDR0=2001:db8:91::1
+ readonly V6_ADDR1=2001:db8:91::2
+ nsid=100
++ret=0
+
+ cleanup_v6()
+ {
+ ip netns del me
+ ip netns del peer
+
+- sysctl -w net.ipv4.conf.veth0.ndisc_evict_nocarrier=1 >/dev/null 2>&1
+- sysctl -w net.ipv4.conf.all.ndisc_evict_nocarrier=1 >/dev/null 2>&1
++ sysctl -w net.ipv6.conf.veth1.ndisc_evict_nocarrier=1 >/dev/null 2>&1
++ sysctl -w net.ipv6.conf.all.ndisc_evict_nocarrier=1 >/dev/null 2>&1
+ }
+
+ create_ns()
+@@ -61,7 +62,7 @@ setup_v6() {
+ if [ $? -ne 0 ]; then
+ cleanup_v6
+ echo "failed"
+- exit
++ exit 1
+ fi
+
+ # Set veth2 down, which will put veth1 in NOCARRIER state
+@@ -88,7 +89,7 @@ setup_v4() {
+ if [ $? -ne 0 ]; then
+ cleanup_v4
+ echo "failed"
+- exit
++ exit 1
+ fi
+
+ # Set veth1 down, which will put veth0 in NOCARRIER state
+@@ -115,6 +116,7 @@ run_arp_evict_nocarrier_enabled() {
+
+ if [ $? -eq 0 ];then
+ echo "failed"
++ ret=1
+ else
+ echo "ok"
+ fi
+@@ -134,6 +136,7 @@ run_arp_evict_nocarrier_disabled() {
+ echo "ok"
+ else
+ echo "failed"
++ ret=1
+ fi
+
+ cleanup_v4
+@@ -164,6 +167,7 @@ run_ndisc_evict_nocarrier_enabled() {
+
+ if [ $? -eq 0 ];then
+ echo "failed"
++ ret=1
+ else
+ echo "ok"
+ fi
+@@ -182,6 +186,7 @@ run_ndisc_evict_nocarrier_disabled() {
+ echo "ok"
+ else
+ echo "failed"
++ ret=1
+ fi
+
+ cleanup_v6
+@@ -198,6 +203,7 @@ run_ndisc_evict_nocarrier_disabled_all() {
+ echo "ok"
+ else
+ echo "failed"
++ ret=1
+ fi
+
+ cleanup_v6
+@@ -218,3 +224,4 @@ if [ "$(id -u)" -ne 0 ];then
+ fi
+
+ run_all_tests
++exit $ret
^ permalink raw reply related [flat|nested] 27+ messages in thread
end of thread, other threads:[~2023-01-12 12:17 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-21 18:50 [gentoo-commits] proj/linux-patches:6.0 commit in: / Alice Ferrazzi
-- strict thread matches above, loose matches on Subject: below --
2023-01-12 12:17 Mike Pagano
2023-01-07 11:11 Mike Pagano
2023-01-04 11:38 Mike Pagano
2022-12-31 15:29 Mike Pagano
2022-12-19 12:23 Alice Ferrazzi
2022-12-16 19:56 Mike Pagano
2022-12-14 12:51 Mike Pagano
2022-12-14 12:13 Mike Pagano
2022-12-08 11:40 Alice Ferrazzi
2022-12-06 13:46 Mike Pagano
2022-12-06 13:00 Mike Pagano
2022-12-02 17:23 Mike Pagano
2022-11-26 11:55 Mike Pagano
2022-11-16 11:16 Alice Ferrazzi
2022-11-10 18:18 Mike Pagano
2022-11-10 18:10 Mike Pagano
2022-11-09 19:00 Mike Pagano
2022-11-03 15:27 Mike Pagano
2022-11-01 12:46 Mike Pagano
2022-10-29 9:54 Mike Pagano
2022-10-26 11:24 Mike Pagano
2022-10-21 13:14 Mike Pagano
2022-10-15 10:03 Mike Pagano
2022-10-12 11:16 Mike Pagano
2022-10-03 9:31 Mike Pagano
2022-09-11 22:30 Mike Pagano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox